Add vectortile branch
This commit is contained in:
132191
vectortile/build/ol-debug.js
Normal file
132191
vectortile/build/ol-debug.js
Normal file
File diff suppressed because it is too large
Load Diff
1710
vectortile/build/ol-deps.js
Normal file
1710
vectortile/build/ol-deps.js
Normal file
File diff suppressed because one or more lines are too long
1000
vectortile/build/ol.js
Normal file
1000
vectortile/build/ol.js
Normal file
File diff suppressed because it is too large
Load Diff
20
vectortile/closure-library/AUTHORS
Normal file
20
vectortile/closure-library/AUTHORS
Normal file
@@ -0,0 +1,20 @@
|
||||
# This is a list of contributors to the Closure Library.
|
||||
|
||||
# Names should be added to this file like so:
|
||||
# Name or Organization <email address>
|
||||
|
||||
Google Inc.
|
||||
Mohamed Mansour <hello@mohamedmansour.com>
|
||||
Bjorn Tipling <bjorn.tipling@gmail.com>
|
||||
SameGoal LLC <help@samegoal.com>
|
||||
Guido Tapia <guido.tapia@gmail.com>
|
||||
Andrew Mattie <amattie@gmail.com>
|
||||
Ilia Mirkin <ibmirkin@gmail.com>
|
||||
Ivan Kozik <ivan.kozik@gmail.com>
|
||||
Rich Dougherty <rich@rd.gen.nz>
|
||||
Chad Killingsworth <chadkillingsworth@missouristate.edu>
|
||||
Dan Pupius <dan.pupius@gmail.com>
|
||||
Mike Dunn <dunn74@gmail.com>
|
||||
Kengo Toda <skypencil@gmail.com>
|
||||
Remember The Milk Inc.
|
||||
|
||||
48
vectortile/closure-library/CONTRIBUTING
Normal file
48
vectortile/closure-library/CONTRIBUTING
Normal file
@@ -0,0 +1,48 @@
|
||||
Closure Library welcomes patches/pulls for features and bugfixes.
|
||||
|
||||
For contributors inside Google, follow the instructions given here:
|
||||
http://go/closure-contributors
|
||||
|
||||
For contributors external to Google, follow the instructions given here:
|
||||
|
||||
Notes on Contributions to Closure Library
|
||||
|
||||
Google Individual Contributor License
|
||||
|
||||
In all cases, contributors must sign a contributor license agreement,
|
||||
either for an individual or corporation, before a patch can be
|
||||
accepted. Please fill out the agreement for an individual or a
|
||||
corporation, as appropriate.
|
||||
|
||||
https://developers.google.com/open-source/cla/individual
|
||||
https://developers.google.com/open-source/cla/corporate
|
||||
|
||||
If you or your organization is not listed there already, you should
|
||||
add an entry to the AUTHORS file as part of your patch.
|
||||
|
||||
If you plan to add a significant component or large chunk of code, it
|
||||
is recommended to bring it up on the discussion list for a design
|
||||
discussion before writing code.
|
||||
|
||||
If appropriate, write a unit test that demonstrates your patch. Tests are the
|
||||
best way to ensure that future contributors do not break your code
|
||||
accidentally.
|
||||
|
||||
To change the Closure Library source, you must submit a pull request
|
||||
in GitHub. See the GitHub documentation here:
|
||||
|
||||
https://help.github.com/categories/63/articles
|
||||
|
||||
Closure Library developers monitor outstanding pull requests. They may
|
||||
request changes on the pull request before accepting. They will also
|
||||
verify that the CLA has been signed.
|
||||
|
||||
Oftentimes, the pull request will not be directly merged, but patched to
|
||||
the internal Google codebase to verify that unit and integration tests
|
||||
will Closure pass before submitting (and optionally make changes to
|
||||
the patch to match style, fix text, or to make the code or comments
|
||||
clearer). In this case, the issue associated with the pull request
|
||||
will be closed when the patch pushed to the repository via the MOE
|
||||
(Make Open Easy) system.
|
||||
|
||||
https://code.google.com/p/moe-java/
|
||||
176
vectortile/closure-library/LICENSE
Normal file
176
vectortile/closure-library/LICENSE
Normal file
@@ -0,0 +1,176 @@
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
16
vectortile/closure-library/README.md
Normal file
16
vectortile/closure-library/README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# Closure Library [](https://travis-ci.org/google/closure-library)
|
||||
|
||||
Closure Library is a powerful, low-level JavaScript library designed
|
||||
for building complex and scalable web applications. It is used by many
|
||||
Google web applications, such as Google Search, Gmail, Google Docs,
|
||||
Google+, Google Maps, and others.
|
||||
|
||||
For more information, visit the
|
||||
[Google Developers](https://developers.google.com/closure/library) or
|
||||
[GitHub](https://github.com/google/closure-library) sites.
|
||||
|
||||
Developers, please see the
|
||||
[Generated API Documentation](http://google.github.io/closure-library/api/).
|
||||
|
||||
See also the
|
||||
[goog.ui Demos](http://google.github.io/closure-library/source/closure/goog/demos/)
|
||||
111
vectortile/closure-library/all_tests.html
Normal file
111
vectortile/closure-library/all_tests.html
Normal file
@@ -0,0 +1,111 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<head>
|
||||
<title>Closure - All JsUnit Tests</title>
|
||||
<script src="closure/goog/base.js"></script>
|
||||
<script src="alltests.js"></script>
|
||||
<script>
|
||||
goog.require('goog.userAgent.product');
|
||||
goog.require('goog.testing.MultiTestRunner');
|
||||
</script>
|
||||
<link rel="stylesheet" href="closure/goog/css/multitestrunner.css" type="text/css">
|
||||
<style>
|
||||
h1 {
|
||||
font: normal x-large arial, helvetica, sans-serif;
|
||||
margin: 0;
|
||||
}
|
||||
p, form {
|
||||
font: normal small sans-serif;
|
||||
margin: 0;
|
||||
}
|
||||
#header {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 13px;
|
||||
}
|
||||
#footer {
|
||||
margin-top: 8px;
|
||||
}
|
||||
a {
|
||||
text-decoration: none;
|
||||
}
|
||||
a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.warning {
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
width: 80%;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script>
|
||||
if (goog.userAgent.product.CHROME &&
|
||||
window.location.toString().indexOf('file:') == 0) {
|
||||
document.write(
|
||||
'<div class="warning">' +
|
||||
'WARNING: Due to Chrome\'s security restrictions ' +
|
||||
'this test will not be able to load files off your local disk ' +
|
||||
'unless you start Chrome with:<br>' +
|
||||
'<code>--allow-file-access-from-files</code></div><br>');
|
||||
}
|
||||
</script>
|
||||
|
||||
<h1>Closure - All JsUnit Tests</h1>
|
||||
<p id="header"></p>
|
||||
<div id="runner"></div>
|
||||
<!-- Use a form so browser persists input values -->
|
||||
<form id="footer" onsubmit="return false">
|
||||
Settings:<br>
|
||||
<input type="checkbox" name="hidepasses" id="hidepasses" checked>
|
||||
<label for="hidepasses">Hide passes</label><br>
|
||||
<input type="checkbox" name="parallel" id="parallel" checked>
|
||||
<label for="parallel">Run in parallel</label>
|
||||
<small>(timing stats not available if enabled)</small><br>
|
||||
<input type="text" name="filter" id="filter" value="">
|
||||
<label for="filter">Run only tests for path</label>
|
||||
</form>
|
||||
<script>
|
||||
var hidePassesInput = document.getElementById('hidepasses');
|
||||
var parallelInput = document.getElementById('parallel');
|
||||
var filterInput = document.getElementById('filter');
|
||||
|
||||
function setFilterFunction() {
|
||||
var matchValue = filterInput.value || '';
|
||||
testRunner.setFilterFunction(function(testPath) {
|
||||
return testPath.indexOf(matchValue) > -1;
|
||||
});
|
||||
}
|
||||
|
||||
// Create a test runner and render it.
|
||||
var testRunner = new goog.testing.MultiTestRunner()
|
||||
.setName(document.title)
|
||||
.setBasePath('./')
|
||||
.setPoolSize(parallelInput.checked ? 8 : 1)
|
||||
.setStatsBucketSizes(5, 500)
|
||||
.setHidePasses(hidePassesInput.checked)
|
||||
//.setVerbosePasses(true)
|
||||
.addTests(_allTests);
|
||||
testRunner.render(document.getElementById('runner'));
|
||||
|
||||
goog.events.listen(hidePassesInput, 'click', function(e) {
|
||||
testRunner.setHidePasses(e.target.checked);
|
||||
});
|
||||
|
||||
goog.events.listen(parallelInput, 'click', function(e) {
|
||||
testRunner.setPoolSize(e.target.checked ? 8 : 1);
|
||||
});
|
||||
|
||||
goog.events.listen(filterInput, 'keyup', setFilterFunction);
|
||||
setFilterFunction();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
16
vectortile/closure-library/alltests.js
Normal file
16
vectortile/closure-library/alltests.js
Normal file
File diff suppressed because one or more lines are too long
287
vectortile/closure-library/closure/bin/build/closurebuilder.py
Normal file
287
vectortile/closure-library/closure/bin/build/closurebuilder.py
Normal file
@@ -0,0 +1,287 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Utility for Closure Library dependency calculation.
|
||||
|
||||
ClosureBuilder scans source files to build dependency info. From the
|
||||
dependencies, the script can produce a manifest in dependency order,
|
||||
a concatenated script, or compiled output from the Closure Compiler.
|
||||
|
||||
Paths to files can be expressed as individual arguments to the tool (intended
|
||||
for use with find and xargs). As a convenience, --root can be used to specify
|
||||
all JS files below a directory.
|
||||
|
||||
usage: %prog [options] [file1.js file2.js ...]
|
||||
"""
|
||||
|
||||
__author__ = 'nnaze@google.com (Nathan Naze)'
|
||||
|
||||
|
||||
import logging
|
||||
import optparse
|
||||
import os
|
||||
import sys
|
||||
|
||||
import depstree
|
||||
import jscompiler
|
||||
import source
|
||||
import treescan
|
||||
|
||||
|
||||
def _GetOptionsParser():
|
||||
"""Get the options parser."""
|
||||
|
||||
parser = optparse.OptionParser(__doc__)
|
||||
parser.add_option('-i',
|
||||
'--input',
|
||||
dest='inputs',
|
||||
action='append',
|
||||
default=[],
|
||||
help='One or more input files to calculate dependencies '
|
||||
'for. The namespaces in this file will be combined with '
|
||||
'those given with the -n flag to form the set of '
|
||||
'namespaces to find dependencies for.')
|
||||
parser.add_option('-n',
|
||||
'--namespace',
|
||||
dest='namespaces',
|
||||
action='append',
|
||||
default=[],
|
||||
help='One or more namespaces to calculate dependencies '
|
||||
'for. These namespaces will be combined with those given '
|
||||
'with the -i flag to form the set of namespaces to find '
|
||||
'dependencies for. A Closure namespace is a '
|
||||
'dot-delimited path expression declared with a call to '
|
||||
'goog.provide() (e.g. "goog.array" or "foo.bar").')
|
||||
parser.add_option('--root',
|
||||
dest='roots',
|
||||
action='append',
|
||||
default=[],
|
||||
help='The paths that should be traversed to build the '
|
||||
'dependencies.')
|
||||
parser.add_option('-o',
|
||||
'--output_mode',
|
||||
dest='output_mode',
|
||||
type='choice',
|
||||
action='store',
|
||||
choices=['list', 'script', 'compiled'],
|
||||
default='list',
|
||||
help='The type of output to generate from this script. '
|
||||
'Options are "list" for a list of filenames, "script" '
|
||||
'for a single script containing the contents of all the '
|
||||
'files, or "compiled" to produce compiled output with '
|
||||
'the Closure Compiler. Default is "list".')
|
||||
parser.add_option('-c',
|
||||
'--compiler_jar',
|
||||
dest='compiler_jar',
|
||||
action='store',
|
||||
help='The location of the Closure compiler .jar file.')
|
||||
parser.add_option('-f',
|
||||
'--compiler_flags',
|
||||
dest='compiler_flags',
|
||||
default=[],
|
||||
action='append',
|
||||
help='Additional flags to pass to the Closure compiler. '
|
||||
'To pass multiple flags, --compiler_flags has to be '
|
||||
'specified multiple times.')
|
||||
parser.add_option('-j',
|
||||
'--jvm_flags',
|
||||
dest='jvm_flags',
|
||||
default=[],
|
||||
action='append',
|
||||
help='Additional flags to pass to the JVM compiler. '
|
||||
'To pass multiple flags, --jvm_flags has to be '
|
||||
'specified multiple times.')
|
||||
parser.add_option('--output_file',
|
||||
dest='output_file',
|
||||
action='store',
|
||||
help=('If specified, write output to this path instead of '
|
||||
'writing to standard output.'))
|
||||
|
||||
return parser
|
||||
|
||||
|
||||
def _GetInputByPath(path, sources):
|
||||
"""Get the source identified by a path.
|
||||
|
||||
Args:
|
||||
path: str, A path to a file that identifies a source.
|
||||
sources: An iterable collection of source objects.
|
||||
|
||||
Returns:
|
||||
The source from sources identified by path, if found. Converts to
|
||||
real paths for comparison.
|
||||
"""
|
||||
for js_source in sources:
|
||||
# Convert both to real paths for comparison.
|
||||
if os.path.realpath(path) == os.path.realpath(js_source.GetPath()):
|
||||
return js_source
|
||||
|
||||
|
||||
def _GetClosureBaseFile(sources):
|
||||
"""Given a set of sources, returns the one base.js file.
|
||||
|
||||
Note that if zero or two or more base.js files are found, an error message
|
||||
will be written and the program will be exited.
|
||||
|
||||
Args:
|
||||
sources: An iterable of _PathSource objects.
|
||||
|
||||
Returns:
|
||||
The _PathSource representing the base Closure file.
|
||||
"""
|
||||
base_files = [
|
||||
js_source for js_source in sources if _IsClosureBaseFile(js_source)]
|
||||
|
||||
if not base_files:
|
||||
logging.error('No Closure base.js file found.')
|
||||
sys.exit(1)
|
||||
if len(base_files) > 1:
|
||||
logging.error('More than one Closure base.js files found at these paths:')
|
||||
for base_file in base_files:
|
||||
logging.error(base_file.GetPath())
|
||||
sys.exit(1)
|
||||
return base_files[0]
|
||||
|
||||
|
||||
def _IsClosureBaseFile(js_source):
|
||||
"""Returns true if the given _PathSource is the Closure base.js source."""
|
||||
return (os.path.basename(js_source.GetPath()) == 'base.js' and
|
||||
js_source.provides == set(['goog']))
|
||||
|
||||
|
||||
class _PathSource(source.Source):
|
||||
"""Source file subclass that remembers its file path."""
|
||||
|
||||
def __init__(self, path):
|
||||
"""Initialize a source.
|
||||
|
||||
Args:
|
||||
path: str, Path to a JavaScript file. The source string will be read
|
||||
from this file.
|
||||
"""
|
||||
super(_PathSource, self).__init__(source.GetFileContents(path))
|
||||
|
||||
self._path = path
|
||||
|
||||
def __str__(self):
|
||||
return 'PathSource %s' % self._path
|
||||
|
||||
def GetPath(self):
|
||||
"""Returns the path."""
|
||||
return self._path
|
||||
|
||||
|
||||
def _WrapGoogModuleSource(src):
|
||||
return ('goog.loadModule(function(exports) {{'
|
||||
'"use strict";'
|
||||
'{0}'
|
||||
'\n' # terminate any trailing single line comment.
|
||||
';return exports'
|
||||
'}});\n').format(src)
|
||||
|
||||
|
||||
def main():
|
||||
logging.basicConfig(format=(sys.argv[0] + ': %(message)s'),
|
||||
level=logging.INFO)
|
||||
options, args = _GetOptionsParser().parse_args()
|
||||
|
||||
# Make our output pipe.
|
||||
if options.output_file:
|
||||
out = open(options.output_file, 'w')
|
||||
else:
|
||||
out = sys.stdout
|
||||
|
||||
sources = set()
|
||||
|
||||
logging.info('Scanning paths...')
|
||||
for path in options.roots:
|
||||
for js_path in treescan.ScanTreeForJsFiles(path):
|
||||
sources.add(_PathSource(js_path))
|
||||
|
||||
# Add scripts specified on the command line.
|
||||
for js_path in args:
|
||||
sources.add(_PathSource(js_path))
|
||||
|
||||
logging.info('%s sources scanned.', len(sources))
|
||||
|
||||
# Though deps output doesn't need to query the tree, we still build it
|
||||
# to validate dependencies.
|
||||
logging.info('Building dependency tree..')
|
||||
tree = depstree.DepsTree(sources)
|
||||
|
||||
input_namespaces = set()
|
||||
inputs = options.inputs or []
|
||||
for input_path in inputs:
|
||||
js_input = _GetInputByPath(input_path, sources)
|
||||
if not js_input:
|
||||
logging.error('No source matched input %s', input_path)
|
||||
sys.exit(1)
|
||||
input_namespaces.update(js_input.provides)
|
||||
|
||||
input_namespaces.update(options.namespaces)
|
||||
|
||||
if not input_namespaces:
|
||||
logging.error('No namespaces found. At least one namespace must be '
|
||||
'specified with the --namespace or --input flags.')
|
||||
sys.exit(2)
|
||||
|
||||
# The Closure Library base file must go first.
|
||||
base = _GetClosureBaseFile(sources)
|
||||
deps = [base] + tree.GetDependencies(input_namespaces)
|
||||
|
||||
output_mode = options.output_mode
|
||||
if output_mode == 'list':
|
||||
out.writelines([js_source.GetPath() + '\n' for js_source in deps])
|
||||
elif output_mode == 'script':
|
||||
for js_source in deps:
|
||||
src = js_source.GetSource()
|
||||
if js_source.is_goog_module:
|
||||
src = _WrapGoogModuleSource(src)
|
||||
out.write(src + '\n')
|
||||
elif output_mode == 'compiled':
|
||||
logging.warning("""\
|
||||
Closure Compiler now natively understands and orders Closure dependencies and
|
||||
is prefererred over using this script for performing JavaScript compilation.
|
||||
|
||||
Please migrate your codebase.
|
||||
|
||||
See:
|
||||
https://github.com/google/closure-compiler/wiki/Manage-Closure-Dependencies
|
||||
""")
|
||||
|
||||
# Make sure a .jar is specified.
|
||||
if not options.compiler_jar:
|
||||
logging.error('--compiler_jar flag must be specified if --output is '
|
||||
'"compiled"')
|
||||
sys.exit(2)
|
||||
|
||||
# Will throw an error if the compilation fails.
|
||||
compiled_source = jscompiler.Compile(
|
||||
options.compiler_jar,
|
||||
[js_source.GetPath() for js_source in deps],
|
||||
jvm_flags=options.jvm_flags,
|
||||
compiler_flags=options.compiler_flags)
|
||||
|
||||
logging.info('JavaScript compilation succeeded.')
|
||||
out.write(compiled_source)
|
||||
|
||||
else:
|
||||
logging.error('Invalid value for --output flag.')
|
||||
sys.exit(2)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
189
vectortile/closure-library/closure/bin/build/depstree.py
Normal file
189
vectortile/closure-library/closure/bin/build/depstree.py
Normal file
@@ -0,0 +1,189 @@
|
||||
# Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
"""Class to represent a full Closure Library dependency tree.
|
||||
|
||||
Offers a queryable tree of dependencies of a given set of sources. The tree
|
||||
will also do logical validation to prevent duplicate provides and circular
|
||||
dependencies.
|
||||
"""
|
||||
|
||||
__author__ = 'nnaze@google.com (Nathan Naze)'
|
||||
|
||||
|
||||
class DepsTree(object):
|
||||
"""Represents the set of dependencies between source files."""
|
||||
|
||||
def __init__(self, sources):
|
||||
"""Initializes the tree with a set of sources.
|
||||
|
||||
Args:
|
||||
sources: A set of JavaScript sources.
|
||||
|
||||
Raises:
|
||||
MultipleProvideError: A namespace is provided by muplitple sources.
|
||||
NamespaceNotFoundError: A namespace is required but never provided.
|
||||
"""
|
||||
|
||||
self._sources = sources
|
||||
self._provides_map = dict()
|
||||
|
||||
# Ensure nothing was provided twice.
|
||||
for source in sources:
|
||||
for provide in source.provides:
|
||||
if provide in self._provides_map:
|
||||
raise MultipleProvideError(
|
||||
provide, [self._provides_map[provide], source])
|
||||
|
||||
self._provides_map[provide] = source
|
||||
|
||||
# Check that all required namespaces are provided.
|
||||
for source in sources:
|
||||
for require in source.requires:
|
||||
if require not in self._provides_map:
|
||||
raise NamespaceNotFoundError(require, source)
|
||||
|
||||
def GetDependencies(self, required_namespaces):
|
||||
"""Get source dependencies, in order, for the given namespaces.
|
||||
|
||||
Args:
|
||||
required_namespaces: A string (for one) or list (for one or more) of
|
||||
namespaces.
|
||||
|
||||
Returns:
|
||||
A list of source objects that provide those namespaces and all
|
||||
requirements, in dependency order.
|
||||
|
||||
Raises:
|
||||
NamespaceNotFoundError: A namespace is requested but doesn't exist.
|
||||
CircularDependencyError: A cycle is detected in the dependency tree.
|
||||
"""
|
||||
if isinstance(required_namespaces, str):
|
||||
required_namespaces = [required_namespaces]
|
||||
|
||||
deps_sources = []
|
||||
|
||||
for namespace in required_namespaces:
|
||||
for source in DepsTree._ResolveDependencies(
|
||||
namespace, [], self._provides_map, []):
|
||||
if source not in deps_sources:
|
||||
deps_sources.append(source)
|
||||
|
||||
return deps_sources
|
||||
|
||||
@staticmethod
|
||||
def _ResolveDependencies(required_namespace, deps_list, provides_map,
|
||||
traversal_path):
|
||||
"""Resolve dependencies for Closure source files.
|
||||
|
||||
Follows the dependency tree down and builds a list of sources in dependency
|
||||
order. This function will recursively call itself to fill all dependencies
|
||||
below the requested namespaces, and then append its sources at the end of
|
||||
the list.
|
||||
|
||||
Args:
|
||||
required_namespace: String of required namespace.
|
||||
deps_list: List of sources in dependency order. This function will append
|
||||
the required source once all of its dependencies are satisfied.
|
||||
provides_map: Map from namespace to source that provides it.
|
||||
traversal_path: List of namespaces of our path from the root down the
|
||||
dependency/recursion tree. Used to identify cyclical dependencies.
|
||||
This is a list used as a stack -- when the function is entered, the
|
||||
current namespace is pushed and popped right before returning.
|
||||
Each recursive call will check that the current namespace does not
|
||||
appear in the list, throwing a CircularDependencyError if it does.
|
||||
|
||||
Returns:
|
||||
The given deps_list object filled with sources in dependency order.
|
||||
|
||||
Raises:
|
||||
NamespaceNotFoundError: A namespace is requested but doesn't exist.
|
||||
CircularDependencyError: A cycle is detected in the dependency tree.
|
||||
"""
|
||||
|
||||
source = provides_map.get(required_namespace)
|
||||
if not source:
|
||||
raise NamespaceNotFoundError(required_namespace)
|
||||
|
||||
if required_namespace in traversal_path:
|
||||
traversal_path.append(required_namespace) # do this *after* the test
|
||||
|
||||
# This must be a cycle.
|
||||
raise CircularDependencyError(traversal_path)
|
||||
|
||||
# If we don't have the source yet, we'll have to visit this namespace and
|
||||
# add the required dependencies to deps_list.
|
||||
if source not in deps_list:
|
||||
traversal_path.append(required_namespace)
|
||||
|
||||
for require in source.requires:
|
||||
|
||||
# Append all other dependencies before we append our own.
|
||||
DepsTree._ResolveDependencies(require, deps_list, provides_map,
|
||||
traversal_path)
|
||||
deps_list.append(source)
|
||||
|
||||
traversal_path.pop()
|
||||
|
||||
return deps_list
|
||||
|
||||
|
||||
class BaseDepsTreeError(Exception):
|
||||
"""Base DepsTree error."""
|
||||
|
||||
def __init__(self):
|
||||
Exception.__init__(self)
|
||||
|
||||
|
||||
class CircularDependencyError(BaseDepsTreeError):
|
||||
"""Raised when a dependency cycle is encountered."""
|
||||
|
||||
def __init__(self, dependency_list):
|
||||
BaseDepsTreeError.__init__(self)
|
||||
self._dependency_list = dependency_list
|
||||
|
||||
def __str__(self):
|
||||
return ('Encountered circular dependency:\n%s\n' %
|
||||
'\n'.join(self._dependency_list))
|
||||
|
||||
|
||||
class MultipleProvideError(BaseDepsTreeError):
|
||||
"""Raised when a namespace is provided more than once."""
|
||||
|
||||
def __init__(self, namespace, sources):
|
||||
BaseDepsTreeError.__init__(self)
|
||||
self._namespace = namespace
|
||||
self._sources = sources
|
||||
|
||||
def __str__(self):
|
||||
source_strs = map(str, self._sources)
|
||||
|
||||
return ('Namespace "%s" provided more than once in sources:\n%s\n' %
|
||||
(self._namespace, '\n'.join(source_strs)))
|
||||
|
||||
|
||||
class NamespaceNotFoundError(BaseDepsTreeError):
|
||||
"""Raised when a namespace is requested but not provided."""
|
||||
|
||||
def __init__(self, namespace, source=None):
|
||||
BaseDepsTreeError.__init__(self)
|
||||
self._namespace = namespace
|
||||
self._source = source
|
||||
|
||||
def __str__(self):
|
||||
msg = 'Namespace "%s" never provided.' % self._namespace
|
||||
if self._source:
|
||||
msg += ' Required in %s' % self._source
|
||||
return msg
|
||||
127
vectortile/closure-library/closure/bin/build/depstree_test.py
Normal file
127
vectortile/closure-library/closure/bin/build/depstree_test.py
Normal file
@@ -0,0 +1,127 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
"""Unit test for depstree."""
|
||||
|
||||
__author__ = 'nnaze@google.com (Nathan Naze)'
|
||||
|
||||
|
||||
import unittest
|
||||
|
||||
import depstree
|
||||
|
||||
|
||||
def _GetProvides(sources):
|
||||
"""Get all namespaces provided by a collection of sources."""
|
||||
|
||||
provides = set()
|
||||
for source in sources:
|
||||
provides.update(source.provides)
|
||||
return provides
|
||||
|
||||
|
||||
class MockSource(object):
|
||||
"""Mock Source file."""
|
||||
|
||||
def __init__(self, provides, requires):
|
||||
self.provides = set(provides)
|
||||
self.requires = set(requires)
|
||||
|
||||
def __repr__(self):
|
||||
return 'MockSource %s' % self.provides
|
||||
|
||||
|
||||
class DepsTreeTestCase(unittest.TestCase):
|
||||
"""Unit test for DepsTree. Tests several common situations and errors."""
|
||||
|
||||
def AssertValidDependencies(self, deps_list):
|
||||
"""Validates a dependency list.
|
||||
|
||||
Asserts that a dependency list is valid: For every source in the list,
|
||||
ensure that every require is provided by a source earlier in the list.
|
||||
|
||||
Args:
|
||||
deps_list: A list of sources that should be in dependency order.
|
||||
"""
|
||||
|
||||
for i in range(len(deps_list)):
|
||||
source = deps_list[i]
|
||||
previous_provides = _GetProvides(deps_list[:i])
|
||||
for require in source.requires:
|
||||
self.assertTrue(
|
||||
require in previous_provides,
|
||||
'Namespace "%s" not provided before required by %s' % (
|
||||
require, source))
|
||||
|
||||
def testSimpleDepsTree(self):
|
||||
a = MockSource(['A'], ['B', 'C'])
|
||||
b = MockSource(['B'], [])
|
||||
c = MockSource(['C'], ['D'])
|
||||
d = MockSource(['D'], ['E'])
|
||||
e = MockSource(['E'], [])
|
||||
|
||||
tree = depstree.DepsTree([a, b, c, d, e])
|
||||
|
||||
self.AssertValidDependencies(tree.GetDependencies('A'))
|
||||
self.AssertValidDependencies(tree.GetDependencies('B'))
|
||||
self.AssertValidDependencies(tree.GetDependencies('C'))
|
||||
self.AssertValidDependencies(tree.GetDependencies('D'))
|
||||
self.AssertValidDependencies(tree.GetDependencies('E'))
|
||||
|
||||
def testCircularDependency(self):
|
||||
# Circular deps
|
||||
a = MockSource(['A'], ['B'])
|
||||
b = MockSource(['B'], ['C'])
|
||||
c = MockSource(['C'], ['A'])
|
||||
|
||||
tree = depstree.DepsTree([a, b, c])
|
||||
|
||||
self.assertRaises(depstree.CircularDependencyError,
|
||||
tree.GetDependencies, 'A')
|
||||
|
||||
def testRequiresUndefinedNamespace(self):
|
||||
a = MockSource(['A'], ['B'])
|
||||
b = MockSource(['B'], ['C'])
|
||||
c = MockSource(['C'], ['D']) # But there is no D.
|
||||
|
||||
def MakeDepsTree():
|
||||
return depstree.DepsTree([a, b, c])
|
||||
|
||||
self.assertRaises(depstree.NamespaceNotFoundError, MakeDepsTree)
|
||||
|
||||
def testDepsForMissingNamespace(self):
|
||||
a = MockSource(['A'], ['B'])
|
||||
b = MockSource(['B'], [])
|
||||
|
||||
tree = depstree.DepsTree([a, b])
|
||||
|
||||
# There is no C.
|
||||
self.assertRaises(depstree.NamespaceNotFoundError,
|
||||
tree.GetDependencies, 'C')
|
||||
|
||||
def testMultipleRequires(self):
|
||||
a = MockSource(['A'], ['B'])
|
||||
b = MockSource(['B'], ['C'])
|
||||
c = MockSource(['C'], [])
|
||||
d = MockSource(['D'], ['B'])
|
||||
|
||||
tree = depstree.DepsTree([a, b, c, d])
|
||||
self.AssertValidDependencies(tree.GetDependencies(['D', 'A']))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
204
vectortile/closure-library/closure/bin/build/depswriter.py
Normal file
204
vectortile/closure-library/closure/bin/build/depswriter.py
Normal file
@@ -0,0 +1,204 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
"""Generates out a Closure deps.js file given a list of JavaScript sources.
|
||||
|
||||
Paths can be specified as arguments or (more commonly) specifying trees
|
||||
with the flags (call with --help for descriptions).
|
||||
|
||||
Usage: depswriter.py [path/to/js1.js [path/to/js2.js] ...]
|
||||
"""
|
||||
|
||||
import logging
|
||||
import optparse
|
||||
import os
|
||||
import posixpath
|
||||
import shlex
|
||||
import sys
|
||||
|
||||
import source
|
||||
import treescan
|
||||
|
||||
|
||||
__author__ = 'nnaze@google.com (Nathan Naze)'
|
||||
|
||||
|
||||
def MakeDepsFile(source_map):
|
||||
"""Make a generated deps file.
|
||||
|
||||
Args:
|
||||
source_map: A dict map of the source path to source.Source object.
|
||||
|
||||
Returns:
|
||||
str, A generated deps file source.
|
||||
"""
|
||||
|
||||
# Write in path alphabetical order
|
||||
paths = sorted(source_map.keys())
|
||||
|
||||
lines = []
|
||||
|
||||
for path in paths:
|
||||
js_source = source_map[path]
|
||||
|
||||
# We don't need to add entries that don't provide anything.
|
||||
if js_source.provides:
|
||||
lines.append(_GetDepsLine(path, js_source))
|
||||
|
||||
return ''.join(lines)
|
||||
|
||||
|
||||
def _GetDepsLine(path, js_source):
|
||||
"""Get a deps.js file string for a source."""
|
||||
|
||||
provides = sorted(js_source.provides)
|
||||
requires = sorted(js_source.requires)
|
||||
module = 'true' if js_source.is_goog_module else 'false'
|
||||
|
||||
return 'goog.addDependency(\'%s\', %s, %s, %s);\n' % (
|
||||
path, provides, requires, module)
|
||||
|
||||
|
||||
def _GetOptionsParser():
|
||||
"""Get the options parser."""
|
||||
|
||||
parser = optparse.OptionParser(__doc__)
|
||||
|
||||
parser.add_option('--output_file',
|
||||
dest='output_file',
|
||||
action='store',
|
||||
help=('If specified, write output to this path instead of '
|
||||
'writing to standard output.'))
|
||||
parser.add_option('--root',
|
||||
dest='roots',
|
||||
default=[],
|
||||
action='append',
|
||||
help='A root directory to scan for JS source files. '
|
||||
'Paths of JS files in generated deps file will be '
|
||||
'relative to this path. This flag may be specified '
|
||||
'multiple times.')
|
||||
parser.add_option('--root_with_prefix',
|
||||
dest='roots_with_prefix',
|
||||
default=[],
|
||||
action='append',
|
||||
help='A root directory to scan for JS source files, plus '
|
||||
'a prefix (if either contains a space, surround with '
|
||||
'quotes). Paths in generated deps file will be relative '
|
||||
'to the root, but preceded by the prefix. This flag '
|
||||
'may be specified multiple times.')
|
||||
parser.add_option('--path_with_depspath',
|
||||
dest='paths_with_depspath',
|
||||
default=[],
|
||||
action='append',
|
||||
help='A path to a source file and an alternate path to '
|
||||
'the file in the generated deps file (if either contains '
|
||||
'a space, surround with whitespace). This flag may be '
|
||||
'specified multiple times.')
|
||||
return parser
|
||||
|
||||
|
||||
def _NormalizePathSeparators(path):
|
||||
"""Replaces OS-specific path separators with POSIX-style slashes.
|
||||
|
||||
Args:
|
||||
path: str, A file path.
|
||||
|
||||
Returns:
|
||||
str, The path with any OS-specific path separators (such as backslash on
|
||||
Windows) replaced with URL-compatible forward slashes. A no-op on systems
|
||||
that use POSIX paths.
|
||||
"""
|
||||
return path.replace(os.sep, posixpath.sep)
|
||||
|
||||
|
||||
def _GetRelativePathToSourceDict(root, prefix=''):
|
||||
"""Scans a top root directory for .js sources.
|
||||
|
||||
Args:
|
||||
root: str, Root directory.
|
||||
prefix: str, Prefix for returned paths.
|
||||
|
||||
Returns:
|
||||
dict, A map of relative paths (with prefix, if given), to source.Source
|
||||
objects.
|
||||
"""
|
||||
# Remember and restore the cwd when we're done. We work from the root so
|
||||
# that paths are relative from the root.
|
||||
start_wd = os.getcwd()
|
||||
os.chdir(root)
|
||||
|
||||
path_to_source = {}
|
||||
for path in treescan.ScanTreeForJsFiles('.'):
|
||||
prefixed_path = _NormalizePathSeparators(os.path.join(prefix, path))
|
||||
path_to_source[prefixed_path] = source.Source(source.GetFileContents(path))
|
||||
|
||||
os.chdir(start_wd)
|
||||
|
||||
return path_to_source
|
||||
|
||||
|
||||
def _GetPair(s):
|
||||
"""Return a string as a shell-parsed tuple. Two values expected."""
|
||||
try:
|
||||
# shlex uses '\' as an escape character, so they must be escaped.
|
||||
s = s.replace('\\', '\\\\')
|
||||
first, second = shlex.split(s)
|
||||
return (first, second)
|
||||
except:
|
||||
raise Exception('Unable to parse input line as a pair: %s' % s)
|
||||
|
||||
|
||||
def main():
|
||||
"""CLI frontend to MakeDepsFile."""
|
||||
logging.basicConfig(format=(sys.argv[0] + ': %(message)s'),
|
||||
level=logging.INFO)
|
||||
options, args = _GetOptionsParser().parse_args()
|
||||
|
||||
path_to_source = {}
|
||||
|
||||
# Roots without prefixes
|
||||
for root in options.roots:
|
||||
path_to_source.update(_GetRelativePathToSourceDict(root))
|
||||
|
||||
# Roots with prefixes
|
||||
for root_and_prefix in options.roots_with_prefix:
|
||||
root, prefix = _GetPair(root_and_prefix)
|
||||
path_to_source.update(_GetRelativePathToSourceDict(root, prefix=prefix))
|
||||
|
||||
# Source paths
|
||||
for path in args:
|
||||
path_to_source[path] = source.Source(source.GetFileContents(path))
|
||||
|
||||
# Source paths with alternate deps paths
|
||||
for path_with_depspath in options.paths_with_depspath:
|
||||
srcpath, depspath = _GetPair(path_with_depspath)
|
||||
path_to_source[depspath] = source.Source(source.GetFileContents(srcpath))
|
||||
|
||||
# Make our output pipe.
|
||||
if options.output_file:
|
||||
out = open(options.output_file, 'w')
|
||||
else:
|
||||
out = sys.stdout
|
||||
|
||||
out.write('// This file was autogenerated by %s.\n' % sys.argv[0])
|
||||
out.write('// Please do not edit.\n')
|
||||
|
||||
out.write(MakeDepsFile(path_to_source))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
135
vectortile/closure-library/closure/bin/build/jscompiler.py
Normal file
135
vectortile/closure-library/closure/bin/build/jscompiler.py
Normal file
@@ -0,0 +1,135 @@
|
||||
# Copyright 2010 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Utility to use the Closure Compiler CLI from Python."""
|
||||
|
||||
|
||||
import logging
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
|
||||
|
||||
# Pulls just the major and minor version numbers from the first line of
|
||||
# 'java -version'. Versions are in the format of [0-9]+\.[0-9]+\..* See:
|
||||
# http://www.oracle.com/technetwork/java/javase/versioning-naming-139433.html
|
||||
_VERSION_REGEX = re.compile(r'"([0-9]+)\.([0-9]+)')
|
||||
|
||||
|
||||
class JsCompilerError(Exception):
|
||||
"""Raised if there's an error in calling the compiler."""
|
||||
pass
|
||||
|
||||
|
||||
def _GetJavaVersionString():
|
||||
"""Get the version string from the Java VM."""
|
||||
return subprocess.check_output(['java', '-version'], stderr=subprocess.STDOUT)
|
||||
|
||||
|
||||
def _ParseJavaVersion(version_string):
|
||||
"""Returns a 2-tuple for the current version of Java installed.
|
||||
|
||||
Args:
|
||||
version_string: String of the Java version (e.g. '1.7.2-ea').
|
||||
|
||||
Returns:
|
||||
The major and minor versions, as a 2-tuple (e.g. (1, 7)).
|
||||
"""
|
||||
match = _VERSION_REGEX.search(version_string)
|
||||
if match:
|
||||
version = tuple(int(x, 10) for x in match.groups())
|
||||
assert len(version) == 2
|
||||
return version
|
||||
|
||||
|
||||
def _JavaSupports32BitMode():
|
||||
"""Determines whether the JVM supports 32-bit mode on the platform."""
|
||||
# Suppresses process output to stderr and stdout from showing up in the
|
||||
# console as we're only trying to determine 32-bit JVM support.
|
||||
supported = False
|
||||
try:
|
||||
devnull = open(os.devnull, 'wb')
|
||||
return subprocess.call(
|
||||
['java', '-d32', '-version'], stdout=devnull, stderr=devnull) == 0
|
||||
except IOError:
|
||||
pass
|
||||
else:
|
||||
devnull.close()
|
||||
return supported
|
||||
|
||||
|
||||
def _GetJsCompilerArgs(compiler_jar_path, java_version, source_paths,
|
||||
jvm_flags, compiler_flags):
|
||||
"""Assembles arguments for call to JsCompiler."""
|
||||
|
||||
if java_version < (1, 7):
|
||||
raise JsCompilerError('Closure Compiler requires Java 1.7 or higher. '
|
||||
'Please visit http://www.java.com/getjava')
|
||||
|
||||
args = ['java']
|
||||
|
||||
# Add JVM flags we believe will produce the best performance. See
|
||||
# https://groups.google.com/forum/#!topic/closure-library-discuss/7w_O9-vzlj4
|
||||
|
||||
# Attempt 32-bit mode if available (Java 7 on Mac OS X does not support 32-bit
|
||||
# mode, for example).
|
||||
if _JavaSupports32BitMode():
|
||||
args += ['-d32']
|
||||
|
||||
# Prefer the "client" VM.
|
||||
args += ['-client']
|
||||
|
||||
# Add JVM flags, if any
|
||||
if jvm_flags:
|
||||
args += jvm_flags
|
||||
|
||||
# Add the application JAR.
|
||||
args += ['-jar', compiler_jar_path]
|
||||
|
||||
for path in source_paths:
|
||||
args += ['--js', path]
|
||||
|
||||
# Add compiler flags, if any.
|
||||
if compiler_flags:
|
||||
args += compiler_flags
|
||||
|
||||
return args
|
||||
|
||||
|
||||
def Compile(compiler_jar_path, source_paths,
|
||||
jvm_flags=None,
|
||||
compiler_flags=None):
|
||||
"""Prepares command-line call to Closure Compiler.
|
||||
|
||||
Args:
|
||||
compiler_jar_path: Path to the Closure compiler .jar file.
|
||||
source_paths: Source paths to build, in order.
|
||||
jvm_flags: A list of additional flags to pass on to JVM.
|
||||
compiler_flags: A list of additional flags to pass on to Closure Compiler.
|
||||
|
||||
Returns:
|
||||
The compiled source, as a string, or None if compilation failed.
|
||||
"""
|
||||
|
||||
java_version = _ParseJavaVersion(_GetJavaVersionString())
|
||||
|
||||
args = _GetJsCompilerArgs(
|
||||
compiler_jar_path, java_version, source_paths, jvm_flags, compiler_flags)
|
||||
|
||||
logging.info('Compiling with the following command: %s', ' '.join(args))
|
||||
|
||||
try:
|
||||
return subprocess.check_output(args)
|
||||
except subprocess.CalledProcessError:
|
||||
raise JsCompilerError('JavaScript compilation failed.')
|
||||
120
vectortile/closure-library/closure/bin/build/jscompiler_test.py
Normal file
120
vectortile/closure-library/closure/bin/build/jscompiler_test.py
Normal file
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
"""Unit test for depstree."""
|
||||
|
||||
__author__ = 'nnaze@google.com (Nathan Naze)'
|
||||
|
||||
|
||||
import unittest
|
||||
|
||||
import jscompiler
|
||||
|
||||
|
||||
class JsCompilerTestCase(unittest.TestCase):
|
||||
"""Unit tests for jscompiler module."""
|
||||
|
||||
def testGetJsCompilerArgs(self):
|
||||
|
||||
original_check = jscompiler._JavaSupports32BitMode
|
||||
jscompiler._JavaSupports32BitMode = lambda: False
|
||||
args = jscompiler._GetJsCompilerArgs(
|
||||
'path/to/jscompiler.jar',
|
||||
(1, 7),
|
||||
['path/to/src1.js', 'path/to/src2.js'],
|
||||
['--test_jvm_flag'],
|
||||
['--test_compiler_flag']
|
||||
)
|
||||
|
||||
self.assertEqual(
|
||||
['java', '-client', '--test_jvm_flag',
|
||||
'-jar', 'path/to/jscompiler.jar',
|
||||
'--js', 'path/to/src1.js',
|
||||
'--js', 'path/to/src2.js', '--test_compiler_flag'],
|
||||
args)
|
||||
|
||||
def CheckJava15RaisesError():
|
||||
jscompiler._GetJsCompilerArgs(
|
||||
'path/to/jscompiler.jar',
|
||||
(1, 5),
|
||||
['path/to/src1.js', 'path/to/src2.js'],
|
||||
['--test_jvm_flag'],
|
||||
['--test_compiler_flag'])
|
||||
|
||||
self.assertRaises(jscompiler.JsCompilerError, CheckJava15RaisesError)
|
||||
jscompiler._JavaSupports32BitMode = original_check
|
||||
|
||||
def testGetJsCompilerArgs32BitJava(self):
|
||||
|
||||
original_check = jscompiler._JavaSupports32BitMode
|
||||
|
||||
# Should include the -d32 flag only if 32-bit Java is supported by the
|
||||
# system.
|
||||
jscompiler._JavaSupports32BitMode = lambda: True
|
||||
args = jscompiler._GetJsCompilerArgs(
|
||||
'path/to/jscompiler.jar',
|
||||
(1, 7),
|
||||
['path/to/src1.js', 'path/to/src2.js'],
|
||||
['--test_jvm_flag'],
|
||||
['--test_compiler_flag'])
|
||||
|
||||
self.assertEqual(
|
||||
['java', '-d32', '-client', '--test_jvm_flag',
|
||||
'-jar', 'path/to/jscompiler.jar',
|
||||
'--js', 'path/to/src1.js',
|
||||
'--js', 'path/to/src2.js',
|
||||
'--test_compiler_flag'],
|
||||
args)
|
||||
|
||||
# Should exclude the -d32 flag if 32-bit Java is not supported by the
|
||||
# system.
|
||||
jscompiler._JavaSupports32BitMode = lambda: False
|
||||
args = jscompiler._GetJsCompilerArgs(
|
||||
'path/to/jscompiler.jar',
|
||||
(1, 7),
|
||||
['path/to/src1.js', 'path/to/src2.js'],
|
||||
['--test_jvm_flag'],
|
||||
['--test_compiler_flag'])
|
||||
|
||||
self.assertEqual(
|
||||
['java', '-client', '--test_jvm_flag',
|
||||
'-jar', 'path/to/jscompiler.jar',
|
||||
'--js', 'path/to/src1.js',
|
||||
'--js', 'path/to/src2.js',
|
||||
'--test_compiler_flag'],
|
||||
args)
|
||||
|
||||
jscompiler._JavaSupports32BitMode = original_check
|
||||
|
||||
def testGetJavaVersion(self):
|
||||
|
||||
def assertVersion(expected, version_string):
|
||||
self.assertEquals(expected, jscompiler._ParseJavaVersion(version_string))
|
||||
|
||||
assertVersion((1, 7), _TEST_JAVA_VERSION_STRING)
|
||||
assertVersion((1, 4), 'java version "1.4.0_03-ea"')
|
||||
|
||||
|
||||
_TEST_JAVA_VERSION_STRING = """\
|
||||
openjdk version "1.7.0-google-v5"
|
||||
OpenJDK Runtime Environment (build 1.7.0-google-v5-64327-39803485)
|
||||
OpenJDK Server VM (build 22.0-b10, mixed mode)
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
132
vectortile/closure-library/closure/bin/build/source.py
Normal file
132
vectortile/closure-library/closure/bin/build/source.py
Normal file
@@ -0,0 +1,132 @@
|
||||
# Copyright 2009 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
"""Scans a source JS file for its provided and required namespaces.
|
||||
|
||||
Simple class to scan a JavaScript file and express its dependencies.
|
||||
"""
|
||||
|
||||
__author__ = 'nnaze@google.com'
|
||||
|
||||
|
||||
import re
|
||||
|
||||
_BASE_REGEX_STRING = r'^\s*goog\.%s\(\s*[\'"](.+)[\'"]\s*\)'
|
||||
_MODULE_REGEX = re.compile(_BASE_REGEX_STRING % 'module')
|
||||
_PROVIDE_REGEX = re.compile(_BASE_REGEX_STRING % 'provide')
|
||||
|
||||
_REQUIRE_REGEX_STRING = (r'^\s*(?:(?:var|let|const)\s+[a-zA-Z_$][a-zA-Z0-9$_]*'
|
||||
r'\s*=\s*)?goog\.require\(\s*[\'"](.+)[\'"]\s*\)')
|
||||
_REQUIRES_REGEX = re.compile(_REQUIRE_REGEX_STRING)
|
||||
|
||||
|
||||
class Source(object):
|
||||
"""Scans a JavaScript source for its provided and required namespaces."""
|
||||
|
||||
# Matches a "/* ... */" comment.
|
||||
# Note: We can't definitively distinguish a "/*" in a string literal without a
|
||||
# state machine tokenizer. We'll assume that a line starting with whitespace
|
||||
# and "/*" is a comment.
|
||||
_COMMENT_REGEX = re.compile(
|
||||
r"""
|
||||
^\s* # Start of a new line and whitespace
|
||||
/\* # Opening "/*"
|
||||
.*? # Non greedy match of any characters (including newlines)
|
||||
\*/ # Closing "*/""",
|
||||
re.MULTILINE | re.DOTALL | re.VERBOSE)
|
||||
|
||||
def __init__(self, source):
|
||||
"""Initialize a source.
|
||||
|
||||
Args:
|
||||
source: str, The JavaScript source.
|
||||
"""
|
||||
|
||||
self.provides = set()
|
||||
self.requires = set()
|
||||
self.is_goog_module = False
|
||||
|
||||
self._source = source
|
||||
self._ScanSource()
|
||||
|
||||
def GetSource(self):
|
||||
"""Get the source as a string."""
|
||||
return self._source
|
||||
|
||||
@classmethod
|
||||
def _StripComments(cls, source):
|
||||
return cls._COMMENT_REGEX.sub('', source)
|
||||
|
||||
@classmethod
|
||||
def _HasProvideGoogFlag(cls, source):
|
||||
"""Determines whether the @provideGoog flag is in a comment."""
|
||||
for comment_content in cls._COMMENT_REGEX.findall(source):
|
||||
if '@provideGoog' in comment_content:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _ScanSource(self):
|
||||
"""Fill in provides and requires by scanning the source."""
|
||||
|
||||
stripped_source = self._StripComments(self.GetSource())
|
||||
|
||||
source_lines = stripped_source.splitlines()
|
||||
for line in source_lines:
|
||||
match = _PROVIDE_REGEX.match(line)
|
||||
if match:
|
||||
self.provides.add(match.group(1))
|
||||
match = _MODULE_REGEX.match(line)
|
||||
if match:
|
||||
self.provides.add(match.group(1))
|
||||
self.is_goog_module = True
|
||||
match = _REQUIRES_REGEX.match(line)
|
||||
if match:
|
||||
self.requires.add(match.group(1))
|
||||
|
||||
# Closure's base file implicitly provides 'goog'.
|
||||
# This is indicated with the @provideGoog flag.
|
||||
if self._HasProvideGoogFlag(self.GetSource()):
|
||||
|
||||
if len(self.provides) or len(self.requires):
|
||||
raise Exception(
|
||||
'Base file should not provide or require namespaces.')
|
||||
|
||||
self.provides.add('goog')
|
||||
|
||||
|
||||
def GetFileContents(path):
|
||||
"""Get a file's contents as a string.
|
||||
|
||||
Args:
|
||||
path: str, Path to file.
|
||||
|
||||
Returns:
|
||||
str, Contents of file.
|
||||
|
||||
Raises:
|
||||
IOError: An error occurred opening or reading the file.
|
||||
|
||||
"""
|
||||
fileobj = None
|
||||
try:
|
||||
fileobj = open(path)
|
||||
return fileobj.read()
|
||||
except IOError as error:
|
||||
raise IOError('An error occurred opening or reading the file: %s. %s'
|
||||
% (path, error))
|
||||
finally:
|
||||
if fileobj is not None:
|
||||
fileobj.close()
|
||||
BIN
vectortile/closure-library/closure/bin/build/source.pyc
Normal file
BIN
vectortile/closure-library/closure/bin/build/source.pyc
Normal file
Binary file not shown.
152
vectortile/closure-library/closure/bin/build/source_test.py
Normal file
152
vectortile/closure-library/closure/bin/build/source_test.py
Normal file
@@ -0,0 +1,152 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2010 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
"""Unit test for source."""
|
||||
|
||||
__author__ = 'nnaze@google.com (Nathan Naze)'
|
||||
|
||||
|
||||
import unittest
|
||||
|
||||
import source
|
||||
|
||||
|
||||
class SourceTestCase(unittest.TestCase):
|
||||
"""Unit test for source. Tests the parser on a known source input."""
|
||||
|
||||
def testSourceScan(self):
|
||||
test_source = source.Source(_TEST_SOURCE)
|
||||
|
||||
self.assertEqual(set(['foo', 'foo.test']),
|
||||
test_source.provides)
|
||||
self.assertEqual(set(['goog.dom', 'goog.events.EventType']),
|
||||
test_source.requires)
|
||||
self.assertFalse(test_source.is_goog_module)
|
||||
|
||||
def testSourceScanBase(self):
|
||||
test_source = source.Source(_TEST_BASE_SOURCE)
|
||||
|
||||
self.assertEqual(set(['goog']),
|
||||
test_source.provides)
|
||||
self.assertEqual(test_source.requires, set())
|
||||
self.assertFalse(test_source.is_goog_module)
|
||||
|
||||
def testSourceScanBadBase(self):
|
||||
|
||||
def MakeSource():
|
||||
source.Source(_TEST_BAD_BASE_SOURCE)
|
||||
|
||||
self.assertRaises(Exception, MakeSource)
|
||||
|
||||
def testSourceScanGoogModule(self):
|
||||
test_source = source.Source(_TEST_MODULE_SOURCE)
|
||||
|
||||
self.assertEqual(set(['foo']),
|
||||
test_source.provides)
|
||||
self.assertEqual(set(['bar']),
|
||||
test_source.requires)
|
||||
self.assertTrue(test_source.is_goog_module)
|
||||
|
||||
def testStripComments(self):
|
||||
self.assertEquals(
|
||||
'\nvar foo = function() {}',
|
||||
source.Source._StripComments((
|
||||
'/* This is\n'
|
||||
' a comment split\n'
|
||||
' over multiple lines\n'
|
||||
'*/\n'
|
||||
'var foo = function() {}')))
|
||||
|
||||
def testGoogStatementsInComments(self):
|
||||
test_source = source.Source(_TEST_COMMENT_SOURCE)
|
||||
|
||||
self.assertEqual(set(['foo']),
|
||||
test_source.provides)
|
||||
self.assertEqual(set(['goog.events.EventType']),
|
||||
test_source.requires)
|
||||
self.assertFalse(test_source.is_goog_module)
|
||||
|
||||
def testHasProvideGoog(self):
|
||||
self.assertTrue(source.Source._HasProvideGoogFlag(_TEST_BASE_SOURCE))
|
||||
self.assertTrue(source.Source._HasProvideGoogFlag(_TEST_BAD_BASE_SOURCE))
|
||||
self.assertFalse(source.Source._HasProvideGoogFlag(_TEST_COMMENT_SOURCE))
|
||||
|
||||
|
||||
_TEST_MODULE_SOURCE = """
|
||||
goog.module('foo');
|
||||
var b = goog.require('bar');
|
||||
"""
|
||||
|
||||
|
||||
_TEST_SOURCE = """// Fake copyright notice
|
||||
|
||||
/** Very important comment. */
|
||||
|
||||
goog.provide('foo');
|
||||
goog.provide('foo.test');
|
||||
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.events.EventType');
|
||||
|
||||
function foo() {
|
||||
// Set bar to seventeen to increase performance.
|
||||
this.bar = 17;
|
||||
}
|
||||
"""
|
||||
|
||||
_TEST_COMMENT_SOURCE = """// Fake copyright notice
|
||||
|
||||
goog.provide('foo');
|
||||
|
||||
/*
|
||||
goog.provide('foo.test');
|
||||
*/
|
||||
|
||||
/*
|
||||
goog.require('goog.dom');
|
||||
*/
|
||||
|
||||
// goog.require('goog.dom');
|
||||
|
||||
goog.require('goog.events.EventType');
|
||||
|
||||
function bar() {
|
||||
this.baz = 55;
|
||||
}
|
||||
"""
|
||||
|
||||
_TEST_BASE_SOURCE = """
|
||||
/**
|
||||
* @fileoverview The base file.
|
||||
* @provideGoog
|
||||
*/
|
||||
|
||||
var goog = goog || {};
|
||||
"""
|
||||
|
||||
_TEST_BAD_BASE_SOURCE = """
|
||||
/**
|
||||
* @fileoverview The base file.
|
||||
* @provideGoog
|
||||
*/
|
||||
|
||||
goog.provide('goog');
|
||||
"""
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
78
vectortile/closure-library/closure/bin/build/treescan.py
Normal file
78
vectortile/closure-library/closure/bin/build/treescan.py
Normal file
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2010 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
"""Shared utility functions for scanning directory trees."""
|
||||
|
||||
import os
|
||||
import re
|
||||
|
||||
|
||||
__author__ = 'nnaze@google.com (Nathan Naze)'
|
||||
|
||||
|
||||
# Matches a .js file path.
|
||||
_JS_FILE_REGEX = re.compile(r'^.+\.js$')
|
||||
|
||||
|
||||
def ScanTreeForJsFiles(root):
|
||||
"""Scans a directory tree for JavaScript files.
|
||||
|
||||
Args:
|
||||
root: str, Path to a root directory.
|
||||
|
||||
Returns:
|
||||
An iterable of paths to JS files, relative to cwd.
|
||||
"""
|
||||
return ScanTree(root, path_filter=_JS_FILE_REGEX)
|
||||
|
||||
|
||||
def ScanTree(root, path_filter=None, ignore_hidden=True):
|
||||
"""Scans a directory tree for files.
|
||||
|
||||
Args:
|
||||
root: str, Path to a root directory.
|
||||
path_filter: A regular expression filter. If set, only paths matching
|
||||
the path_filter are returned.
|
||||
ignore_hidden: If True, do not follow or return hidden directories or files
|
||||
(those starting with a '.' character).
|
||||
|
||||
Yields:
|
||||
A string path to files, relative to cwd.
|
||||
"""
|
||||
|
||||
def OnError(os_error):
|
||||
raise os_error
|
||||
|
||||
for dirpath, dirnames, filenames in os.walk(root, onerror=OnError):
|
||||
# os.walk allows us to modify dirnames to prevent decent into particular
|
||||
# directories. Avoid hidden directories.
|
||||
for dirname in dirnames:
|
||||
if ignore_hidden and dirname.startswith('.'):
|
||||
dirnames.remove(dirname)
|
||||
|
||||
for filename in filenames:
|
||||
|
||||
# nothing that starts with '.'
|
||||
if ignore_hidden and filename.startswith('.'):
|
||||
continue
|
||||
|
||||
fullpath = os.path.join(dirpath, filename)
|
||||
|
||||
if path_filter and not path_filter.match(fullpath):
|
||||
continue
|
||||
|
||||
yield os.path.normpath(fullpath)
|
||||
BIN
vectortile/closure-library/closure/bin/build/treescan.pyc
Normal file
BIN
vectortile/closure-library/closure/bin/build/treescan.pyc
Normal file
Binary file not shown.
590
vectortile/closure-library/closure/bin/calcdeps.py
Normal file
590
vectortile/closure-library/closure/bin/calcdeps.py
Normal file
@@ -0,0 +1,590 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
"""Calculates JavaScript dependencies without requiring Google's build system.
|
||||
|
||||
This tool is deprecated and is provided for legacy users.
|
||||
See build/closurebuilder.py and build/depswriter.py for the current tools.
|
||||
|
||||
It iterates over a number of search paths and builds a dependency tree. With
|
||||
the inputs provided, it walks the dependency tree and outputs all the files
|
||||
required for compilation.
|
||||
"""
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
try:
|
||||
import distutils.version
|
||||
except ImportError:
|
||||
# distutils is not available in all environments
|
||||
distutils = None
|
||||
|
||||
import logging
|
||||
import optparse
|
||||
import os
|
||||
import re
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
_BASE_REGEX_STRING = '^\s*goog\.%s\(\s*[\'"](.+)[\'"]\s*\)'
|
||||
req_regex = re.compile(_BASE_REGEX_STRING % 'require')
|
||||
prov_regex = re.compile(_BASE_REGEX_STRING % 'provide')
|
||||
ns_regex = re.compile('^ns:((\w+\.)*(\w+))$')
|
||||
version_regex = re.compile('[\.0-9]+')
|
||||
|
||||
|
||||
def IsValidFile(ref):
|
||||
"""Returns true if the provided reference is a file and exists."""
|
||||
return os.path.isfile(ref)
|
||||
|
||||
|
||||
def IsJsFile(ref):
|
||||
"""Returns true if the provided reference is a Javascript file."""
|
||||
return ref.endswith('.js')
|
||||
|
||||
|
||||
def IsNamespace(ref):
|
||||
"""Returns true if the provided reference is a namespace."""
|
||||
return re.match(ns_regex, ref) is not None
|
||||
|
||||
|
||||
def IsDirectory(ref):
|
||||
"""Returns true if the provided reference is a directory."""
|
||||
return os.path.isdir(ref)
|
||||
|
||||
|
||||
def ExpandDirectories(refs):
|
||||
"""Expands any directory references into inputs.
|
||||
|
||||
Description:
|
||||
Looks for any directories in the provided references. Found directories
|
||||
are recursively searched for .js files, which are then added to the result
|
||||
list.
|
||||
|
||||
Args:
|
||||
refs: a list of references such as files, directories, and namespaces
|
||||
|
||||
Returns:
|
||||
A list of references with directories removed and replaced by any
|
||||
.js files that are found in them. Also, the paths will be normalized.
|
||||
"""
|
||||
result = []
|
||||
for ref in refs:
|
||||
if IsDirectory(ref):
|
||||
# Disable 'Unused variable' for subdirs
|
||||
# pylint: disable=unused-variable
|
||||
for (directory, subdirs, filenames) in os.walk(ref):
|
||||
for filename in filenames:
|
||||
if IsJsFile(filename):
|
||||
result.append(os.path.join(directory, filename))
|
||||
else:
|
||||
result.append(ref)
|
||||
return map(os.path.normpath, result)
|
||||
|
||||
|
||||
class DependencyInfo(object):
|
||||
"""Represents a dependency that is used to build and walk a tree."""
|
||||
|
||||
def __init__(self, filename):
|
||||
self.filename = filename
|
||||
self.provides = []
|
||||
self.requires = []
|
||||
|
||||
def __str__(self):
|
||||
return '%s Provides: %s Requires: %s' % (self.filename,
|
||||
repr(self.provides),
|
||||
repr(self.requires))
|
||||
|
||||
|
||||
def BuildDependenciesFromFiles(files):
|
||||
"""Build a list of dependencies from a list of files.
|
||||
|
||||
Description:
|
||||
Takes a list of files, extracts their provides and requires, and builds
|
||||
out a list of dependency objects.
|
||||
|
||||
Args:
|
||||
files: a list of files to be parsed for goog.provides and goog.requires.
|
||||
|
||||
Returns:
|
||||
A list of dependency objects, one for each file in the files argument.
|
||||
"""
|
||||
result = []
|
||||
filenames = set()
|
||||
for filename in files:
|
||||
if filename in filenames:
|
||||
continue
|
||||
|
||||
# Python 3 requires the file encoding to be specified
|
||||
if (sys.version_info[0] < 3):
|
||||
file_handle = open(filename, 'r')
|
||||
else:
|
||||
file_handle = open(filename, 'r', encoding='utf8')
|
||||
|
||||
try:
|
||||
dep = CreateDependencyInfo(filename, file_handle)
|
||||
result.append(dep)
|
||||
finally:
|
||||
file_handle.close()
|
||||
|
||||
filenames.add(filename)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def CreateDependencyInfo(filename, source):
|
||||
"""Create dependency info.
|
||||
|
||||
Args:
|
||||
filename: Filename for source.
|
||||
source: File-like object containing source.
|
||||
|
||||
Returns:
|
||||
A DependencyInfo object with provides and requires filled.
|
||||
"""
|
||||
dep = DependencyInfo(filename)
|
||||
for line in source:
|
||||
if re.match(req_regex, line):
|
||||
dep.requires.append(re.search(req_regex, line).group(1))
|
||||
if re.match(prov_regex, line):
|
||||
dep.provides.append(re.search(prov_regex, line).group(1))
|
||||
return dep
|
||||
|
||||
|
||||
def BuildDependencyHashFromDependencies(deps):
|
||||
"""Builds a hash for searching dependencies by the namespaces they provide.
|
||||
|
||||
Description:
|
||||
Dependency objects can provide multiple namespaces. This method enumerates
|
||||
the provides of each dependency and adds them to a hash that can be used
|
||||
to easily resolve a given dependency by a namespace it provides.
|
||||
|
||||
Args:
|
||||
deps: a list of dependency objects used to build the hash.
|
||||
|
||||
Raises:
|
||||
Exception: If a multiple files try to provide the same namepace.
|
||||
|
||||
Returns:
|
||||
A hash table { namespace: dependency } that can be used to resolve a
|
||||
dependency by a namespace it provides.
|
||||
"""
|
||||
dep_hash = {}
|
||||
for dep in deps:
|
||||
for provide in dep.provides:
|
||||
if provide in dep_hash:
|
||||
raise Exception('Duplicate provide (%s) in (%s, %s)' % (
|
||||
provide,
|
||||
dep_hash[provide].filename,
|
||||
dep.filename))
|
||||
dep_hash[provide] = dep
|
||||
return dep_hash
|
||||
|
||||
|
||||
def CalculateDependencies(paths, inputs):
|
||||
"""Calculates the dependencies for given inputs.
|
||||
|
||||
Description:
|
||||
This method takes a list of paths (files, directories) and builds a
|
||||
searchable data structure based on the namespaces that each .js file
|
||||
provides. It then parses through each input, resolving dependencies
|
||||
against this data structure. The final output is a list of files,
|
||||
including the inputs, that represent all of the code that is needed to
|
||||
compile the given inputs.
|
||||
|
||||
Args:
|
||||
paths: the references (files, directories) that are used to build the
|
||||
dependency hash.
|
||||
inputs: the inputs (files, directories, namespaces) that have dependencies
|
||||
that need to be calculated.
|
||||
|
||||
Raises:
|
||||
Exception: if a provided input is invalid.
|
||||
|
||||
Returns:
|
||||
A list of all files, including inputs, that are needed to compile the given
|
||||
inputs.
|
||||
"""
|
||||
deps = BuildDependenciesFromFiles(paths + inputs)
|
||||
search_hash = BuildDependencyHashFromDependencies(deps)
|
||||
result_list = []
|
||||
seen_list = []
|
||||
for input_file in inputs:
|
||||
if IsNamespace(input_file):
|
||||
namespace = re.search(ns_regex, input_file).group(1)
|
||||
if namespace not in search_hash:
|
||||
raise Exception('Invalid namespace (%s)' % namespace)
|
||||
input_file = search_hash[namespace].filename
|
||||
if not IsValidFile(input_file) or not IsJsFile(input_file):
|
||||
raise Exception('Invalid file (%s)' % input_file)
|
||||
seen_list.append(input_file)
|
||||
file_handle = open(input_file, 'r')
|
||||
try:
|
||||
for line in file_handle:
|
||||
if re.match(req_regex, line):
|
||||
require = re.search(req_regex, line).group(1)
|
||||
ResolveDependencies(require, search_hash, result_list, seen_list)
|
||||
finally:
|
||||
file_handle.close()
|
||||
result_list.append(input_file)
|
||||
|
||||
# All files depend on base.js, so put it first.
|
||||
base_js_path = FindClosureBasePath(paths)
|
||||
if base_js_path:
|
||||
result_list.insert(0, base_js_path)
|
||||
else:
|
||||
logging.warning('Closure Library base.js not found.')
|
||||
|
||||
return result_list
|
||||
|
||||
|
||||
def FindClosureBasePath(paths):
|
||||
"""Given a list of file paths, return Closure base.js path, if any.
|
||||
|
||||
Args:
|
||||
paths: A list of paths.
|
||||
|
||||
Returns:
|
||||
The path to Closure's base.js file including filename, if found.
|
||||
"""
|
||||
|
||||
for path in paths:
|
||||
pathname, filename = os.path.split(path)
|
||||
|
||||
if filename == 'base.js':
|
||||
f = open(path)
|
||||
|
||||
is_base = False
|
||||
|
||||
# Sanity check that this is the Closure base file. Check that this
|
||||
# is where goog is defined. This is determined by the @provideGoog
|
||||
# flag.
|
||||
for line in f:
|
||||
if '@provideGoog' in line:
|
||||
is_base = True
|
||||
break
|
||||
|
||||
f.close()
|
||||
|
||||
if is_base:
|
||||
return path
|
||||
|
||||
def ResolveDependencies(require, search_hash, result_list, seen_list):
|
||||
"""Takes a given requirement and resolves all of the dependencies for it.
|
||||
|
||||
Description:
|
||||
A given requirement may require other dependencies. This method
|
||||
recursively resolves all dependencies for the given requirement.
|
||||
|
||||
Raises:
|
||||
Exception: when require does not exist in the search_hash.
|
||||
|
||||
Args:
|
||||
require: the namespace to resolve dependencies for.
|
||||
search_hash: the data structure used for resolving dependencies.
|
||||
result_list: a list of filenames that have been calculated as dependencies.
|
||||
This variable is the output for this function.
|
||||
seen_list: a list of filenames that have been 'seen'. This is required
|
||||
for the dependency->dependant ordering.
|
||||
"""
|
||||
if require not in search_hash:
|
||||
raise Exception('Missing provider for (%s)' % require)
|
||||
|
||||
dep = search_hash[require]
|
||||
if not dep.filename in seen_list:
|
||||
seen_list.append(dep.filename)
|
||||
for sub_require in dep.requires:
|
||||
ResolveDependencies(sub_require, search_hash, result_list, seen_list)
|
||||
result_list.append(dep.filename)
|
||||
|
||||
|
||||
def GetDepsLine(dep, base_path):
|
||||
"""Returns a JS string for a dependency statement in the deps.js file.
|
||||
|
||||
Args:
|
||||
dep: The dependency that we're printing.
|
||||
base_path: The path to Closure's base.js including filename.
|
||||
"""
|
||||
return 'goog.addDependency("%s", %s, %s);' % (
|
||||
GetRelpath(dep.filename, base_path), dep.provides, dep.requires)
|
||||
|
||||
|
||||
def GetRelpath(path, start):
|
||||
"""Return a relative path to |path| from |start|."""
|
||||
# NOTE: Python 2.6 provides os.path.relpath, which has almost the same
|
||||
# functionality as this function. Since we want to support 2.4, we have
|
||||
# to implement it manually. :(
|
||||
path_list = os.path.abspath(os.path.normpath(path)).split(os.sep)
|
||||
start_list = os.path.abspath(
|
||||
os.path.normpath(os.path.dirname(start))).split(os.sep)
|
||||
|
||||
common_prefix_count = 0
|
||||
for i in range(0, min(len(path_list), len(start_list))):
|
||||
if path_list[i] != start_list[i]:
|
||||
break
|
||||
common_prefix_count += 1
|
||||
|
||||
# Always use forward slashes, because this will get expanded to a url,
|
||||
# not a file path.
|
||||
return '/'.join(['..'] * (len(start_list) - common_prefix_count) +
|
||||
path_list[common_prefix_count:])
|
||||
|
||||
|
||||
def PrintLine(msg, out):
|
||||
out.write(msg)
|
||||
out.write('\n')
|
||||
|
||||
|
||||
def PrintDeps(source_paths, deps, out):
|
||||
"""Print out a deps.js file from a list of source paths.
|
||||
|
||||
Args:
|
||||
source_paths: Paths that we should generate dependency info for.
|
||||
deps: Paths that provide dependency info. Their dependency info should
|
||||
not appear in the deps file.
|
||||
out: The output file.
|
||||
|
||||
Returns:
|
||||
True on success, false if it was unable to find the base path
|
||||
to generate deps relative to.
|
||||
"""
|
||||
base_path = FindClosureBasePath(source_paths + deps)
|
||||
if not base_path:
|
||||
return False
|
||||
|
||||
PrintLine('// This file was autogenerated by calcdeps.py', out)
|
||||
excludesSet = set(deps)
|
||||
|
||||
for dep in BuildDependenciesFromFiles(source_paths + deps):
|
||||
if not dep.filename in excludesSet:
|
||||
PrintLine(GetDepsLine(dep, base_path), out)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
def PrintScript(source_paths, out):
|
||||
for index, dep in enumerate(source_paths):
|
||||
PrintLine('// Input %d' % index, out)
|
||||
f = open(dep, 'r')
|
||||
PrintLine(f.read(), out)
|
||||
f.close()
|
||||
|
||||
|
||||
def GetJavaVersion():
|
||||
"""Returns the string for the current version of Java installed."""
|
||||
proc = subprocess.Popen(['java', '-version'], stderr=subprocess.PIPE)
|
||||
proc.wait()
|
||||
version_line = proc.stderr.read().splitlines()[0]
|
||||
return version_regex.search(version_line.decode('utf-8')).group()
|
||||
|
||||
|
||||
def FilterByExcludes(options, files):
|
||||
"""Filters the given files by the exlusions specified at the command line.
|
||||
|
||||
Args:
|
||||
options: The flags to calcdeps.
|
||||
files: The files to filter.
|
||||
Returns:
|
||||
A list of files.
|
||||
"""
|
||||
excludes = []
|
||||
if options.excludes:
|
||||
excludes = ExpandDirectories(options.excludes)
|
||||
|
||||
excludesSet = set(excludes)
|
||||
return [i for i in files if not i in excludesSet]
|
||||
|
||||
|
||||
def GetPathsFromOptions(options):
|
||||
"""Generates the path files from flag options.
|
||||
|
||||
Args:
|
||||
options: The flags to calcdeps.
|
||||
Returns:
|
||||
A list of files in the specified paths. (strings).
|
||||
"""
|
||||
|
||||
search_paths = options.paths
|
||||
if not search_paths:
|
||||
search_paths = ['.'] # Add default folder if no path is specified.
|
||||
|
||||
search_paths = ExpandDirectories(search_paths)
|
||||
return FilterByExcludes(options, search_paths)
|
||||
|
||||
|
||||
def GetInputsFromOptions(options):
|
||||
"""Generates the inputs from flag options.
|
||||
|
||||
Args:
|
||||
options: The flags to calcdeps.
|
||||
Returns:
|
||||
A list of inputs (strings).
|
||||
"""
|
||||
inputs = options.inputs
|
||||
if not inputs: # Parse stdin
|
||||
logging.info('No inputs specified. Reading from stdin...')
|
||||
inputs = filter(None, [line.strip('\n') for line in sys.stdin.readlines()])
|
||||
|
||||
logging.info('Scanning files...')
|
||||
inputs = ExpandDirectories(inputs)
|
||||
|
||||
return FilterByExcludes(options, inputs)
|
||||
|
||||
|
||||
def Compile(compiler_jar_path, source_paths, out, flags=None):
|
||||
"""Prepares command-line call to Closure compiler.
|
||||
|
||||
Args:
|
||||
compiler_jar_path: Path to the Closure compiler .jar file.
|
||||
source_paths: Source paths to build, in order.
|
||||
flags: A list of additional flags to pass on to Closure compiler.
|
||||
"""
|
||||
args = ['java', '-jar', compiler_jar_path]
|
||||
for path in source_paths:
|
||||
args += ['--js', path]
|
||||
|
||||
if flags:
|
||||
args += flags
|
||||
|
||||
logging.info('Compiling with the following command: %s', ' '.join(args))
|
||||
proc = subprocess.Popen(args, stdout=subprocess.PIPE)
|
||||
(stdoutdata, stderrdata) = proc.communicate()
|
||||
if proc.returncode != 0:
|
||||
logging.error('JavaScript compilation failed.')
|
||||
sys.exit(1)
|
||||
else:
|
||||
out.write(stdoutdata.decode('utf-8'))
|
||||
|
||||
|
||||
def main():
|
||||
"""The entrypoint for this script."""
|
||||
|
||||
logging.basicConfig(format='calcdeps.py: %(message)s', level=logging.INFO)
|
||||
|
||||
usage = 'usage: %prog [options] arg'
|
||||
parser = optparse.OptionParser(usage)
|
||||
parser.add_option('-i',
|
||||
'--input',
|
||||
dest='inputs',
|
||||
action='append',
|
||||
help='The inputs to calculate dependencies for. Valid '
|
||||
'values can be files, directories, or namespaces '
|
||||
'(ns:goog.net.XhrIo). Only relevant to "list" and '
|
||||
'"script" output.')
|
||||
parser.add_option('-p',
|
||||
'--path',
|
||||
dest='paths',
|
||||
action='append',
|
||||
help='The paths that should be traversed to build the '
|
||||
'dependencies.')
|
||||
parser.add_option('-d',
|
||||
'--dep',
|
||||
dest='deps',
|
||||
action='append',
|
||||
help='Directories or files that should be traversed to '
|
||||
'find required dependencies for the deps file. '
|
||||
'Does not generate dependency information for names '
|
||||
'provided by these files. Only useful in "deps" mode.')
|
||||
parser.add_option('-e',
|
||||
'--exclude',
|
||||
dest='excludes',
|
||||
action='append',
|
||||
help='Files or directories to exclude from the --path '
|
||||
'and --input flags')
|
||||
parser.add_option('-o',
|
||||
'--output_mode',
|
||||
dest='output_mode',
|
||||
action='store',
|
||||
default='list',
|
||||
help='The type of output to generate from this script. '
|
||||
'Options are "list" for a list of filenames, "script" '
|
||||
'for a single script containing the contents of all the '
|
||||
'file, "deps" to generate a deps.js file for all '
|
||||
'paths, or "compiled" to produce compiled output with '
|
||||
'the Closure compiler.')
|
||||
parser.add_option('-c',
|
||||
'--compiler_jar',
|
||||
dest='compiler_jar',
|
||||
action='store',
|
||||
help='The location of the Closure compiler .jar file.')
|
||||
parser.add_option('-f',
|
||||
'--compiler_flag',
|
||||
'--compiler_flags', # for backwards compatability
|
||||
dest='compiler_flags',
|
||||
action='append',
|
||||
help='Additional flag to pass to the Closure compiler. '
|
||||
'May be specified multiple times to pass multiple flags.')
|
||||
parser.add_option('--output_file',
|
||||
dest='output_file',
|
||||
action='store',
|
||||
help=('If specified, write output to this path instead of '
|
||||
'writing to standard output.'))
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
|
||||
search_paths = GetPathsFromOptions(options)
|
||||
|
||||
if options.output_file:
|
||||
out = open(options.output_file, 'w')
|
||||
else:
|
||||
out = sys.stdout
|
||||
|
||||
if options.output_mode == 'deps':
|
||||
result = PrintDeps(search_paths, ExpandDirectories(options.deps or []), out)
|
||||
if not result:
|
||||
logging.error('Could not find Closure Library in the specified paths')
|
||||
sys.exit(1)
|
||||
|
||||
return
|
||||
|
||||
inputs = GetInputsFromOptions(options)
|
||||
|
||||
logging.info('Finding Closure dependencies...')
|
||||
deps = CalculateDependencies(search_paths, inputs)
|
||||
output_mode = options.output_mode
|
||||
|
||||
if output_mode == 'script':
|
||||
PrintScript(deps, out)
|
||||
elif output_mode == 'list':
|
||||
# Just print out a dep per line
|
||||
for dep in deps:
|
||||
PrintLine(dep, out)
|
||||
elif output_mode == 'compiled':
|
||||
# Make sure a .jar is specified.
|
||||
if not options.compiler_jar:
|
||||
logging.error('--compiler_jar flag must be specified if --output is '
|
||||
'"compiled"')
|
||||
sys.exit(1)
|
||||
|
||||
# User friendly version check.
|
||||
if distutils and not (distutils.version.LooseVersion(GetJavaVersion()) >
|
||||
distutils.version.LooseVersion('1.6')):
|
||||
logging.error('Closure Compiler requires Java 1.6 or higher.')
|
||||
logging.error('Please visit http://www.java.com/getjava')
|
||||
sys.exit(1)
|
||||
|
||||
Compile(options.compiler_jar, deps, out, options.compiler_flags)
|
||||
|
||||
else:
|
||||
logging.error('Invalid value for --output flag.')
|
||||
sys.exit(1)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
39
vectortile/closure-library/closure/bin/labs/code/closure.el
Normal file
39
vectortile/closure-library/closure/bin/labs/code/closure.el
Normal file
@@ -0,0 +1,39 @@
|
||||
;; Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
;;
|
||||
;; Licensed under the Apache License, Version 2.0 (the "License");
|
||||
;; you may not use this file except in compliance with the License.
|
||||
;; You may obtain a copy of the License at
|
||||
;;
|
||||
;; http://www.apache.org/licenses/LICENSE-2.0
|
||||
;;
|
||||
;; Unless required `by applicable law or agreed to in writing, software
|
||||
;; distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
;; See the License for the specific language governing permissions and
|
||||
;; limitations under the License.
|
||||
|
||||
;; Closure JS code editing functions for emacs.
|
||||
|
||||
;; Author: nnaze@google.com (Nathan Naze)
|
||||
|
||||
;; Remember the path of this file, as we will base our paths on it.
|
||||
(setq closure-el-path load-file-name)
|
||||
|
||||
(defun closure-el-directory ()
|
||||
"Get the directory the closure.el file lives in."
|
||||
(file-name-directory closure-el-path))
|
||||
|
||||
(defun closure-generate-jsdoc-path()
|
||||
"The path of the generate_jsdoc.py script."
|
||||
(concat (closure-el-directory) "generate_jsdoc.py"))
|
||||
|
||||
(defun closure-insert-jsdoc ()
|
||||
"Insert JSDoc for the next function after the cursor."
|
||||
(interactive)
|
||||
(save-excursion ; Remembers cursor location
|
||||
(call-process-region
|
||||
(point) (point-max)
|
||||
(closure-generate-jsdoc-path)
|
||||
t t)))
|
||||
|
||||
(provide 'closure)
|
||||
@@ -0,0 +1,31 @@
|
||||
;; Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
;;
|
||||
;; Licensed under the Apache License, Version 2.0 (the "License");
|
||||
;; you may not use this file except in compliance with the License.
|
||||
;; You may obtain a copy of the License at
|
||||
;;
|
||||
;; http://www.apache.org/licenses/LICENSE-2.0
|
||||
;;
|
||||
;; Unless required `by applicable law or agreed to in writing, software
|
||||
;; distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
;; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
;; See the License for the specific language governing permissions and
|
||||
;; limitations under the License.
|
||||
|
||||
;; Unit tests for closure_test.el
|
||||
|
||||
;; Author: nnaze@google.com (Nathan Naze)
|
||||
|
||||
(require 'cl)
|
||||
|
||||
(setq closure-test-directory (file-name-directory load-file-name))
|
||||
|
||||
(load-file (concat closure-test-directory "closure.el"))
|
||||
|
||||
(setq closure-el-path "/test/path/closure.el")
|
||||
|
||||
(assert (string= "/test/path/" (closure-el-directory)))
|
||||
|
||||
(assert (string=
|
||||
"/test/path/generate_jsdoc.py"
|
||||
(closure-generate-jsdoc-path)))
|
||||
@@ -0,0 +1,171 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
"""Tool to insert JsDoc before a function.
|
||||
|
||||
This script attempts to find the first function passed in to stdin, generate
|
||||
JSDoc for it (with argument names and possibly return value), and inject
|
||||
it in the string. This is intended to be used as a subprocess by editors
|
||||
such as emacs and vi.
|
||||
"""
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
# Matches a typical Closure-style function definition.
|
||||
_FUNCTION_REGEX = re.compile(r"""
|
||||
# Start of line
|
||||
^
|
||||
|
||||
# Indentation
|
||||
(?P<indentation>[ ]*)
|
||||
|
||||
# Identifier (handling split across line)
|
||||
(?P<identifier>\w+(\s*\.\s*\w+)*)
|
||||
|
||||
# "= function"
|
||||
\s* = \s* function \s*
|
||||
|
||||
# opening paren
|
||||
\(
|
||||
|
||||
# Function arguments
|
||||
(?P<arguments>(?:\s|\w+|,)*)
|
||||
|
||||
# closing paren
|
||||
\)
|
||||
|
||||
# opening bracket
|
||||
\s* {
|
||||
|
||||
""", re.MULTILINE | re.VERBOSE)
|
||||
|
||||
|
||||
def _MatchFirstFunction(script):
|
||||
"""Match the first function seen in the script."""
|
||||
return _FUNCTION_REGEX.search(script)
|
||||
|
||||
|
||||
def _ParseArgString(arg_string):
|
||||
"""Parse an argument string (inside parens) into parameter names."""
|
||||
for arg in arg_string.split(','):
|
||||
arg = arg.strip()
|
||||
if arg:
|
||||
yield arg
|
||||
|
||||
|
||||
def _ExtractFunctionBody(script, indentation=0):
|
||||
"""Attempt to return the function body."""
|
||||
|
||||
# Real extraction would require a token parser and state machines.
|
||||
# We look for first bracket at the same level of indentation.
|
||||
regex_str = r'{(.*?)^[ ]{%d}}' % indentation
|
||||
|
||||
function_regex = re.compile(regex_str, re.MULTILINE | re.DOTALL)
|
||||
match = function_regex.search(script)
|
||||
if match:
|
||||
return match.group(1)
|
||||
|
||||
|
||||
def _ContainsReturnValue(function_body):
|
||||
"""Attempt to determine if the function body returns a value."""
|
||||
return_regex = re.compile(r'\breturn\b[^;]')
|
||||
|
||||
# If this matches, we assume they're returning something.
|
||||
return bool(return_regex.search(function_body))
|
||||
|
||||
|
||||
def _InsertString(original_string, inserted_string, index):
|
||||
"""Insert a string into another string at a given index."""
|
||||
return original_string[0:index] + inserted_string + original_string[index:]
|
||||
|
||||
|
||||
def _GenerateJsDoc(args, return_val=False):
|
||||
"""Generate JSDoc for a function.
|
||||
|
||||
Args:
|
||||
args: A list of names of the argument.
|
||||
return_val: Whether the function has a return value.
|
||||
|
||||
Returns:
|
||||
The JSDoc as a string.
|
||||
"""
|
||||
|
||||
lines = []
|
||||
lines.append('/**')
|
||||
|
||||
lines += [' * @param {} %s' % arg for arg in args]
|
||||
|
||||
if return_val:
|
||||
lines.append(' * @return')
|
||||
|
||||
lines.append(' */')
|
||||
|
||||
return '\n'.join(lines) + '\n'
|
||||
|
||||
|
||||
def _IndentString(source_string, indentation):
|
||||
"""Indent string some number of characters."""
|
||||
lines = [(indentation * ' ') + line
|
||||
for line in source_string.splitlines(True)]
|
||||
return ''.join(lines)
|
||||
|
||||
|
||||
def InsertJsDoc(script):
|
||||
"""Attempt to insert JSDoc for the first seen function in the script.
|
||||
|
||||
Args:
|
||||
script: The script, as a string.
|
||||
|
||||
Returns:
|
||||
Returns the new string if function was found and JSDoc inserted. Otherwise
|
||||
returns None.
|
||||
"""
|
||||
|
||||
match = _MatchFirstFunction(script)
|
||||
if not match:
|
||||
return
|
||||
|
||||
# Add argument flags.
|
||||
args_string = match.group('arguments')
|
||||
args = _ParseArgString(args_string)
|
||||
|
||||
start_index = match.start(0)
|
||||
function_to_end = script[start_index:]
|
||||
|
||||
lvalue_indentation = len(match.group('indentation'))
|
||||
|
||||
return_val = False
|
||||
function_body = _ExtractFunctionBody(function_to_end, lvalue_indentation)
|
||||
if function_body:
|
||||
return_val = _ContainsReturnValue(function_body)
|
||||
|
||||
jsdoc = _GenerateJsDoc(args, return_val)
|
||||
if lvalue_indentation:
|
||||
jsdoc = _IndentString(jsdoc, lvalue_indentation)
|
||||
|
||||
return _InsertString(script, jsdoc, start_index)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
stdin_script = sys.stdin.read()
|
||||
result = InsertJsDoc(stdin_script)
|
||||
|
||||
if result:
|
||||
sys.stdout.write(result)
|
||||
else:
|
||||
sys.stdout.write(stdin_script)
|
||||
@@ -0,0 +1,167 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required `by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
"""Unit test for generate_jsdoc."""
|
||||
|
||||
__author__ = 'nnaze@google.com (Nathan Naze)'
|
||||
|
||||
|
||||
import re
|
||||
import unittest
|
||||
|
||||
import generate_jsdoc
|
||||
|
||||
|
||||
class InsertJsDocTestCase(unittest.TestCase):
|
||||
"""Unit test for source. Tests the parser on a known source input."""
|
||||
|
||||
def testMatchFirstFunction(self):
|
||||
match = generate_jsdoc._MatchFirstFunction(_TEST_SOURCE)
|
||||
self.assertNotEqual(None, match)
|
||||
self.assertEqual('aaa, bbb, ccc', match.group('arguments'))
|
||||
|
||||
match = generate_jsdoc._MatchFirstFunction(_INDENTED_SOURCE)
|
||||
self.assertNotEqual(None, match)
|
||||
self.assertEqual('', match.group('arguments'))
|
||||
|
||||
match = generate_jsdoc._MatchFirstFunction(_ODD_NEWLINES_SOURCE)
|
||||
self.assertEquals('goog.\nfoo.\nbar\n.baz.\nqux',
|
||||
match.group('identifier'))
|
||||
|
||||
def testParseArgString(self):
|
||||
self.assertEquals(
|
||||
['foo', 'bar', 'baz'],
|
||||
list(generate_jsdoc._ParseArgString('foo, bar, baz')))
|
||||
|
||||
def testExtractFunctionBody(self):
|
||||
self.assertEquals(
|
||||
'\n // Function comments.\n return;\n',
|
||||
generate_jsdoc._ExtractFunctionBody(_TEST_SOURCE))
|
||||
|
||||
self.assertEquals(
|
||||
'\n var bar = 3;\n return true;\n',
|
||||
generate_jsdoc._ExtractFunctionBody(_INDENTED_SOURCE, 2))
|
||||
|
||||
def testContainsValueReturn(self):
|
||||
self.assertTrue(generate_jsdoc._ContainsReturnValue(_INDENTED_SOURCE))
|
||||
self.assertFalse(generate_jsdoc._ContainsReturnValue(_TEST_SOURCE))
|
||||
|
||||
def testInsertString(self):
|
||||
self.assertEquals(
|
||||
'abc123def',
|
||||
generate_jsdoc._InsertString('abcdef', '123', 3))
|
||||
|
||||
def testInsertJsDoc(self):
|
||||
self.assertEquals(
|
||||
_EXPECTED_INDENTED_SOURCE,
|
||||
generate_jsdoc.InsertJsDoc(_INDENTED_SOURCE))
|
||||
|
||||
self.assertEquals(
|
||||
_EXPECTED_TEST_SOURCE,
|
||||
generate_jsdoc.InsertJsDoc(_TEST_SOURCE))
|
||||
|
||||
self.assertEquals(
|
||||
_EXPECTED_ODD_NEWLINES_SOURCE,
|
||||
generate_jsdoc.InsertJsDoc(_ODD_NEWLINES_SOURCE))
|
||||
|
||||
|
||||
_INDENTED_SOURCE = """\
|
||||
boo.foo.woo = function() {
|
||||
var bar = 3;
|
||||
return true;
|
||||
};
|
||||
"""
|
||||
|
||||
_EXPECTED_INDENTED_SOURCE = """\
|
||||
/**
|
||||
* @return
|
||||
*/
|
||||
boo.foo.woo = function() {
|
||||
var bar = 3;
|
||||
return true;
|
||||
};
|
||||
"""
|
||||
|
||||
|
||||
_TEST_SOURCE = """\
|
||||
|
||||
// Random comment.
|
||||
|
||||
goog.foo.bar = function (aaa, bbb, ccc) {
|
||||
// Function comments.
|
||||
return;
|
||||
};
|
||||
"""
|
||||
|
||||
_EXPECTED_TEST_SOURCE = """\
|
||||
|
||||
// Random comment.
|
||||
|
||||
/**
|
||||
* @param {} aaa
|
||||
* @param {} bbb
|
||||
* @param {} ccc
|
||||
*/
|
||||
goog.foo.bar = function (aaa, bbb, ccc) {
|
||||
// Function comments.
|
||||
return;
|
||||
};
|
||||
"""
|
||||
|
||||
_ODD_NEWLINES_SOURCE = """\
|
||||
goog.
|
||||
foo.
|
||||
bar
|
||||
.baz.
|
||||
qux
|
||||
=
|
||||
|
||||
function
|
||||
|
||||
(aaa,
|
||||
|
||||
bbb, ccc) {
|
||||
// Function comments.
|
||||
return;
|
||||
};
|
||||
"""
|
||||
|
||||
_EXPECTED_ODD_NEWLINES_SOURCE = """\
|
||||
/**
|
||||
* @param {} aaa
|
||||
* @param {} bbb
|
||||
* @param {} ccc
|
||||
*/
|
||||
goog.
|
||||
foo.
|
||||
bar
|
||||
.baz.
|
||||
qux
|
||||
=
|
||||
|
||||
function
|
||||
|
||||
(aaa,
|
||||
|
||||
bbb, ccc) {
|
||||
// Function comments.
|
||||
return;
|
||||
};
|
||||
"""
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2013 The Closure Library Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# Wraps the unit tests not using the Google framework so they may be run
|
||||
# on the continuous build.
|
||||
#
|
||||
# Author: nnaze@google.com (Nathan Naze)
|
||||
#
|
||||
# Wraps the unit tests not using the Google framework so they may be run
|
||||
# run on the continuous build.
|
||||
|
||||
set -e
|
||||
|
||||
source googletest.sh || exit 1
|
||||
|
||||
CLOSURE_SRCDIR=$TEST_SRCDIR/google3/javascript/closure/labs/bin/code/
|
||||
|
||||
emacs --script $CLOSURE_SRCDIR/closure_test.el
|
||||
@@ -0,0 +1,28 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright 2013 The Closure Library Authors
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
# Wraps the unit tests not using the Google framework so they may be run
|
||||
# on the continuous build.
|
||||
|
||||
set -e
|
||||
|
||||
source googletest.sh || exit 1
|
||||
|
||||
CLOSURE_SRCDIR=$TEST_SRCDIR/google3/javascript/closure/labs/bin/code/
|
||||
|
||||
PYTHONPATH=$CLOSURE_SRCDIR
|
||||
|
||||
$CLOSURE_SRCDIR/generate_jsdoc_test.py
|
||||
25
vectortile/closure-library/closure/bin/logos/logo.svg
Normal file
25
vectortile/closure-library/closure/bin/logos/logo.svg
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!--
|
||||
Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<svg xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 9 9">
|
||||
<title>Closure Logo</title>
|
||||
<path d="M2,2 h2 a2,2 0 1 0 -2,2 z" fill="#0066CF" />
|
||||
<path d="M7,2 h-2 a2,2 0 1 1 2,2 z" fill="#FD0100" />
|
||||
<path d="M2,7 h2 a2,2 0 1 1 -2,-2 z" fill="#FEC502" />
|
||||
<path d="M7,7 h-2 a2,2 0 1 0 2,-2 z" fill="#009338" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
|
||||
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
|
||||
<!--
|
||||
Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
-->
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
viewBox="0 0 200 250">
|
||||
<image x="0" y="0" width="200" height="200" xlink:href="logo.svg" />
|
||||
<text text-anchor="middle" x="100" y="245" font-family="Helvetica"
|
||||
font-size="53" font-weight="bold">Closure</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.0 KiB |
221
vectortile/closure-library/closure/bin/scopify.py
Normal file
221
vectortile/closure-library/closure/bin/scopify.py
Normal file
@@ -0,0 +1,221 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# Copyright 2010 The Closure Library Authors. All Rights Reserved.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
|
||||
"""Automatically converts codebases over to goog.scope.
|
||||
|
||||
Usage:
|
||||
cd path/to/my/dir;
|
||||
../../../../javascript/closure/bin/scopify.py
|
||||
|
||||
Scans every file in this directory, recursively. Looks for existing
|
||||
goog.scope calls, and goog.require'd symbols. If it makes sense to
|
||||
generate a goog.scope call for the file, then we will do so, and
|
||||
try to auto-generate some aliases based on the goog.require'd symbols.
|
||||
|
||||
Known Issues:
|
||||
|
||||
When a file is goog.scope'd, the file contents will be indented +2.
|
||||
This may put some lines over 80 chars. These will need to be fixed manually.
|
||||
|
||||
We will only try to create aliases for capitalized names. We do not check
|
||||
to see if those names will conflict with any existing locals.
|
||||
|
||||
This creates merge conflicts for every line of every outstanding change.
|
||||
If you intend to run this on your codebase, make sure your team members
|
||||
know. Better yet, send them this script so that they can scopify their
|
||||
outstanding changes and "accept theirs".
|
||||
|
||||
When an alias is "captured", it can no longer be stubbed out for testing.
|
||||
Run your tests.
|
||||
|
||||
"""
|
||||
|
||||
__author__ = 'nicksantos@google.com (Nick Santos)'
|
||||
|
||||
import os.path
|
||||
import re
|
||||
import sys
|
||||
|
||||
REQUIRES_RE = re.compile(r"goog.require\('([^']*)'\)")
|
||||
|
||||
# Edit this manually if you want something to "always" be aliased.
|
||||
# TODO(nicksantos): Add a flag for this.
|
||||
DEFAULT_ALIASES = {}
|
||||
|
||||
def Transform(lines):
|
||||
"""Converts the contents of a file into javascript that uses goog.scope.
|
||||
|
||||
Arguments:
|
||||
lines: A list of strings, corresponding to each line of the file.
|
||||
Returns:
|
||||
A new list of strings, or None if the file was not modified.
|
||||
"""
|
||||
requires = []
|
||||
|
||||
# Do an initial scan to be sure that this file can be processed.
|
||||
for line in lines:
|
||||
# Skip this file if it has already been scopified.
|
||||
if line.find('goog.scope') != -1:
|
||||
return None
|
||||
|
||||
# If there are any global vars or functions, then we also have
|
||||
# to skip the whole file. We might be able to deal with this
|
||||
# more elegantly.
|
||||
if line.find('var ') == 0 or line.find('function ') == 0:
|
||||
return None
|
||||
|
||||
for match in REQUIRES_RE.finditer(line):
|
||||
requires.append(match.group(1))
|
||||
|
||||
if len(requires) == 0:
|
||||
return None
|
||||
|
||||
# Backwards-sort the requires, so that when one is a substring of another,
|
||||
# we match the longer one first.
|
||||
for val in DEFAULT_ALIASES.values():
|
||||
if requires.count(val) == 0:
|
||||
requires.append(val)
|
||||
|
||||
requires.sort()
|
||||
requires.reverse()
|
||||
|
||||
# Generate a map of requires to their aliases
|
||||
aliases_to_globals = DEFAULT_ALIASES.copy()
|
||||
for req in requires:
|
||||
index = req.rfind('.')
|
||||
if index == -1:
|
||||
alias = req
|
||||
else:
|
||||
alias = req[(index + 1):]
|
||||
|
||||
# Don't scopify lowercase namespaces, because they may conflict with
|
||||
# local variables.
|
||||
if alias[0].isupper():
|
||||
aliases_to_globals[alias] = req
|
||||
|
||||
aliases_to_matchers = {}
|
||||
globals_to_aliases = {}
|
||||
for alias, symbol in aliases_to_globals.items():
|
||||
globals_to_aliases[symbol] = alias
|
||||
aliases_to_matchers[alias] = re.compile('\\b%s\\b' % symbol)
|
||||
|
||||
# Insert a goog.scope that aliases all required symbols.
|
||||
result = []
|
||||
|
||||
START = 0
|
||||
SEEN_REQUIRES = 1
|
||||
IN_SCOPE = 2
|
||||
|
||||
mode = START
|
||||
aliases_used = set()
|
||||
insertion_index = None
|
||||
num_blank_lines = 0
|
||||
for line in lines:
|
||||
if mode == START:
|
||||
result.append(line)
|
||||
|
||||
if re.search(REQUIRES_RE, line):
|
||||
mode = SEEN_REQUIRES
|
||||
|
||||
elif mode == SEEN_REQUIRES:
|
||||
if (line and
|
||||
not re.search(REQUIRES_RE, line) and
|
||||
not line.isspace()):
|
||||
# There should be two blank lines before goog.scope
|
||||
result += ['\n'] * 2
|
||||
result.append('goog.scope(function() {\n')
|
||||
insertion_index = len(result)
|
||||
result += ['\n'] * num_blank_lines
|
||||
mode = IN_SCOPE
|
||||
elif line.isspace():
|
||||
# Keep track of the number of blank lines before each block of code so
|
||||
# that we can move them after the goog.scope line if necessary.
|
||||
num_blank_lines += 1
|
||||
else:
|
||||
# Print the blank lines we saw before this code block
|
||||
result += ['\n'] * num_blank_lines
|
||||
num_blank_lines = 0
|
||||
result.append(line)
|
||||
|
||||
if mode == IN_SCOPE:
|
||||
for symbol in requires:
|
||||
if not symbol in globals_to_aliases:
|
||||
continue
|
||||
|
||||
alias = globals_to_aliases[symbol]
|
||||
matcher = aliases_to_matchers[alias]
|
||||
for match in matcher.finditer(line):
|
||||
# Check to make sure we're not in a string.
|
||||
# We do this by being as conservative as possible:
|
||||
# if there are any quote or double quote characters
|
||||
# before the symbol on this line, then bail out.
|
||||
before_symbol = line[:match.start(0)]
|
||||
if before_symbol.count('"') > 0 or before_symbol.count("'") > 0:
|
||||
continue
|
||||
|
||||
line = line.replace(match.group(0), alias)
|
||||
aliases_used.add(alias)
|
||||
|
||||
if line.isspace():
|
||||
# Truncate all-whitespace lines
|
||||
result.append('\n')
|
||||
else:
|
||||
result.append(line)
|
||||
|
||||
if len(aliases_used):
|
||||
aliases_used = [alias for alias in aliases_used]
|
||||
aliases_used.sort()
|
||||
aliases_used.reverse()
|
||||
for alias in aliases_used:
|
||||
symbol = aliases_to_globals[alias]
|
||||
result.insert(insertion_index,
|
||||
'var %s = %s;\n' % (alias, symbol))
|
||||
result.append('}); // goog.scope\n')
|
||||
return result
|
||||
else:
|
||||
return None
|
||||
|
||||
def TransformFileAt(path):
|
||||
"""Converts a file into javascript that uses goog.scope.
|
||||
|
||||
Arguments:
|
||||
path: A path to a file.
|
||||
"""
|
||||
f = open(path)
|
||||
lines = Transform(f.readlines())
|
||||
if lines:
|
||||
f = open(path, 'w')
|
||||
for l in lines:
|
||||
f.write(l)
|
||||
f.close()
|
||||
|
||||
if __name__ == '__main__':
|
||||
args = sys.argv[1:]
|
||||
if not len(args):
|
||||
args = '.'
|
||||
|
||||
for file_name in args:
|
||||
if os.path.isdir(file_name):
|
||||
for root, dirs, files in os.walk(file_name):
|
||||
for name in files:
|
||||
if name.endswith('.js') and \
|
||||
not os.path.islink(os.path.join(root, name)):
|
||||
TransformFileAt(os.path.join(root, name))
|
||||
else:
|
||||
if file_name.endswith('.js') and \
|
||||
not os.path.islink(file_name):
|
||||
TransformFileAt(file_name)
|
||||
82
vectortile/closure-library/closure/css/inlay/g-base.css
Normal file
82
vectortile/closure-library/closure/css/inlay/g-base.css
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by the Apache License, Version 2.0.
|
||||
* See the COPYING file for details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* CSS Inlay
|
||||
* This is the minimum CSS required to use the markup/classname patterns.
|
||||
* @author elsigh@google.com (Lindsey Simon)
|
||||
* @author ddiaz@google.com (Dustin Diaz)
|
||||
*/
|
||||
|
||||
/**
|
||||
* Document container designed for fluid width scaling.
|
||||
* Alternative g-doc- fixed-width classes are in gui-fixed.css.
|
||||
*/
|
||||
.g-doc {
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
/**
|
||||
* g-section fundamentally has to clear floats. There are many ways to do this.
|
||||
* This technique is nice because it doesn't rely on overflow: hidden, which
|
||||
* has the potential to hide your content in situations where a fixed size
|
||||
* node takes up too much space (like a big table, or a text input or image.
|
||||
* Works in Webkit, IE8, and FF3.
|
||||
*/
|
||||
.g-section {
|
||||
width: 100%;
|
||||
vertical-align: top;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/**
|
||||
* IE7-only hack. Nicely IE7 will clear floats with just block display
|
||||
* and hasLayout.
|
||||
*/
|
||||
*:first-child+html .g-section {
|
||||
display: block;
|
||||
}
|
||||
|
||||
/**
|
||||
* IE6 cannot hang with overflow: visible. If we use the IE7 display block
|
||||
* trick in IE6 we get severe float drop in nested grids.
|
||||
*/
|
||||
* html .g-section {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
/* FF2 can't actually hang with overflow: visible. */
|
||||
@-moz-document url-prefix() {
|
||||
.g-section {
|
||||
overflow: hidden;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* FF3 now needs to be reset after the previous block which affects it as well.
|
||||
* We target the tt element in this hack because no one uses it.
|
||||
*/
|
||||
@-moz-document url-prefix() {
|
||||
.g-section,tt:default {
|
||||
overflow: visible;
|
||||
}
|
||||
}
|
||||
|
||||
/* Forces "hasLayout" fixing a gamut of bugs in <= IE7. */
|
||||
.g-section,
|
||||
.g-unit {
|
||||
zoom: 1;
|
||||
}
|
||||
|
||||
/* Used for splitting a template's units text-alignment to the outer edges. */
|
||||
.g-split .g-unit {
|
||||
text-align: right;
|
||||
}
|
||||
.g-split .g-first {
|
||||
text-align: left;
|
||||
}
|
||||
173
vectortile/closure-library/closure/css/inlay/g-fixed.css
Normal file
173
vectortile/closure-library/closure/css/inlay/g-fixed.css
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by the Apache License, Version 2.0.
|
||||
* See the COPYING file for details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* CSS Inlay
|
||||
* Fixed templates
|
||||
* @author ddiaz@google.com (Dustin Diaz)
|
||||
* @author elsigh@google.com (Lindsey Simon)
|
||||
* @fileoverview
|
||||
* The nature of these templates is to have one unit be a fixed width
|
||||
* and the supplementary unit to take up the rest of the width
|
||||
* of its parents' container.
|
||||
*
|
||||
* Sample Usage:
|
||||
<div class="g-section g-tpl-180">
|
||||
<div class="g-unit g-first">
|
||||
<p>
|
||||
Lorem Ipsum...
|
||||
</p>
|
||||
</div>
|
||||
<div class="g-unit">
|
||||
<p>
|
||||
Lorem Ipsum...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
*/
|
||||
|
||||
/* Document container designed for 1024x768 */
|
||||
/* TODO(ux-webdev): convert this to a straight px value - em assumes reset. */
|
||||
.g-doc-1024 {
|
||||
width: 73.074em;
|
||||
min-width: 950px; /* min-width doesn't work in IE6 */
|
||||
margin: 0 auto;
|
||||
text-align: left;
|
||||
}
|
||||
/* IE 6 */
|
||||
* html .g-doc-1024 {
|
||||
width: 71.313em;
|
||||
}
|
||||
/* IE 7 */
|
||||
*+html .g-doc-1024 {
|
||||
width: 71.313em;
|
||||
}
|
||||
|
||||
/* Document container designed for 800x600 */
|
||||
/* TODO(ux-webdev): convert this to a straight px value - em assumes reset. */
|
||||
.g-doc-800 {
|
||||
width: 57.69em;
|
||||
min-width: 750px; /* min-width doesn't work in IE6 */
|
||||
margin: 0 auto;
|
||||
text-align: left;
|
||||
}
|
||||
/* IE 6 */
|
||||
* html .g-doc-800 {
|
||||
width: 56.3em;
|
||||
}
|
||||
/* IE 7 */
|
||||
*+html .g-doc-800 {
|
||||
width: 56.3em;
|
||||
}
|
||||
|
||||
/* 160px */
|
||||
.g-tpl-160 .g-unit,
|
||||
.g-unit .g-tpl-160 .g-unit,
|
||||
.g-unit .g-unit .g-tpl-160 .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-160 .g-unit {
|
||||
margin: 0 0 0 160px;
|
||||
width: auto;
|
||||
float: none;
|
||||
}
|
||||
.g-unit .g-unit .g-unit .g-tpl-160 .g-first,
|
||||
.g-unit .g-unit .g-tpl-160 .g-first,
|
||||
.g-unit .g-tpl-160 .g-first,
|
||||
.g-tpl-160 .g-first {
|
||||
margin: 0;
|
||||
width: 160px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
/* 160px alt */
|
||||
.g-tpl-160-alt .g-unit,
|
||||
.g-unit .g-tpl-160-alt .g-unit,
|
||||
.g-unit .g-unit .g-tpl-160-alt .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-160-alt .g-unit {
|
||||
margin: 0 160px 0 0;
|
||||
width: auto;
|
||||
float: none;
|
||||
}
|
||||
.g-unit .g-unit .g-unit .g-tpl-160-alt .g-first,
|
||||
.g-unit .g-unit .g-tpl-160-alt .g-first,
|
||||
.g-unit .g-tpl-160-alt .g-first,
|
||||
.g-tpl-160-alt .g-first {
|
||||
margin: 0;
|
||||
width: 160px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* 180px */
|
||||
.g-tpl-180 .g-unit,
|
||||
.g-unit .g-tpl-180 .g-unit,
|
||||
.g-unit .g-unit .g-tpl-180 .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-180 .g-unit {
|
||||
margin: 0 0 0 180px;
|
||||
width: auto;
|
||||
float: none;
|
||||
}
|
||||
.g-unit .g-unit .g-unit .g-tpl-180 .g-first,
|
||||
.g-unit .g-unit .g-tpl-180 .g-first,
|
||||
.g-unit .g-tpl-180 .g-first,
|
||||
.g-tpl-180 .g-first {
|
||||
margin: 0;
|
||||
width: 180px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
/* 180px alt */
|
||||
.g-tpl-180-alt .g-unit,
|
||||
.g-unit .g-tpl-180-alt .g-unit,
|
||||
.g-unit .g-unit .g-tpl-180-alt .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-180-alt .g-unit {
|
||||
margin: 0 180px 0 0;
|
||||
width: auto;
|
||||
float: none;
|
||||
}
|
||||
.g-unit .g-unit .g-unit .g-tpl-180-alt .g-first,
|
||||
.g-unit .g-unit .g-tpl-180-alt .g-first,
|
||||
.g-unit .g-tpl-180-alt .g-first,
|
||||
.g-tpl-180-alt .g-first {
|
||||
margin: 0;
|
||||
width: 180px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
/* 300px */
|
||||
.g-tpl-300 .g-unit,
|
||||
.g-unit .g-tpl-300 .g-unit,
|
||||
.g-unit .g-unit .g-tpl-300 .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-300 .g-unit {
|
||||
margin: 0 0 0 300px;
|
||||
width: auto;
|
||||
float: none;
|
||||
}
|
||||
.g-unit .g-unit .g-unit .g-tpl-300 .g-first,
|
||||
.g-unit .g-unit .g-tpl-300 .g-first,
|
||||
.g-unit .g-tpl-300 .g-first,
|
||||
.g-tpl-300 .g-first {
|
||||
margin: 0;
|
||||
width: 300px;
|
||||
float: left;
|
||||
}
|
||||
|
||||
/* 300px alt */
|
||||
.g-tpl-300-alt .g-unit,
|
||||
.g-unit .g-tpl-300-alt .g-unit,
|
||||
.g-unit .g-unit .g-tpl-300-alt .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-300-alt .g-unit {
|
||||
margin: 0 300px 0 0;
|
||||
width: auto;
|
||||
float: none;
|
||||
}
|
||||
.g-unit .g-unit .g-unit .g-tpl-300-alt .g-first,
|
||||
.g-unit .g-unit .g-tpl-300-alt .g-first,
|
||||
.g-unit .g-tpl-300-alt .g-first,
|
||||
.g-tpl-300-alt .g-first {
|
||||
margin: 0;
|
||||
width: 300px;
|
||||
float: right;
|
||||
}
|
||||
253
vectortile/closure-library/closure/css/inlay/g-ratio.css
Normal file
253
vectortile/closure-library/closure/css/inlay/g-ratio.css
Normal file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
*
|
||||
* Use of this source code is governed by the Apache License, Version 2.0.
|
||||
* See the COPYING file for details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* CSS Inlay
|
||||
* Percentage based templates
|
||||
* @author ddiaz@google.com (Dustin Diaz)
|
||||
* @author elsigh@google.com (Lindsey Simon)
|
||||
* @fileoverview
|
||||
* The first ten templates are described using the following convention:
|
||||
* tpl-LEFT%-RIGHT% and tpl-LEFT%-RIGHT%-alt, where alt switches render order.
|
||||
*
|
||||
* The rationale for the percentage values are pretty fascinating.
|
||||
* Three nine's are needed for a miminal affordance in the gap between units
|
||||
* for Opera, while two for IE 5.5 and down.
|
||||
* Straight percentages seem to work fine otherwise, but the values here test
|
||||
* well cross-browser.
|
||||
*
|
||||
* Sample Usage:
|
||||
<div class="g-section g-tpl-50-50">
|
||||
<div class="g-unit g-first">
|
||||
<p>
|
||||
Lorem Ipsum...
|
||||
</p>
|
||||
</div>
|
||||
<div class="g-unit">
|
||||
<p>
|
||||
Lorem Ipsum...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
*/
|
||||
|
||||
/* 25/75 */
|
||||
.g-tpl-25-75 .g-unit,
|
||||
.g-unit .g-tpl-25-75 .g-unit,
|
||||
.g-unit .g-unit .g-tpl-25-75 .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-25-75 .g-unit {
|
||||
width: 74.999%;
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
.g-unit .g-unit .g-unit .g-tpl-25-75 .g-first,
|
||||
.g-unit .g-unit .g-tpl-25-75 .g-first,
|
||||
.g-unit .g-tpl-25-75 .g-first,
|
||||
.g-tpl-25-75 .g-first {
|
||||
width: 24.999%;
|
||||
float: left;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 25/75-alt */
|
||||
.g-tpl-25-75-alt .g-unit,
|
||||
.g-unit .g-tpl-25-75-alt .g-unit,
|
||||
.g-unit .g-unit .g-tpl-25-75-alt .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-25-75-alt .g-unit {
|
||||
width: 24.999%;
|
||||
float: left;
|
||||
margin: 0;
|
||||
}
|
||||
.g-unit .g-unit .g-unit .g-tpl-25-75-alt .g-first,
|
||||
.g-unit .g-unit .g-tpl-25-75-alt .g-first,
|
||||
.g-unit .g-tpl-25-75-alt .g-first,
|
||||
.g-tpl-25-75-alt .g-first {
|
||||
width: 74.999%;
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 75/25 */
|
||||
.g-tpl-75-25 .g-unit,
|
||||
.g-unit .g-tpl-75-25 .g-unit,
|
||||
.g-unit .g-unit .g-tpl-75-25 .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-75-25 .g-unit {
|
||||
width: 24.999%;
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
.g-unit .g-unit .g-unit .g-tpl-75-25 .g-first,
|
||||
.g-unit .g-unit .g-tpl-75-25 .g-first,
|
||||
.g-unit .g-tpl-75-25 .g-first,
|
||||
.g-tpl-75-25 .g-first {
|
||||
width: 74.999%;
|
||||
float: left;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 75/25-alt */
|
||||
.g-tpl-75-25-alt .g-unit,
|
||||
.g-unit .g-tpl-75-25-alt .g-unit,
|
||||
.g-unit .g-unit .g-tpl-75-25-alt .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-75-25-alt .g-unit {
|
||||
width: 74.999%;
|
||||
float: left;
|
||||
margin: 0;
|
||||
}
|
||||
.g-unit .g-unit .g-unit .g-tpl-75-25-alt .g-first,
|
||||
.g-unit .g-unit .g-tpl-75-25-alt .g-first,
|
||||
.g-unit .g-tpl-75-25-alt .g-first,
|
||||
.g-tpl-75-25-alt .g-first {
|
||||
width: 24.999%;
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 33/67 */
|
||||
.g-tpl-33-67 .g-unit,
|
||||
.g-unit .g-tpl-33-67 .g-unit,
|
||||
.g-unit .g-unit .g-tpl-33-67 .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-33-67 .g-unit {
|
||||
width: 66.999%;
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
.g-unit .g-unit .g-unit .g-tpl-33-67 .g-first,
|
||||
.g-unit .g-unit .g-tpl-33-67 .g-first,
|
||||
.g-unit .g-tpl-33-67 .g-first,
|
||||
.g-tpl-33-67 .g-first {
|
||||
width: 32.999%;
|
||||
float: left;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 33/67-alt */
|
||||
.g-tpl-33-67-alt .g-unit,
|
||||
.g-unit .g-tpl-33-67-alt .g-unit,
|
||||
.g-unit .g-unit .g-tpl-33-67-alt .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-33-67-alt .g-unit {
|
||||
width: 32.999%;
|
||||
float: left;
|
||||
margin: 0;
|
||||
}
|
||||
.g-unit .g-unit .g-unit .g-tpl-33-67-alt .g-first,
|
||||
.g-unit .g-unit .g-tpl-33-67-alt .g-first,
|
||||
.g-unit .g-tpl-33-67-alt .g-first,
|
||||
.g-tpl-33-67-alt .g-first {
|
||||
width: 66.999%;
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
/* 67/33 */
|
||||
.g-tpl-67-33 .g-unit,
|
||||
.g-unit .g-tpl-67-33 .g-unit,
|
||||
.g-unit .g-unit .g-tpl-67-33 .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-67-33 .g-unit {
|
||||
width: 32.999%;
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
.g-unit .g-unit .g-unit .g-tpl-67-33 .g-first,
|
||||
.g-unit .g-unit .g-tpl-67-33 .g-first,
|
||||
.g-unit .g-tpl-67-33 .g-first,
|
||||
.g-tpl-67-33 .g-first {
|
||||
width: 66.999%;
|
||||
float: left;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 67/33-alt */
|
||||
.g-tpl-67-33-alt .g-unit,
|
||||
.g-unit .g-tpl-67-33-alt .g-unit,
|
||||
.g-unit .g-unit .g-tpl-67-33-alt .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-67-33-alt .g-unit {
|
||||
width: 66.999%;
|
||||
float: left;
|
||||
margin: 0;
|
||||
}
|
||||
.g-unit .g-unit .g-unit .g-tpl-67-33-alt .g-first,
|
||||
.g-unit .g-unit .g-tpl-67-33-alt .g-first,
|
||||
.g-unit .g-tpl-67-33-alt .g-first,
|
||||
.g-tpl-67-33-alt .g-first {
|
||||
width: 32.999%;
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 50/50 */
|
||||
.g-tpl-50-50 .g-unit,
|
||||
.g-unit .g-tpl-50-50 .g-unit,
|
||||
.g-unit .g-unit .g-tpl-50-50 .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-50-50 .g-unit {
|
||||
width: 49.999%;
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
.g-unit .g-unit .g-unit .g-tpl-50-50 .g-first,
|
||||
.g-unit .g-unit .g-tpl-50-50 .g-first,
|
||||
.g-unit .g-tpl-50-50 .g-first,
|
||||
.g-tpl-50-50 .g-first {
|
||||
width: 49.999%;
|
||||
float: left;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* 50/50-alt */
|
||||
.g-tpl-50-50-alt .g-unit,
|
||||
.g-unit .g-tpl-50-50-alt .g-unit,
|
||||
.g-unit .g-unit .g-tpl-50-50-alt .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-50-50-alt .g-unit {
|
||||
width: 49.999%;
|
||||
float: left;
|
||||
margin: 0;
|
||||
}
|
||||
.g-unit .g-unit .g-unit .g-tpl-50-50-alt .g-first,
|
||||
.g-unit .g-unit .g-tpl-50-50-alt .g-first,
|
||||
.g-unit .g-tpl-50-50-alt .g-first,
|
||||
.g-tpl-50-50-alt .g-first {
|
||||
width: 49.999%;
|
||||
float: right;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Nest templates contain floating g-units.
|
||||
* For these, width needs to be reset from the 100% for inline-block
|
||||
* to auto. This fixes an issue with horizontal scrollbars.
|
||||
*/
|
||||
.g-tpl-nest {
|
||||
width: auto;
|
||||
}
|
||||
/**
|
||||
* Making any g-sections inside of g-tpl-nests display inline instead
|
||||
* of display block solves an issue where inner sections add up incrementally
|
||||
* their widths to set the width of the outer g-unit. This causes all kinds of
|
||||
* problems with float-drops and display:inline fixes this.
|
||||
*/
|
||||
.g-tpl-nest .g-section {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
/* g-tpl-nest for multi unit nesting (float left), say for a menu. */
|
||||
.g-tpl-nest .g-unit,
|
||||
.g-unit .g-tpl-nest .g-unit,
|
||||
.g-unit .g-unit .g-tpl-nest .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-nest .g-unit {
|
||||
float: left;
|
||||
width: auto;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
/* g-tpl-nest-alt for multi unit nesting (float right), say for a menu. */
|
||||
.g-tpl-nest-alt .g-unit,
|
||||
.g-unit .g-tpl-nest-alt .g-unit,
|
||||
.g-unit .g-unit .g-tpl-nest-alt .g-unit,
|
||||
.g-unit .g-unit .g-unit .g-tpl-nest-alt .g-unit {
|
||||
float: right;
|
||||
width: auto;
|
||||
margin: 0;
|
||||
}
|
||||
123
vectortile/closure-library/closure/goog/a11y/aria/announcer.js
Normal file
123
vectortile/closure-library/closure/goog/a11y/aria/announcer.js
Normal file
@@ -0,0 +1,123 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Announcer that allows messages to be spoken by assistive
|
||||
* technologies.
|
||||
*/
|
||||
|
||||
goog.provide('goog.a11y.aria.Announcer');
|
||||
|
||||
goog.require('goog.Disposable');
|
||||
goog.require('goog.Timer');
|
||||
goog.require('goog.a11y.aria');
|
||||
goog.require('goog.a11y.aria.LivePriority');
|
||||
goog.require('goog.a11y.aria.State');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.dom.TagName');
|
||||
goog.require('goog.object');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Class that allows messages to be spoken by assistive technologies that the
|
||||
* user may have active.
|
||||
*
|
||||
* @param {goog.dom.DomHelper=} opt_domHelper DOM helper.
|
||||
* @constructor
|
||||
* @extends {goog.Disposable}
|
||||
* @final
|
||||
*/
|
||||
goog.a11y.aria.Announcer = function(opt_domHelper) {
|
||||
goog.a11y.aria.Announcer.base(this, 'constructor');
|
||||
|
||||
/**
|
||||
* @type {goog.dom.DomHelper}
|
||||
* @private
|
||||
*/
|
||||
this.domHelper_ = opt_domHelper || goog.dom.getDomHelper();
|
||||
|
||||
/**
|
||||
* Map of priority to live region elements to use for communicating updates.
|
||||
* Elements are created on demand.
|
||||
* @type {Object<goog.a11y.aria.LivePriority, !Element>}
|
||||
* @private
|
||||
*/
|
||||
this.liveRegions_ = {};
|
||||
};
|
||||
goog.inherits(goog.a11y.aria.Announcer, goog.Disposable);
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.a11y.aria.Announcer.prototype.disposeInternal = function() {
|
||||
goog.object.forEach(
|
||||
this.liveRegions_, this.domHelper_.removeNode, this.domHelper_);
|
||||
this.liveRegions_ = null;
|
||||
this.domHelper_ = null;
|
||||
goog.a11y.aria.Announcer.base(this, 'disposeInternal');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Announce a message to be read by any assistive technologies the user may
|
||||
* have active.
|
||||
* @param {string} message The message to announce to screen readers.
|
||||
* @param {goog.a11y.aria.LivePriority=} opt_priority The priority of the
|
||||
* message. Defaults to POLITE.
|
||||
*/
|
||||
goog.a11y.aria.Announcer.prototype.say = function(message, opt_priority) {
|
||||
var priority = opt_priority || goog.a11y.aria.LivePriority.POLITE;
|
||||
var liveRegion = this.getLiveRegion_(priority);
|
||||
// Resets text content to force a DOM mutation (so that the setTextContent
|
||||
// post-timeout function will be noticed by the screen reader). This is to
|
||||
// avoid the problem of when the same message is "said" twice, which doesn't
|
||||
// trigger a DOM mutation.
|
||||
goog.dom.setTextContent(liveRegion, '');
|
||||
// Uses non-zero timer to make VoiceOver and NVDA work
|
||||
goog.Timer.callOnce(function() {
|
||||
goog.dom.setTextContent(liveRegion, message);
|
||||
}, 1);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns an aria-live region that can be used to communicate announcements.
|
||||
* @param {!goog.a11y.aria.LivePriority} priority The required priority.
|
||||
* @return {!Element} A live region of the requested priority.
|
||||
* @private
|
||||
*/
|
||||
goog.a11y.aria.Announcer.prototype.getLiveRegion_ = function(priority) {
|
||||
var liveRegion = this.liveRegions_[priority];
|
||||
if (liveRegion) {
|
||||
// Make sure the live region is not aria-hidden.
|
||||
goog.a11y.aria.removeState(liveRegion, goog.a11y.aria.State.HIDDEN);
|
||||
return liveRegion;
|
||||
}
|
||||
|
||||
liveRegion = this.domHelper_.createElement(goog.dom.TagName.DIV);
|
||||
// Note that IE has a habit of declaring things that aren't display:none as
|
||||
// invisible to third-party tools like JAWs, so we can't just use height:0.
|
||||
liveRegion.style.position = 'absolute';
|
||||
liveRegion.style.top = '-1000px';
|
||||
liveRegion.style.height = '1px';
|
||||
liveRegion.style.overflow = 'hidden';
|
||||
goog.a11y.aria.setState(liveRegion, goog.a11y.aria.State.LIVE,
|
||||
priority);
|
||||
goog.a11y.aria.setState(liveRegion, goog.a11y.aria.State.ATOMIC,
|
||||
'true');
|
||||
this.domHelper_.getDocument().body.appendChild(liveRegion);
|
||||
this.liveRegions_[priority] = liveRegion;
|
||||
return liveRegion;
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<!--
|
||||
Author: attila@google.com (Attila Bodis)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>
|
||||
Closure Unit Tests - goog.a11y.aria announcer
|
||||
</title>
|
||||
<script src="../../base.js">
|
||||
</script>
|
||||
<script>
|
||||
goog.require('goog.a11y.aria.AnnouncerTest');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="sandbox">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,137 @@
|
||||
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.a11y.aria.AnnouncerTest');
|
||||
goog.setTestOnly('goog.a11y.aria.AnnouncerTest');
|
||||
|
||||
goog.require('goog.a11y.aria');
|
||||
goog.require('goog.a11y.aria.Announcer');
|
||||
goog.require('goog.a11y.aria.LivePriority');
|
||||
goog.require('goog.a11y.aria.State');
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.dom.TagName');
|
||||
goog.require('goog.dom.iframe');
|
||||
goog.require('goog.testing.MockClock');
|
||||
goog.require('goog.testing.jsunit');
|
||||
|
||||
var sandbox;
|
||||
var someDiv;
|
||||
var someSpan;
|
||||
var mockClock;
|
||||
|
||||
function setUp() {
|
||||
sandbox = goog.dom.getElement('sandbox');
|
||||
someDiv = goog.dom.createDom(goog.dom.TagName.DIV, {id: 'someDiv'}, 'DIV');
|
||||
someSpan = goog.dom.createDom(goog.dom.TagName.SPAN,
|
||||
{id: 'someSpan'}, 'SPAN');
|
||||
sandbox.appendChild(someDiv);
|
||||
someDiv.appendChild(someSpan);
|
||||
|
||||
mockClock = new goog.testing.MockClock(true);
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
sandbox.innerHTML = '';
|
||||
someDiv = null;
|
||||
someSpan = null;
|
||||
|
||||
goog.dispose(mockClock);
|
||||
}
|
||||
|
||||
function testAnnouncerAndDispose() {
|
||||
var text = 'test content';
|
||||
var announcer = new goog.a11y.aria.Announcer(goog.dom.getDomHelper());
|
||||
announcer.say(text);
|
||||
checkLiveRegionContains(text, 'polite');
|
||||
goog.dispose(announcer);
|
||||
}
|
||||
|
||||
function testAnnouncerTwice() {
|
||||
var text = 'test content1';
|
||||
var text2 = 'test content2';
|
||||
var announcer = new goog.a11y.aria.Announcer(goog.dom.getDomHelper());
|
||||
announcer.say(text);
|
||||
announcer.say(text2);
|
||||
checkLiveRegionContains(text2, 'polite');
|
||||
goog.dispose(announcer);
|
||||
}
|
||||
|
||||
function testAnnouncerTwiceSameMessage() {
|
||||
var text = 'test content';
|
||||
var announcer = new goog.a11y.aria.Announcer(goog.dom.getDomHelper());
|
||||
announcer.say(text);
|
||||
var firstLiveRegion = getLiveRegion('polite');
|
||||
announcer.say(text, undefined);
|
||||
var secondLiveRegion = getLiveRegion('polite');
|
||||
assertEquals(firstLiveRegion, secondLiveRegion);
|
||||
checkLiveRegionContains(text, 'polite');
|
||||
goog.dispose(announcer);
|
||||
}
|
||||
|
||||
function testAnnouncerAssertive() {
|
||||
var text = 'test content';
|
||||
var announcer = new goog.a11y.aria.Announcer(goog.dom.getDomHelper());
|
||||
announcer.say(text, goog.a11y.aria.LivePriority.ASSERTIVE);
|
||||
checkLiveRegionContains(text, 'assertive');
|
||||
goog.dispose(announcer);
|
||||
}
|
||||
|
||||
function testAnnouncerInIframe() {
|
||||
var text = 'test content';
|
||||
var frame = goog.dom.iframe.createWithContent(sandbox);
|
||||
var helper = goog.dom.getDomHelper(
|
||||
goog.dom.getFrameContentDocument(frame).body);
|
||||
var announcer = new goog.a11y.aria.Announcer(helper);
|
||||
announcer.say(text, 'polite', helper);
|
||||
checkLiveRegionContains(text, 'polite', helper);
|
||||
goog.dispose(announcer);
|
||||
}
|
||||
|
||||
function testAnnouncerWithAriaHidden() {
|
||||
var text = 'test content1';
|
||||
var text2 = 'test content2';
|
||||
var announcer = new goog.a11y.aria.Announcer(goog.dom.getDomHelper());
|
||||
announcer.say(text);
|
||||
// Set aria-hidden attribute on the live region (simulates a modal dialog
|
||||
// being opened).
|
||||
var liveRegion = getLiveRegion('polite');
|
||||
goog.a11y.aria.setState(liveRegion, goog.a11y.aria.State.HIDDEN, true);
|
||||
|
||||
// Announce a new message and make sure that the aria-hidden was removed.
|
||||
announcer.say(text2);
|
||||
checkLiveRegionContains(text2, 'polite');
|
||||
assertEquals('',
|
||||
goog.a11y.aria.getState(liveRegion, goog.a11y.aria.State.HIDDEN));
|
||||
goog.dispose(announcer);
|
||||
}
|
||||
|
||||
function getLiveRegion(priority, opt_domHelper) {
|
||||
var dom = opt_domHelper || goog.dom.getDomHelper();
|
||||
var divs = dom.getElementsByTagNameAndClass(goog.dom.TagName.DIV, null);
|
||||
var liveRegions = [];
|
||||
goog.array.forEach(divs, function(div) {
|
||||
if (goog.a11y.aria.getState(div, 'live') == priority) {
|
||||
liveRegions.push(div);
|
||||
}
|
||||
});
|
||||
assertEquals(1, liveRegions.length);
|
||||
return liveRegions[0];
|
||||
}
|
||||
|
||||
function checkLiveRegionContains(text, priority, opt_domHelper) {
|
||||
var liveRegion = getLiveRegion(priority, opt_domHelper);
|
||||
mockClock.tick(1);
|
||||
assertEquals(text, goog.dom.getTextContent(liveRegion));
|
||||
}
|
||||
438
vectortile/closure-library/closure/goog/a11y/aria/aria.js
Normal file
438
vectortile/closure-library/closure/goog/a11y/aria/aria.js
Normal file
@@ -0,0 +1,438 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Utilities for adding, removing and setting ARIA roles and
|
||||
* states as defined by W3C ARIA standard: http://www.w3.org/TR/wai-aria/
|
||||
* All modern browsers have some form of ARIA support, so no browser checks are
|
||||
* performed when adding ARIA to components.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.a11y.aria');
|
||||
|
||||
goog.require('goog.a11y.aria.Role');
|
||||
goog.require('goog.a11y.aria.State');
|
||||
goog.require('goog.a11y.aria.datatables');
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.dom.TagName');
|
||||
goog.require('goog.object');
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* ARIA states/properties prefix.
|
||||
* @private
|
||||
*/
|
||||
goog.a11y.aria.ARIA_PREFIX_ = 'aria-';
|
||||
|
||||
|
||||
/**
|
||||
* ARIA role attribute.
|
||||
* @private
|
||||
*/
|
||||
goog.a11y.aria.ROLE_ATTRIBUTE_ = 'role';
|
||||
|
||||
|
||||
/**
|
||||
* A list of tag names for which we don't need to set ARIA role and states
|
||||
* because they have well supported semantics for screen readers or because
|
||||
* they don't contain content to be made accessible.
|
||||
* @private
|
||||
*/
|
||||
goog.a11y.aria.TAGS_WITH_ASSUMED_ROLES_ = [
|
||||
goog.dom.TagName.A,
|
||||
goog.dom.TagName.AREA,
|
||||
goog.dom.TagName.BUTTON,
|
||||
goog.dom.TagName.HEAD,
|
||||
goog.dom.TagName.INPUT,
|
||||
goog.dom.TagName.LINK,
|
||||
goog.dom.TagName.MENU,
|
||||
goog.dom.TagName.META,
|
||||
goog.dom.TagName.OPTGROUP,
|
||||
goog.dom.TagName.OPTION,
|
||||
goog.dom.TagName.PROGRESS,
|
||||
goog.dom.TagName.STYLE,
|
||||
goog.dom.TagName.SELECT,
|
||||
goog.dom.TagName.SOURCE,
|
||||
goog.dom.TagName.TEXTAREA,
|
||||
goog.dom.TagName.TITLE,
|
||||
goog.dom.TagName.TRACK
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* A list of roles which are considered container roles.
|
||||
* Container roles are ARIA roles which use the aria-activedescendant property
|
||||
* to manage their active descendants or children. See
|
||||
* {@link http://www.w3.org/TR/wai-aria/states_and_properties
|
||||
* #aria-activedescendant} for more information.
|
||||
* @private @const
|
||||
*/
|
||||
goog.a11y.aria.CONTAINER_ROLES_ = [
|
||||
goog.a11y.aria.Role.COMBOBOX,
|
||||
goog.a11y.aria.Role.GRID,
|
||||
goog.a11y.aria.Role.GROUP,
|
||||
goog.a11y.aria.Role.LISTBOX,
|
||||
goog.a11y.aria.Role.MENU,
|
||||
goog.a11y.aria.Role.MENUBAR,
|
||||
goog.a11y.aria.Role.RADIOGROUP,
|
||||
goog.a11y.aria.Role.ROW,
|
||||
goog.a11y.aria.Role.ROWGROUP,
|
||||
goog.a11y.aria.Role.TAB_LIST,
|
||||
goog.a11y.aria.Role.TEXTBOX,
|
||||
goog.a11y.aria.Role.TOOLBAR,
|
||||
goog.a11y.aria.Role.TREE,
|
||||
goog.a11y.aria.Role.TREEGRID
|
||||
];
|
||||
|
||||
|
||||
/**
|
||||
* Sets the role of an element. If the roleName is
|
||||
* empty string or null, the role for the element is removed.
|
||||
* We encourage clients to call the goog.a11y.aria.removeRole
|
||||
* method instead of setting null and empty string values.
|
||||
* Special handling for this case is added to ensure
|
||||
* backword compatibility with existing code.
|
||||
*
|
||||
* @param {!Element} element DOM node to set role of.
|
||||
* @param {!goog.a11y.aria.Role|string} roleName role name(s).
|
||||
*/
|
||||
goog.a11y.aria.setRole = function(element, roleName) {
|
||||
if (!roleName) {
|
||||
// Setting the ARIA role to empty string is not allowed
|
||||
// by the ARIA standard.
|
||||
goog.a11y.aria.removeRole(element);
|
||||
} else {
|
||||
if (goog.asserts.ENABLE_ASSERTS) {
|
||||
goog.asserts.assert(goog.object.containsValue(
|
||||
goog.a11y.aria.Role, roleName), 'No such ARIA role ' + roleName);
|
||||
}
|
||||
element.setAttribute(goog.a11y.aria.ROLE_ATTRIBUTE_, roleName);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets role of an element.
|
||||
* @param {!Element} element DOM element to get role of.
|
||||
* @return {goog.a11y.aria.Role} ARIA Role name.
|
||||
*/
|
||||
goog.a11y.aria.getRole = function(element) {
|
||||
var role = element.getAttribute(goog.a11y.aria.ROLE_ATTRIBUTE_);
|
||||
return /** @type {goog.a11y.aria.Role} */ (role) || null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Removes role of an element.
|
||||
* @param {!Element} element DOM element to remove the role from.
|
||||
*/
|
||||
goog.a11y.aria.removeRole = function(element) {
|
||||
element.removeAttribute(goog.a11y.aria.ROLE_ATTRIBUTE_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the state or property of an element.
|
||||
* @param {!Element} element DOM node where we set state.
|
||||
* @param {!(goog.a11y.aria.State|string)} stateName State attribute being set.
|
||||
* Automatically adds prefix 'aria-' to the state name if the attribute is
|
||||
* not an extra attribute.
|
||||
* @param {string|boolean|number|!Array<string>} value Value
|
||||
* for the state attribute.
|
||||
*/
|
||||
goog.a11y.aria.setState = function(element, stateName, value) {
|
||||
if (goog.isArray(value)) {
|
||||
value = value.join(' ');
|
||||
}
|
||||
var attrStateName = goog.a11y.aria.getAriaAttributeName_(stateName);
|
||||
if (value === '' || value == undefined) {
|
||||
var defaultValueMap = goog.a11y.aria.datatables.getDefaultValuesMap();
|
||||
// Work around for browsers that don't properly support ARIA.
|
||||
// According to the ARIA W3C standard, user agents should allow
|
||||
// setting empty value which results in setting the default value
|
||||
// for the ARIA state if such exists. The exact text from the ARIA W3C
|
||||
// standard (http://www.w3.org/TR/wai-aria/states_and_properties):
|
||||
// "When a value is indicated as the default, the user agent
|
||||
// MUST follow the behavior prescribed by this value when the state or
|
||||
// property is empty or undefined."
|
||||
// The defaultValueMap contains the default values for the ARIA states
|
||||
// and has as a key the goog.a11y.aria.State constant for the state.
|
||||
if (stateName in defaultValueMap) {
|
||||
element.setAttribute(attrStateName, defaultValueMap[stateName]);
|
||||
} else {
|
||||
element.removeAttribute(attrStateName);
|
||||
}
|
||||
} else {
|
||||
element.setAttribute(attrStateName, value);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Toggles the ARIA attribute of an element.
|
||||
* Meant for attributes with a true/false value, but works with any attribute.
|
||||
* If the attribute does not have a true/false value, the following rules apply:
|
||||
* A not empty attribute will be removed.
|
||||
* An empty attribute will be set to true.
|
||||
* @param {!Element} el DOM node for which to set attribute.
|
||||
* @param {!(goog.a11y.aria.State|string)} attr ARIA attribute being set.
|
||||
* Automatically adds prefix 'aria-' to the attribute name if the attribute
|
||||
* is not an extra attribute.
|
||||
*/
|
||||
goog.a11y.aria.toggleState = function(el, attr) {
|
||||
var val = goog.a11y.aria.getState(el, attr);
|
||||
if (!goog.string.isEmptyOrWhitespace(goog.string.makeSafe(val)) &&
|
||||
!(val == 'true' || val == 'false')) {
|
||||
goog.a11y.aria.removeState(el, /** @type {!goog.a11y.aria.State} */ (attr));
|
||||
return;
|
||||
}
|
||||
goog.a11y.aria.setState(el, attr, val == 'true' ? 'false' : 'true');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Remove the state or property for the element.
|
||||
* @param {!Element} element DOM node where we set state.
|
||||
* @param {!goog.a11y.aria.State} stateName State name.
|
||||
*/
|
||||
goog.a11y.aria.removeState = function(element, stateName) {
|
||||
element.removeAttribute(goog.a11y.aria.getAriaAttributeName_(stateName));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets value of specified state or property.
|
||||
* @param {!Element} element DOM node to get state from.
|
||||
* @param {!goog.a11y.aria.State|string} stateName State name.
|
||||
* @return {string} Value of the state attribute.
|
||||
*/
|
||||
goog.a11y.aria.getState = function(element, stateName) {
|
||||
// TODO(user): return properly typed value result --
|
||||
// boolean, number, string, null. We should be able to chain
|
||||
// getState(...) and setState(...) methods.
|
||||
|
||||
var attr =
|
||||
/** @type {string|number|boolean} */ (element.getAttribute(
|
||||
goog.a11y.aria.getAriaAttributeName_(stateName)));
|
||||
var isNullOrUndefined = attr == null || attr == undefined;
|
||||
return isNullOrUndefined ? '' : String(attr);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the activedescendant element for the input element by
|
||||
* using the activedescendant ARIA property of the given element.
|
||||
* @param {!Element} element DOM node to get activedescendant
|
||||
* element for.
|
||||
* @return {?Element} DOM node of the activedescendant, if found.
|
||||
*/
|
||||
goog.a11y.aria.getActiveDescendant = function(element) {
|
||||
var id = goog.a11y.aria.getState(
|
||||
element, goog.a11y.aria.State.ACTIVEDESCENDANT);
|
||||
return goog.dom.getOwnerDocument(element).getElementById(id);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the activedescendant ARIA property value for an element.
|
||||
* If the activeElement is not null, it should have an id set.
|
||||
* @param {!Element} element DOM node to set activedescendant ARIA property to.
|
||||
* @param {?Element} activeElement DOM node being set as activedescendant.
|
||||
*/
|
||||
goog.a11y.aria.setActiveDescendant = function(element, activeElement) {
|
||||
var id = '';
|
||||
if (activeElement) {
|
||||
id = activeElement.id;
|
||||
goog.asserts.assert(id, 'The active element should have an id.');
|
||||
}
|
||||
|
||||
goog.a11y.aria.setState(element, goog.a11y.aria.State.ACTIVEDESCENDANT, id);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the label of the given element.
|
||||
* @param {!Element} element DOM node to get label from.
|
||||
* @return {string} label The label.
|
||||
*/
|
||||
goog.a11y.aria.getLabel = function(element) {
|
||||
return goog.a11y.aria.getState(element, goog.a11y.aria.State.LABEL);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the label of the given element.
|
||||
* @param {!Element} element DOM node to set label to.
|
||||
* @param {string} label The label to set.
|
||||
*/
|
||||
goog.a11y.aria.setLabel = function(element, label) {
|
||||
goog.a11y.aria.setState(element, goog.a11y.aria.State.LABEL, label);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Asserts that the element has a role set if it's not an HTML element whose
|
||||
* semantics is well supported by most screen readers.
|
||||
* Only to be used internally by the ARIA library in goog.a11y.aria.*.
|
||||
* @param {!Element} element The element to assert an ARIA role set.
|
||||
* @param {!goog.array.ArrayLike<string>} allowedRoles The child roles of
|
||||
* the roles.
|
||||
*/
|
||||
goog.a11y.aria.assertRoleIsSetInternalUtil = function(element, allowedRoles) {
|
||||
if (goog.array.contains(goog.a11y.aria.TAGS_WITH_ASSUMED_ROLES_,
|
||||
element.tagName)) {
|
||||
return;
|
||||
}
|
||||
var elementRole = /** @type {string}*/ (goog.a11y.aria.getRole(element));
|
||||
goog.asserts.assert(elementRole != null,
|
||||
'The element ARIA role cannot be null.');
|
||||
|
||||
goog.asserts.assert(goog.array.contains(allowedRoles, elementRole),
|
||||
'Non existing or incorrect role set for element.' +
|
||||
'The role set is "' + elementRole +
|
||||
'". The role should be any of "' + allowedRoles +
|
||||
'". Check the ARIA specification for more details ' +
|
||||
'http://www.w3.org/TR/wai-aria/roles.');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the boolean value of an ARIA state/property.
|
||||
* @param {!Element} element The element to get the ARIA state for.
|
||||
* @param {!goog.a11y.aria.State|string} stateName the ARIA state name.
|
||||
* @return {?boolean} Boolean value for the ARIA state value or null if
|
||||
* the state value is not 'true', not 'false', or not set.
|
||||
*/
|
||||
goog.a11y.aria.getStateBoolean = function(element, stateName) {
|
||||
var attr =
|
||||
/** @type {string|boolean} */ (element.getAttribute(
|
||||
goog.a11y.aria.getAriaAttributeName_(stateName)));
|
||||
goog.asserts.assert(
|
||||
goog.isBoolean(attr) || attr == null || attr == 'true' ||
|
||||
attr == 'false');
|
||||
if (attr == null) {
|
||||
return attr;
|
||||
}
|
||||
return goog.isBoolean(attr) ? attr : attr == 'true';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the number value of an ARIA state/property.
|
||||
* @param {!Element} element The element to get the ARIA state for.
|
||||
* @param {!goog.a11y.aria.State|string} stateName the ARIA state name.
|
||||
* @return {?number} Number value for the ARIA state value or null if
|
||||
* the state value is not a number or not set.
|
||||
*/
|
||||
goog.a11y.aria.getStateNumber = function(element, stateName) {
|
||||
var attr =
|
||||
/** @type {string|number} */ (element.getAttribute(
|
||||
goog.a11y.aria.getAriaAttributeName_(stateName)));
|
||||
goog.asserts.assert((attr == null || !isNaN(Number(attr))) &&
|
||||
!goog.isBoolean(attr));
|
||||
return attr == null ? null : Number(attr);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the string value of an ARIA state/property.
|
||||
* @param {!Element} element The element to get the ARIA state for.
|
||||
* @param {!goog.a11y.aria.State|string} stateName the ARIA state name.
|
||||
* @return {?string} String value for the ARIA state value or null if
|
||||
* the state value is empty string or not set.
|
||||
*/
|
||||
goog.a11y.aria.getStateString = function(element, stateName) {
|
||||
var attr = element.getAttribute(
|
||||
goog.a11y.aria.getAriaAttributeName_(stateName));
|
||||
goog.asserts.assert((attr == null || goog.isString(attr)) &&
|
||||
(attr == '' || isNaN(Number(attr))) && attr != 'true' && attr != 'false');
|
||||
return (attr == null || attr == '') ? null : attr;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets array of strings value of the specified state or
|
||||
* property for the element.
|
||||
* Only to be used internally by the ARIA library in goog.a11y.aria.*.
|
||||
* @param {!Element} element DOM node to get state from.
|
||||
* @param {!goog.a11y.aria.State} stateName State name.
|
||||
* @return {!goog.array.ArrayLike<string>} string Array
|
||||
* value of the state attribute.
|
||||
*/
|
||||
goog.a11y.aria.getStringArrayStateInternalUtil = function(element, stateName) {
|
||||
var attrValue = element.getAttribute(
|
||||
goog.a11y.aria.getAriaAttributeName_(stateName));
|
||||
return goog.a11y.aria.splitStringOnWhitespace_(attrValue);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns true if element has an ARIA state/property, false otherwise.
|
||||
* @param {!Element} element The element to get the ARIA state for.
|
||||
* @param {!goog.a11y.aria.State|string} stateName the ARIA state name.
|
||||
* @return {boolean}
|
||||
*/
|
||||
goog.a11y.aria.hasState = function(element, stateName) {
|
||||
return element.hasAttribute(goog.a11y.aria.getAriaAttributeName_(stateName));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns whether the element has a container ARIA role.
|
||||
* Container roles are ARIA roles that use the aria-activedescendant property
|
||||
* to manage their active descendants or children. See
|
||||
* {@link http://www.w3.org/TR/wai-aria/states_and_properties
|
||||
* #aria-activedescendant} for more information.
|
||||
* @param {!Element} element
|
||||
* @return {boolean}
|
||||
*/
|
||||
goog.a11y.aria.isContainerRole = function(element) {
|
||||
var role = goog.a11y.aria.getRole(element);
|
||||
return goog.array.contains(goog.a11y.aria.CONTAINER_ROLES_, role);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Splits the input stringValue on whitespace.
|
||||
* @param {string} stringValue The value of the string to split.
|
||||
* @return {!goog.array.ArrayLike<string>} string Array
|
||||
* value as result of the split.
|
||||
* @private
|
||||
*/
|
||||
goog.a11y.aria.splitStringOnWhitespace_ = function(stringValue) {
|
||||
return stringValue ? stringValue.split(/\s+/) : [];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds the 'aria-' prefix to ariaName.
|
||||
* @param {string} ariaName ARIA state/property name.
|
||||
* @private
|
||||
* @return {string} The ARIA attribute name with added 'aria-' prefix.
|
||||
* @throws {Error} If no such attribute exists.
|
||||
*/
|
||||
goog.a11y.aria.getAriaAttributeName_ = function(ariaName) {
|
||||
if (goog.asserts.ENABLE_ASSERTS) {
|
||||
goog.asserts.assert(ariaName, 'ARIA attribute cannot be empty.');
|
||||
goog.asserts.assert(goog.object.containsValue(
|
||||
goog.a11y.aria.State, ariaName),
|
||||
'No such ARIA attribute ' + ariaName);
|
||||
}
|
||||
return goog.a11y.aria.ARIA_PREFIX_ + ariaName;
|
||||
};
|
||||
@@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<!--
|
||||
Author: attila@google.com (Attila Bodis)
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>
|
||||
Closure Unit Tests - goog.a11y.aria
|
||||
</title>
|
||||
<script src="../../base.js">
|
||||
</script>
|
||||
<script>
|
||||
goog.require('goog.a11y.ariaTest');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="sandbox">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
278
vectortile/closure-library/closure/goog/a11y/aria/aria_test.js
Normal file
278
vectortile/closure-library/closure/goog/a11y/aria/aria_test.js
Normal file
@@ -0,0 +1,278 @@
|
||||
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.goog.provide('goog.a11y.ariaTest');
|
||||
|
||||
goog.provide('goog.a11y.ariaTest');
|
||||
goog.setTestOnly('goog.a11y.ariaTest');
|
||||
|
||||
goog.require('goog.a11y.aria');
|
||||
goog.require('goog.a11y.aria.Role');
|
||||
goog.require('goog.a11y.aria.State');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.dom.TagName');
|
||||
goog.require('goog.testing.jsunit');
|
||||
|
||||
var aria = goog.a11y.aria;
|
||||
var Role = goog.a11y.aria.Role;
|
||||
var State = goog.a11y.aria.State;
|
||||
var sandbox;
|
||||
var someDiv;
|
||||
var someSpan;
|
||||
var htmlButton;
|
||||
|
||||
function setUp() {
|
||||
sandbox = goog.dom.getElement('sandbox');
|
||||
someDiv = goog.dom.createDom(
|
||||
goog.dom.TagName.DIV, {id: 'someDiv'}, 'DIV');
|
||||
someSpan = goog.dom.createDom(
|
||||
goog.dom.TagName.SPAN, {id: 'someSpan'}, 'SPAN');
|
||||
htmlButton = goog.dom.createDom(
|
||||
goog.dom.TagName.BUTTON, {id: 'someButton'}, 'BUTTON');
|
||||
goog.dom.appendChild(sandbox, someDiv);
|
||||
goog.dom.appendChild(someDiv, someSpan);
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
goog.dom.removeChildren(sandbox);
|
||||
someDiv = null;
|
||||
someSpan = null;
|
||||
htmlButton = null;
|
||||
}
|
||||
|
||||
function testGetSetRole() {
|
||||
assertNull('someDiv\'s role should be null', aria.getRole(someDiv));
|
||||
assertNull('someSpan\'s role should be null', aria.getRole(someSpan));
|
||||
|
||||
aria.setRole(someDiv, Role.MENU);
|
||||
aria.setRole(someSpan, Role.MENU_ITEM);
|
||||
|
||||
assertEquals('someDiv\'s role should be MENU',
|
||||
Role.MENU, aria.getRole(someDiv));
|
||||
assertEquals('someSpan\'s role should be MENU_ITEM',
|
||||
Role.MENU_ITEM, aria.getRole(someSpan));
|
||||
|
||||
var div = goog.dom.createElement(goog.dom.TagName.DIV);
|
||||
goog.dom.appendChild(sandbox, div);
|
||||
goog.dom.appendChild(div, goog.dom.createDom(goog.dom.TagName.SPAN,
|
||||
{id: 'anotherSpan', role: Role.CHECKBOX}));
|
||||
assertEquals('anotherSpan\'s role should be CHECKBOX',
|
||||
Role.CHECKBOX, aria.getRole(goog.dom.getElement('anotherSpan')));
|
||||
}
|
||||
|
||||
function testGetSetToggleState() {
|
||||
assertThrows('Should throw because no state is specified.',
|
||||
function() {
|
||||
aria.getState(someDiv);
|
||||
});
|
||||
assertThrows('Should throw because no state is specified.',
|
||||
function() {
|
||||
aria.getState(someDiv);
|
||||
});
|
||||
aria.setState(someDiv, State.LABELLEDBY, 'someSpan');
|
||||
|
||||
assertEquals('someDiv\'s labelledby state should be "someSpan"',
|
||||
'someSpan', aria.getState(someDiv, State.LABELLEDBY));
|
||||
|
||||
// Test setting for aria-activedescendant with empty value.
|
||||
assertFalse(someDiv.hasAttribute ?
|
||||
someDiv.hasAttribute('aria-activedescendant') :
|
||||
!!someDiv.getAttribute('aria-activedescendant'));
|
||||
aria.setState(someDiv, State.ACTIVEDESCENDANT, 'someSpan');
|
||||
assertEquals('someSpan', aria.getState(someDiv, State.ACTIVEDESCENDANT));
|
||||
aria.setState(someDiv, State.ACTIVEDESCENDANT, '');
|
||||
assertFalse(someDiv.hasAttribute ?
|
||||
someDiv.hasAttribute('aria-activedescendant') :
|
||||
!!someDiv.getAttribute('aria-activedescendant'));
|
||||
|
||||
// Test setting state that has a default value to empty value.
|
||||
assertFalse(someDiv.hasAttribute ?
|
||||
someDiv.hasAttribute('aria-relevant') :
|
||||
!!someDiv.getAttribute('aria-relevant'));
|
||||
aria.setState(someDiv, State.RELEVANT, aria.RelevantValues.TEXT);
|
||||
assertEquals(
|
||||
aria.RelevantValues.TEXT, aria.getState(someDiv, State.RELEVANT));
|
||||
aria.setState(someDiv, State.RELEVANT, '');
|
||||
assertEquals(
|
||||
aria.RelevantValues.ADDITIONS + ' ' + aria.RelevantValues.TEXT,
|
||||
aria.getState(someDiv, State.RELEVANT));
|
||||
|
||||
// Test toggling an attribute that has a true/false value.
|
||||
aria.setState(someDiv, State.EXPANDED, false);
|
||||
assertEquals('false', aria.getState(someDiv, State.EXPANDED));
|
||||
aria.toggleState(someDiv, State.EXPANDED);
|
||||
assertEquals('true', aria.getState(someDiv, State.EXPANDED));
|
||||
aria.setState(someDiv, State.EXPANDED, true);
|
||||
assertEquals('true', aria.getState(someDiv, State.EXPANDED));
|
||||
aria.toggleState(someDiv, State.EXPANDED);
|
||||
assertEquals('false', aria.getState(someDiv, State.EXPANDED));
|
||||
|
||||
// Test toggling an attribute that does not have a true/false value.
|
||||
aria.setState(someDiv, State.RELEVANT, aria.RelevantValues.TEXT);
|
||||
assertEquals(
|
||||
aria.RelevantValues.TEXT, aria.getState(someDiv, State.RELEVANT));
|
||||
aria.toggleState(someDiv, State.RELEVANT);
|
||||
assertEquals('', aria.getState(someDiv, State.RELEVANT));
|
||||
aria.removeState(someDiv, State.RELEVANT);
|
||||
assertEquals('', aria.getState(someDiv, State.RELEVANT));
|
||||
// This is not a valid value, but this is what happens if toggle is misused.
|
||||
aria.toggleState(someDiv, State.RELEVANT);
|
||||
assertEquals('true', aria.getState(someDiv, State.RELEVANT));
|
||||
}
|
||||
|
||||
function testGetStateString() {
|
||||
aria.setState(someDiv, State.LABEL, 'test_label');
|
||||
aria.setState(
|
||||
someSpan, State.LABEL, aria.getStateString(someDiv, State.LABEL));
|
||||
assertEquals(aria.getState(someDiv, State.LABEL),
|
||||
aria.getState(someSpan, State.LABEL));
|
||||
assertEquals('The someDiv\'s enum value should be "test_label".',
|
||||
'test_label', aria.getState(someDiv, State.LABEL));
|
||||
assertEquals('The someSpan\'s enum value should be "copy move".',
|
||||
'test_label', aria.getStateString(someSpan, State.LABEL));
|
||||
someDiv.setAttribute('aria-label', '');
|
||||
assertEquals(null, aria.getStateString(someDiv, State.LABEL));
|
||||
aria.setState(someDiv, State.MULTILINE, true);
|
||||
var thrown = false;
|
||||
try {
|
||||
aria.getStateString(someDiv, State.MULTILINE);
|
||||
} catch (e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue('invalid use of getStateString on boolean.', thrown);
|
||||
aria.setState(someDiv, State.LIVE, aria.LivePriority.ASSERTIVE);
|
||||
thrown = false;
|
||||
aria.setState(someDiv, State.LEVEL, 1);
|
||||
try {
|
||||
aria.getStateString(someDiv, State.LEVEL);
|
||||
} catch (e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue('invalid use of getStateString on numbers.', thrown);
|
||||
}
|
||||
|
||||
|
||||
function testGetStateStringArray() {
|
||||
aria.setState(someDiv, State.LABELLEDBY, ['1', '2']);
|
||||
aria.setState(someSpan, State.LABELLEDBY,
|
||||
aria.getStringArrayStateInternalUtil(someDiv, State.LABELLEDBY));
|
||||
assertEquals(aria.getState(someDiv, State.LABELLEDBY),
|
||||
aria.getState(someSpan, State.LABELLEDBY));
|
||||
|
||||
assertEquals('The someDiv\'s enum value should be "1 2".', '1 2',
|
||||
aria.getState(someDiv, State.LABELLEDBY));
|
||||
assertEquals('The someSpan\'s enum value should be "1 2".', '1 2',
|
||||
aria.getState(someSpan, State.LABELLEDBY));
|
||||
|
||||
assertSameElements('The someDiv\'s enum value should be "1 2".',
|
||||
['1', '2'],
|
||||
aria.getStringArrayStateInternalUtil(someDiv, State.LABELLEDBY));
|
||||
assertSameElements('The someSpan\'s enum value should be "1 2".',
|
||||
['1', '2'],
|
||||
aria.getStringArrayStateInternalUtil(someSpan, State.LABELLEDBY));
|
||||
}
|
||||
|
||||
|
||||
function testGetStateNumber() {
|
||||
aria.setState(someDiv, State.LEVEL, 1);
|
||||
aria.setState(
|
||||
someSpan, State.LEVEL, aria.getStateNumber(someDiv, State.LEVEL));
|
||||
assertEquals(aria.getState(someDiv, State.LEVEL),
|
||||
aria.getState(someSpan, State.LEVEL));
|
||||
assertEquals('The someDiv\'s enum value should be "1".', '1',
|
||||
aria.getState(someDiv, State.LEVEL));
|
||||
assertEquals('The someSpan\'s enum value should be "1".', '1',
|
||||
aria.getState(someSpan, State.LEVEL));
|
||||
assertEquals('The someDiv\'s enum value should be "1".', 1,
|
||||
aria.getStateNumber(someDiv, State.LEVEL));
|
||||
assertEquals('The someSpan\'s enum value should be "1".', 1,
|
||||
aria.getStateNumber(someSpan, State.LEVEL));
|
||||
aria.setState(someDiv, State.MULTILINE, true);
|
||||
var thrown = false;
|
||||
try {
|
||||
aria.getStateNumber(someDiv, State.MULTILINE);
|
||||
} catch (e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue('invalid use of getStateNumber on boolean.', thrown);
|
||||
aria.setState(someDiv, State.LIVE, aria.LivePriority.ASSERTIVE);
|
||||
thrown = false;
|
||||
try {
|
||||
aria.getStateBoolean(someDiv, State.LIVE);
|
||||
} catch (e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue('invalid use of getStateNumber on strings.', thrown);
|
||||
}
|
||||
|
||||
function testGetStateBoolean() {
|
||||
assertNull(aria.getStateBoolean(someDiv, State.MULTILINE));
|
||||
|
||||
aria.setState(someDiv, State.MULTILINE, false);
|
||||
assertFalse(aria.getStateBoolean(someDiv, State.MULTILINE));
|
||||
|
||||
aria.setState(someDiv, State.MULTILINE, true);
|
||||
aria.setState(someSpan, State.MULTILINE,
|
||||
aria.getStateBoolean(someDiv, State.MULTILINE));
|
||||
assertEquals(aria.getState(someDiv, State.MULTILINE),
|
||||
aria.getState(someSpan, State.MULTILINE));
|
||||
assertEquals('The someDiv\'s enum value should be "true".', 'true',
|
||||
aria.getState(someDiv, State.MULTILINE));
|
||||
assertEquals('The someSpan\'s enum value should be "true".', 'true',
|
||||
aria.getState(someSpan, State.MULTILINE));
|
||||
assertEquals('The someDiv\'s enum value should be "true".', true,
|
||||
aria.getStateBoolean(someDiv, State.MULTILINE));
|
||||
assertEquals('The someSpan\'s enum value should be "true".', true,
|
||||
aria.getStateBoolean(someSpan, State.MULTILINE));
|
||||
aria.setState(someDiv, State.LEVEL, 1);
|
||||
var thrown = false;
|
||||
try {
|
||||
aria.getStateBoolean(someDiv, State.LEVEL);
|
||||
} catch (e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue('invalid use of getStateBoolean on numbers.', thrown);
|
||||
aria.setState(someDiv, State.LIVE, aria.LivePriority.ASSERTIVE);
|
||||
thrown = false;
|
||||
try {
|
||||
aria.getStateBoolean(someDiv, State.LIVE);
|
||||
} catch (e) {
|
||||
thrown = true;
|
||||
}
|
||||
assertTrue('invalid use of getStateBoolean on strings.', thrown);
|
||||
}
|
||||
|
||||
function testGetSetActiveDescendant() {
|
||||
aria.setActiveDescendant(someDiv, null);
|
||||
assertNull('someDiv\'s activedescendant should be null',
|
||||
aria.getActiveDescendant(someDiv));
|
||||
|
||||
aria.setActiveDescendant(someDiv, someSpan);
|
||||
|
||||
assertEquals('someDiv\'s active descendant should be "someSpan"',
|
||||
someSpan, aria.getActiveDescendant(someDiv));
|
||||
}
|
||||
|
||||
function testGetSetLabel() {
|
||||
assertEquals('someDiv\'s label should be ""', '', aria.getLabel(someDiv));
|
||||
|
||||
aria.setLabel(someDiv, 'somelabel');
|
||||
assertEquals('someDiv\'s label should be "somelabel"', 'somelabel',
|
||||
aria.getLabel(someDiv));
|
||||
}
|
||||
|
||||
function testHasState() {
|
||||
aria.setState(someDiv, State.EXPANDED, false);
|
||||
assertTrue(aria.hasState(someDiv, State.EXPANDED));
|
||||
aria.removeState(someDiv, State.EXPANDED);
|
||||
assertFalse(aria.hasState(someDiv, State.EXPANDED));
|
||||
}
|
||||
389
vectortile/closure-library/closure/goog/a11y/aria/attributes.js
Normal file
389
vectortile/closure-library/closure/goog/a11y/aria/attributes.js
Normal file
@@ -0,0 +1,389 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview The file contains generated enumerations for ARIA states
|
||||
* and properties as defined by W3C ARIA standard:
|
||||
* http://www.w3.org/TR/wai-aria/.
|
||||
*
|
||||
* This is auto-generated code. Do not manually edit! For more details
|
||||
* about how to edit it via the generator check go/closure-ariagen.
|
||||
*/
|
||||
|
||||
goog.provide('goog.a11y.aria.AutoCompleteValues');
|
||||
goog.provide('goog.a11y.aria.CheckedValues');
|
||||
goog.provide('goog.a11y.aria.DropEffectValues');
|
||||
goog.provide('goog.a11y.aria.ExpandedValues');
|
||||
goog.provide('goog.a11y.aria.GrabbedValues');
|
||||
goog.provide('goog.a11y.aria.InvalidValues');
|
||||
goog.provide('goog.a11y.aria.LivePriority');
|
||||
goog.provide('goog.a11y.aria.OrientationValues');
|
||||
goog.provide('goog.a11y.aria.PressedValues');
|
||||
goog.provide('goog.a11y.aria.RelevantValues');
|
||||
goog.provide('goog.a11y.aria.SelectedValues');
|
||||
goog.provide('goog.a11y.aria.SortValues');
|
||||
goog.provide('goog.a11y.aria.State');
|
||||
|
||||
|
||||
/**
|
||||
* ARIA states and properties.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.a11y.aria.State = {
|
||||
// ARIA property for setting the currently active descendant of an element,
|
||||
// for example the selected item in a list box. Value: ID of an element.
|
||||
ACTIVEDESCENDANT: 'activedescendant',
|
||||
|
||||
// ARIA property that, if true, indicates that all of a changed region should
|
||||
// be presented, instead of only parts. Value: one of {true, false}.
|
||||
ATOMIC: 'atomic',
|
||||
|
||||
// ARIA property to specify that input completion is provided. Value:
|
||||
// one of {'inline', 'list', 'both', 'none'}.
|
||||
AUTOCOMPLETE: 'autocomplete',
|
||||
|
||||
// ARIA state to indicate that an element and its subtree are being updated.
|
||||
// Value: one of {true, false}.
|
||||
BUSY: 'busy',
|
||||
|
||||
// ARIA state for a checked item. Value: one of {'true', 'false', 'mixed',
|
||||
// undefined}.
|
||||
CHECKED: 'checked',
|
||||
|
||||
// ARIA property that identifies the element or elements whose contents or
|
||||
// presence are controlled by this element.
|
||||
// Value: space-separated IDs of other elements.
|
||||
CONTROLS: 'controls',
|
||||
|
||||
// ARIA property that identifies the element or elements that describe
|
||||
// this element. Value: space-separated IDs of other elements.
|
||||
DESCRIBEDBY: 'describedby',
|
||||
|
||||
// ARIA state for a disabled item. Value: one of {true, false}.
|
||||
DISABLED: 'disabled',
|
||||
|
||||
// ARIA property that indicates what functions can be performed when a
|
||||
// dragged object is released on the drop target. Value: one of
|
||||
// {'copy', 'move', 'link', 'execute', 'popup', 'none'}.
|
||||
DROPEFFECT: 'dropeffect',
|
||||
|
||||
// ARIA state for setting whether the element like a tree node is expanded.
|
||||
// Value: one of {true, false, undefined}.
|
||||
EXPANDED: 'expanded',
|
||||
|
||||
// ARIA property that identifies the next element (or elements) in the
|
||||
// recommended reading order of content. Value: space-separated ids of
|
||||
// elements to flow to.
|
||||
FLOWTO: 'flowto',
|
||||
|
||||
// ARIA state that indicates an element's "grabbed" state in drag-and-drop.
|
||||
// Value: one of {true, false, undefined}.
|
||||
GRABBED: 'grabbed',
|
||||
|
||||
// ARIA property indicating whether the element has a popup.
|
||||
// Value: one of {true, false}.
|
||||
HASPOPUP: 'haspopup',
|
||||
|
||||
// ARIA state indicating that the element is not visible or perceivable
|
||||
// to any user. Value: one of {true, false}.
|
||||
HIDDEN: 'hidden',
|
||||
|
||||
// ARIA state indicating that the entered value does not conform. Value:
|
||||
// one of {false, true, 'grammar', 'spelling'}
|
||||
INVALID: 'invalid',
|
||||
|
||||
// ARIA property that provides a label to override any other text, value, or
|
||||
// contents used to describe this element. Value: string.
|
||||
LABEL: 'label',
|
||||
|
||||
// ARIA property for setting the element which labels another element.
|
||||
// Value: space-separated IDs of elements.
|
||||
LABELLEDBY: 'labelledby',
|
||||
|
||||
// ARIA property for setting the level of an element in the hierarchy.
|
||||
// Value: integer.
|
||||
LEVEL: 'level',
|
||||
|
||||
// ARIA property indicating that an element will be updated, and
|
||||
// describes the types of updates the user agents, assistive technologies,
|
||||
// and user can expect from the live region. Value: one of {'off', 'polite',
|
||||
// 'assertive'}.
|
||||
LIVE: 'live',
|
||||
|
||||
// ARIA property indicating whether a text box can accept multiline input.
|
||||
// Value: one of {true, false}.
|
||||
MULTILINE: 'multiline',
|
||||
|
||||
// ARIA property indicating if the user may select more than one item.
|
||||
// Value: one of {true, false}.
|
||||
MULTISELECTABLE: 'multiselectable',
|
||||
|
||||
// ARIA property indicating if the element is horizontal or vertical.
|
||||
// Value: one of {'vertical', 'horizontal'}.
|
||||
ORIENTATION: 'orientation',
|
||||
|
||||
// ARIA property creating a visual, functional, or contextual parent/child
|
||||
// relationship when the DOM hierarchy can't be used to represent it.
|
||||
// Value: Space-separated IDs of elements.
|
||||
OWNS: 'owns',
|
||||
|
||||
// ARIA property that defines an element's number of position in a list.
|
||||
// Value: integer.
|
||||
POSINSET: 'posinset',
|
||||
|
||||
// ARIA state for a pressed item.
|
||||
// Value: one of {true, false, undefined, 'mixed'}.
|
||||
PRESSED: 'pressed',
|
||||
|
||||
// ARIA property indicating that an element is not editable.
|
||||
// Value: one of {true, false}.
|
||||
READONLY: 'readonly',
|
||||
|
||||
// ARIA property indicating that change notifications within this subtree
|
||||
// of a live region should be announced. Value: one of {'additions',
|
||||
// 'removals', 'text', 'all', 'additions text'}.
|
||||
RELEVANT: 'relevant',
|
||||
|
||||
// ARIA property indicating that user input is required on this element
|
||||
// before a form may be submitted. Value: one of {true, false}.
|
||||
REQUIRED: 'required',
|
||||
|
||||
// ARIA state for setting the currently selected item in the list.
|
||||
// Value: one of {true, false, undefined}.
|
||||
SELECTED: 'selected',
|
||||
|
||||
// ARIA property defining the number of items in a list. Value: integer.
|
||||
SETSIZE: 'setsize',
|
||||
|
||||
// ARIA property indicating if items are sorted. Value: one of {'ascending',
|
||||
// 'descending', 'none', 'other'}.
|
||||
SORT: 'sort',
|
||||
|
||||
// ARIA property for slider maximum value. Value: number.
|
||||
VALUEMAX: 'valuemax',
|
||||
|
||||
// ARIA property for slider minimum value. Value: number.
|
||||
VALUEMIN: 'valuemin',
|
||||
|
||||
// ARIA property for slider active value. Value: number.
|
||||
VALUENOW: 'valuenow',
|
||||
|
||||
// ARIA property for slider active value represented as text.
|
||||
// Value: string.
|
||||
VALUETEXT: 'valuetext'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ARIA state values for AutoCompleteValues.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.a11y.aria.AutoCompleteValues = {
|
||||
// The system provides text after the caret as a suggestion
|
||||
// for how to complete the field.
|
||||
INLINE: 'inline',
|
||||
// A list of choices appears from which the user can choose,
|
||||
// but the edit box retains focus.
|
||||
LIST: 'list',
|
||||
// A list of choices appears and the currently selected suggestion
|
||||
// also appears inline.
|
||||
BOTH: 'both',
|
||||
// No input completion suggestions are provided.
|
||||
NONE: 'none'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ARIA state values for DropEffectValues.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.a11y.aria.DropEffectValues = {
|
||||
// A duplicate of the source object will be dropped into the target.
|
||||
COPY: 'copy',
|
||||
// The source object will be removed from its current location
|
||||
// and dropped into the target.
|
||||
MOVE: 'move',
|
||||
// A reference or shortcut to the dragged object
|
||||
// will be created in the target object.
|
||||
LINK: 'link',
|
||||
// A function supported by the drop target is
|
||||
// executed, using the drag source as an input.
|
||||
EXECUTE: 'execute',
|
||||
// There is a popup menu or dialog that allows the user to choose
|
||||
// one of the drag operations (copy, move, link, execute) and any other
|
||||
// drag functionality, such as cancel.
|
||||
POPUP: 'popup',
|
||||
// No operation can be performed; effectively
|
||||
// cancels the drag operation if an attempt is made to drop on this object.
|
||||
NONE: 'none'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ARIA state values for LivePriority.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.a11y.aria.LivePriority = {
|
||||
// Updates to the region will not be presented to the user
|
||||
// unless the assitive technology is currently focused on that region.
|
||||
OFF: 'off',
|
||||
// (Background change) Assistive technologies SHOULD announce
|
||||
// updates at the next graceful opportunity, such as at the end of
|
||||
// speaking the current sentence or when the user pauses typing.
|
||||
POLITE: 'polite',
|
||||
// This information has the highest priority and assistive
|
||||
// technologies SHOULD notify the user immediately.
|
||||
// Because an interruption may disorient users or cause them to not complete
|
||||
// their current task, authors SHOULD NOT use the assertive value unless the
|
||||
// interruption is imperative.
|
||||
ASSERTIVE: 'assertive'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ARIA state values for OrientationValues.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.a11y.aria.OrientationValues = {
|
||||
// The element is oriented vertically.
|
||||
VERTICAL: 'vertical',
|
||||
// The element is oriented horizontally.
|
||||
HORIZONTAL: 'horizontal'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ARIA state values for RelevantValues.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.a11y.aria.RelevantValues = {
|
||||
// Element nodes are added to the DOM within the live region.
|
||||
ADDITIONS: 'additions',
|
||||
// Text or element nodes within the live region are removed from the DOM.
|
||||
REMOVALS: 'removals',
|
||||
// Text is added to any DOM descendant nodes of the live region.
|
||||
TEXT: 'text',
|
||||
// Equivalent to the combination of all values, "additions removals text".
|
||||
ALL: 'all'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ARIA state values for SortValues.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.a11y.aria.SortValues = {
|
||||
// Items are sorted in ascending order by this column.
|
||||
ASCENDING: 'ascending',
|
||||
// Items are sorted in descending order by this column.
|
||||
DESCENDING: 'descending',
|
||||
// There is no defined sort applied to the column.
|
||||
NONE: 'none',
|
||||
// A sort algorithm other than ascending or descending has been applied.
|
||||
OTHER: 'other'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ARIA state values for CheckedValues.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.a11y.aria.CheckedValues = {
|
||||
// The selectable element is checked.
|
||||
TRUE: 'true',
|
||||
// The selectable element is not checked.
|
||||
FALSE: 'false',
|
||||
// Indicates a mixed mode value for a tri-state
|
||||
// checkbox or menuitemcheckbox.
|
||||
MIXED: 'mixed',
|
||||
// The element does not support being checked.
|
||||
UNDEFINED: 'undefined'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ARIA state values for ExpandedValues.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.a11y.aria.ExpandedValues = {
|
||||
// The element, or another grouping element it controls, is expanded.
|
||||
TRUE: 'true',
|
||||
// The element, or another grouping element it controls, is collapsed.
|
||||
FALSE: 'false',
|
||||
// The element, or another grouping element
|
||||
// it controls, is neither expandable nor collapsible; all its
|
||||
// child elements are shown or there are no child elements.
|
||||
UNDEFINED: 'undefined'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ARIA state values for GrabbedValues.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.a11y.aria.GrabbedValues = {
|
||||
// Indicates that the element has been "grabbed" for dragging.
|
||||
TRUE: 'true',
|
||||
// Indicates that the element supports being dragged.
|
||||
FALSE: 'false',
|
||||
// Indicates that the element does not support being dragged.
|
||||
UNDEFINED: 'undefined'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ARIA state values for InvalidValues.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.a11y.aria.InvalidValues = {
|
||||
// There are no detected errors in the value.
|
||||
FALSE: 'false',
|
||||
// The value entered by the user has failed validation.
|
||||
TRUE: 'true',
|
||||
// A grammatical error was detected.
|
||||
GRAMMAR: 'grammar',
|
||||
// A spelling error was detected.
|
||||
SPELLING: 'spelling'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ARIA state values for PressedValues.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.a11y.aria.PressedValues = {
|
||||
// The element is pressed.
|
||||
TRUE: 'true',
|
||||
// The element supports being pressed but is not currently pressed.
|
||||
FALSE: 'false',
|
||||
// Indicates a mixed mode value for a tri-state toggle button.
|
||||
MIXED: 'mixed',
|
||||
// The element does not support being pressed.
|
||||
UNDEFINED: 'undefined'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ARIA state values for SelectedValues.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.a11y.aria.SelectedValues = {
|
||||
// The selectable element is selected.
|
||||
TRUE: 'true',
|
||||
// The selectable element is not selected.
|
||||
FALSE: 'false',
|
||||
// The element is not selectable.
|
||||
UNDEFINED: 'undefined'
|
||||
};
|
||||
@@ -0,0 +1,68 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview The file contains data tables generated from the ARIA
|
||||
* standard schema http://www.w3.org/TR/wai-aria/.
|
||||
*
|
||||
* This is auto-generated code. Do not manually edit!
|
||||
*/
|
||||
|
||||
goog.provide('goog.a11y.aria.datatables');
|
||||
|
||||
goog.require('goog.a11y.aria.State');
|
||||
goog.require('goog.object');
|
||||
|
||||
|
||||
/**
|
||||
* A map that contains mapping between an ARIA state and the default value
|
||||
* for it. Note that not all ARIA states have default values.
|
||||
*
|
||||
* @type {Object<!(goog.a11y.aria.State|string), (string|boolean|number)>}
|
||||
*/
|
||||
goog.a11y.aria.DefaultStateValueMap_;
|
||||
|
||||
|
||||
/**
|
||||
* A method that creates a map that contains mapping between an ARIA state and
|
||||
* the default value for it. Note that not all ARIA states have default values.
|
||||
*
|
||||
* @return {!Object<!(goog.a11y.aria.State|string), (string|boolean|number)>}
|
||||
* The names for each of the notification methods.
|
||||
*/
|
||||
goog.a11y.aria.datatables.getDefaultValuesMap = function() {
|
||||
if (!goog.a11y.aria.DefaultStateValueMap_) {
|
||||
goog.a11y.aria.DefaultStateValueMap_ = goog.object.create(
|
||||
goog.a11y.aria.State.ATOMIC, false,
|
||||
goog.a11y.aria.State.AUTOCOMPLETE, 'none',
|
||||
goog.a11y.aria.State.DROPEFFECT, 'none',
|
||||
goog.a11y.aria.State.HASPOPUP, false,
|
||||
goog.a11y.aria.State.LIVE, 'off',
|
||||
goog.a11y.aria.State.MULTILINE, false,
|
||||
goog.a11y.aria.State.MULTISELECTABLE, false,
|
||||
goog.a11y.aria.State.ORIENTATION, 'vertical',
|
||||
goog.a11y.aria.State.READONLY, false,
|
||||
goog.a11y.aria.State.RELEVANT, 'additions text',
|
||||
goog.a11y.aria.State.REQUIRED, false,
|
||||
goog.a11y.aria.State.SORT, 'none',
|
||||
goog.a11y.aria.State.BUSY, false,
|
||||
goog.a11y.aria.State.DISABLED, false,
|
||||
goog.a11y.aria.State.HIDDEN, false,
|
||||
goog.a11y.aria.State.INVALID, 'false');
|
||||
}
|
||||
|
||||
return goog.a11y.aria.DefaultStateValueMap_;
|
||||
};
|
||||
219
vectortile/closure-library/closure/goog/a11y/aria/roles.js
Normal file
219
vectortile/closure-library/closure/goog/a11y/aria/roles.js
Normal file
@@ -0,0 +1,219 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview The file contains generated enumerations for ARIA roles
|
||||
* as defined by W3C ARIA standard: http://www.w3.org/TR/wai-aria/.
|
||||
*
|
||||
* This is auto-generated code. Do not manually edit! For more details
|
||||
* about how to edit it via the generator check go/closure-ariagen.
|
||||
*/
|
||||
|
||||
goog.provide('goog.a11y.aria.Role');
|
||||
|
||||
|
||||
/**
|
||||
* ARIA role values.
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.a11y.aria.Role = {
|
||||
// ARIA role for an alert element that doesn't need to be explicitly closed.
|
||||
ALERT: 'alert',
|
||||
|
||||
// ARIA role for an alert dialog element that takes focus and must be closed.
|
||||
ALERTDIALOG: 'alertdialog',
|
||||
|
||||
// ARIA role for an application that implements its own keyboard navigation.
|
||||
APPLICATION: 'application',
|
||||
|
||||
// ARIA role for an article.
|
||||
ARTICLE: 'article',
|
||||
|
||||
// ARIA role for a banner containing mostly site content, not page content.
|
||||
BANNER: 'banner',
|
||||
|
||||
// ARIA role for a button element.
|
||||
BUTTON: 'button',
|
||||
|
||||
// ARIA role for a checkbox button element; use with the CHECKED state.
|
||||
CHECKBOX: 'checkbox',
|
||||
|
||||
// ARIA role for a column header of a table or grid.
|
||||
COLUMNHEADER: 'columnheader',
|
||||
|
||||
// ARIA role for a combo box element.
|
||||
COMBOBOX: 'combobox',
|
||||
|
||||
// ARIA role for a supporting section of the document.
|
||||
COMPLEMENTARY: 'complementary',
|
||||
|
||||
// ARIA role for a large perceivable region that contains information
|
||||
// about the parent document.
|
||||
CONTENTINFO: 'contentinfo',
|
||||
|
||||
// ARIA role for a definition of a term or concept.
|
||||
DEFINITION: 'definition',
|
||||
|
||||
// ARIA role for a dialog, some descendant must take initial focus.
|
||||
DIALOG: 'dialog',
|
||||
|
||||
// ARIA role for a directory, like a table of contents.
|
||||
DIRECTORY: 'directory',
|
||||
|
||||
// ARIA role for a part of a page that's a document, not a web application.
|
||||
DOCUMENT: 'document',
|
||||
|
||||
// ARIA role for a landmark region logically considered one form.
|
||||
FORM: 'form',
|
||||
|
||||
// ARIA role for an interactive control of tabular data.
|
||||
GRID: 'grid',
|
||||
|
||||
// ARIA role for a cell in a grid.
|
||||
GRIDCELL: 'gridcell',
|
||||
|
||||
// ARIA role for a group of related elements like tree item siblings.
|
||||
GROUP: 'group',
|
||||
|
||||
// ARIA role for a heading element.
|
||||
HEADING: 'heading',
|
||||
|
||||
// ARIA role for a container of elements that together comprise one image.
|
||||
IMG: 'img',
|
||||
|
||||
// ARIA role for a link.
|
||||
LINK: 'link',
|
||||
|
||||
// ARIA role for a list of non-interactive list items.
|
||||
LIST: 'list',
|
||||
|
||||
// ARIA role for a listbox.
|
||||
LISTBOX: 'listbox',
|
||||
|
||||
// ARIA role for a list item.
|
||||
LISTITEM: 'listitem',
|
||||
|
||||
// ARIA role for a live region where new information is added.
|
||||
LOG: 'log',
|
||||
|
||||
// ARIA landmark role for the main content in a document. Use only once.
|
||||
MAIN: 'main',
|
||||
|
||||
// ARIA role for a live region of non-essential information that changes.
|
||||
MARQUEE: 'marquee',
|
||||
|
||||
// ARIA role for a mathematical expression.
|
||||
MATH: 'math',
|
||||
|
||||
// ARIA role for a popup menu.
|
||||
MENU: 'menu',
|
||||
|
||||
// ARIA role for a menubar element containing menu elements.
|
||||
MENUBAR: 'menubar',
|
||||
|
||||
// ARIA role for menu item elements.
|
||||
MENU_ITEM: 'menuitem',
|
||||
|
||||
// ARIA role for a checkbox box element inside a menu.
|
||||
MENU_ITEM_CHECKBOX: 'menuitemcheckbox',
|
||||
|
||||
// ARIA role for a radio button element inside a menu.
|
||||
MENU_ITEM_RADIO: 'menuitemradio',
|
||||
|
||||
// ARIA landmark role for a collection of navigation links.
|
||||
NAVIGATION: 'navigation',
|
||||
|
||||
// ARIA role for a section ancillary to the main content.
|
||||
NOTE: 'note',
|
||||
|
||||
// ARIA role for option items that are children of combobox, listbox, menu,
|
||||
// radiogroup, or tree elements.
|
||||
OPTION: 'option',
|
||||
|
||||
// ARIA role for ignorable cosmetic elements with no semantic significance.
|
||||
PRESENTATION: 'presentation',
|
||||
|
||||
// ARIA role for a progress bar element.
|
||||
PROGRESSBAR: 'progressbar',
|
||||
|
||||
// ARIA role for a radio button element.
|
||||
RADIO: 'radio',
|
||||
|
||||
// ARIA role for a group of connected radio button elements.
|
||||
RADIOGROUP: 'radiogroup',
|
||||
|
||||
// ARIA role for an important region of the page.
|
||||
REGION: 'region',
|
||||
|
||||
// ARIA role for a row of cells in a grid.
|
||||
ROW: 'row',
|
||||
|
||||
// ARIA role for a group of one or more rows in a grid.
|
||||
ROWGROUP: 'rowgroup',
|
||||
|
||||
// ARIA role for a row header of a table or grid.
|
||||
ROWHEADER: 'rowheader',
|
||||
|
||||
// ARIA role for a scrollbar element.
|
||||
SCROLLBAR: 'scrollbar',
|
||||
|
||||
// ARIA landmark role for a part of the page providing search functionality.
|
||||
SEARCH: 'search',
|
||||
|
||||
// ARIA role for a menu separator.
|
||||
SEPARATOR: 'separator',
|
||||
|
||||
// ARIA role for a slider.
|
||||
SLIDER: 'slider',
|
||||
|
||||
// ARIA role for a spin button.
|
||||
SPINBUTTON: 'spinbutton',
|
||||
|
||||
// ARIA role for a live region with advisory info less severe than an alert.
|
||||
STATUS: 'status',
|
||||
|
||||
// ARIA role for a tab button.
|
||||
TAB: 'tab',
|
||||
|
||||
// ARIA role for a tab bar (i.e. a list of tab buttons).
|
||||
TAB_LIST: 'tablist',
|
||||
|
||||
// ARIA role for a tab page (i.e. the element holding tab contents).
|
||||
TAB_PANEL: 'tabpanel',
|
||||
|
||||
// ARIA role for a textbox element.
|
||||
TEXTBOX: 'textbox',
|
||||
|
||||
// ARIA role for a textinfo element.
|
||||
TEXTINFO: 'textinfo',
|
||||
|
||||
// ARIA role for an element displaying elapsed time or time remaining.
|
||||
TIMER: 'timer',
|
||||
|
||||
// ARIA role for a toolbar element.
|
||||
TOOLBAR: 'toolbar',
|
||||
|
||||
// ARIA role for a tooltip element.
|
||||
TOOLTIP: 'tooltip',
|
||||
|
||||
// ARIA role for a tree.
|
||||
TREE: 'tree',
|
||||
|
||||
// ARIA role for a grid whose rows can be expanded and collapsed like a tree.
|
||||
TREEGRID: 'treegrid',
|
||||
|
||||
// ARIA role for a tree item that sometimes may be expanded or collapsed.
|
||||
TREEITEM: 'treeitem'
|
||||
};
|
||||
1654
vectortile/closure-library/closure/goog/array/array.js
Normal file
1654
vectortile/closure-library/closure/goog/array/array.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,24 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>
|
||||
Closure Unit Tests - goog.array
|
||||
</title>
|
||||
<script src="../base.js">
|
||||
</script>
|
||||
<script>
|
||||
goog.require('goog.arrayTest');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="foo">
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
1787
vectortile/closure-library/closure/goog/array/array_test.js
Normal file
1787
vectortile/closure-library/closure/goog/array/array_test.js
Normal file
File diff suppressed because it is too large
Load Diff
365
vectortile/closure-library/closure/goog/asserts/asserts.js
Normal file
365
vectortile/closure-library/closure/goog/asserts/asserts.js
Normal file
@@ -0,0 +1,365 @@
|
||||
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utilities to check the preconditions, postconditions and
|
||||
* invariants runtime.
|
||||
*
|
||||
* Methods in this package should be given special treatment by the compiler
|
||||
* for type-inference. For example, <code>goog.asserts.assert(foo)</code>
|
||||
* will restrict <code>foo</code> to a truthy value.
|
||||
*
|
||||
* The compiler has an option to disable asserts. So code like:
|
||||
* <code>
|
||||
* var x = goog.asserts.assert(foo()); goog.asserts.assert(bar());
|
||||
* </code>
|
||||
* will be transformed into:
|
||||
* <code>
|
||||
* var x = foo();
|
||||
* </code>
|
||||
* The compiler will leave in foo() (because its return value is used),
|
||||
* but it will remove bar() because it assumes it does not have side-effects.
|
||||
*
|
||||
* @author agrieve@google.com (Andrew Grieve)
|
||||
*/
|
||||
|
||||
goog.provide('goog.asserts');
|
||||
goog.provide('goog.asserts.AssertionError');
|
||||
|
||||
goog.require('goog.debug.Error');
|
||||
goog.require('goog.dom.NodeType');
|
||||
goog.require('goog.string');
|
||||
|
||||
|
||||
/**
|
||||
* @define {boolean} Whether to strip out asserts or to leave them in.
|
||||
*/
|
||||
goog.define('goog.asserts.ENABLE_ASSERTS', goog.DEBUG);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Error object for failed assertions.
|
||||
* @param {string} messagePattern The pattern that was used to form message.
|
||||
* @param {!Array<*>} messageArgs The items to substitute into the pattern.
|
||||
* @constructor
|
||||
* @extends {goog.debug.Error}
|
||||
* @final
|
||||
*/
|
||||
goog.asserts.AssertionError = function(messagePattern, messageArgs) {
|
||||
messageArgs.unshift(messagePattern);
|
||||
goog.debug.Error.call(this, goog.string.subs.apply(null, messageArgs));
|
||||
// Remove the messagePattern afterwards to avoid permanently modifying the
|
||||
// passed in array.
|
||||
messageArgs.shift();
|
||||
|
||||
/**
|
||||
* The message pattern used to format the error message. Error handlers can
|
||||
* use this to uniquely identify the assertion.
|
||||
* @type {string}
|
||||
*/
|
||||
this.messagePattern = messagePattern;
|
||||
};
|
||||
goog.inherits(goog.asserts.AssertionError, goog.debug.Error);
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.asserts.AssertionError.prototype.name = 'AssertionError';
|
||||
|
||||
|
||||
/**
|
||||
* The default error handler.
|
||||
* @param {!goog.asserts.AssertionError} e The exception to be handled.
|
||||
*/
|
||||
goog.asserts.DEFAULT_ERROR_HANDLER = function(e) { throw e; };
|
||||
|
||||
|
||||
/**
|
||||
* The handler responsible for throwing or logging assertion errors.
|
||||
* @private {function(!goog.asserts.AssertionError)}
|
||||
*/
|
||||
goog.asserts.errorHandler_ = goog.asserts.DEFAULT_ERROR_HANDLER;
|
||||
|
||||
|
||||
/**
|
||||
* Throws an exception with the given message and "Assertion failed" prefixed
|
||||
* onto it.
|
||||
* @param {string} defaultMessage The message to use if givenMessage is empty.
|
||||
* @param {Array<*>} defaultArgs The substitution arguments for defaultMessage.
|
||||
* @param {string|undefined} givenMessage Message supplied by the caller.
|
||||
* @param {Array<*>} givenArgs The substitution arguments for givenMessage.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not a number.
|
||||
* @private
|
||||
*/
|
||||
goog.asserts.doAssertFailure_ =
|
||||
function(defaultMessage, defaultArgs, givenMessage, givenArgs) {
|
||||
var message = 'Assertion failed';
|
||||
if (givenMessage) {
|
||||
message += ': ' + givenMessage;
|
||||
var args = givenArgs;
|
||||
} else if (defaultMessage) {
|
||||
message += ': ' + defaultMessage;
|
||||
args = defaultArgs;
|
||||
}
|
||||
// The '' + works around an Opera 10 bug in the unit tests. Without it,
|
||||
// a stack trace is added to var message above. With this, a stack trace is
|
||||
// not added until this line (it causes the extra garbage to be added after
|
||||
// the assertion message instead of in the middle of it).
|
||||
var e = new goog.asserts.AssertionError('' + message, args || []);
|
||||
goog.asserts.errorHandler_(e);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets a custom error handler that can be used to customize the behavior of
|
||||
* assertion failures, for example by turning all assertion failures into log
|
||||
* messages.
|
||||
* @param {function(!goog.asserts.AssertionError)} errorHandler
|
||||
*/
|
||||
goog.asserts.setErrorHandler = function(errorHandler) {
|
||||
if (goog.asserts.ENABLE_ASSERTS) {
|
||||
goog.asserts.errorHandler_ = errorHandler;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the condition evaluates to true if goog.asserts.ENABLE_ASSERTS is
|
||||
* true.
|
||||
* @template T
|
||||
* @param {T} condition The condition to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {T} The value of the condition.
|
||||
* @throws {goog.asserts.AssertionError} When the condition evaluates to false.
|
||||
*/
|
||||
goog.asserts.assert = function(condition, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !condition) {
|
||||
goog.asserts.doAssertFailure_('', null, opt_message,
|
||||
Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return condition;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fails if goog.asserts.ENABLE_ASSERTS is true. This function is useful in case
|
||||
* when we want to add a check in the unreachable area like switch-case
|
||||
* statement:
|
||||
*
|
||||
* <pre>
|
||||
* switch(type) {
|
||||
* case FOO: doSomething(); break;
|
||||
* case BAR: doSomethingElse(); break;
|
||||
* default: goog.assert.fail('Unrecognized type: ' + type);
|
||||
* // We have only 2 types - "default:" section is unreachable code.
|
||||
* }
|
||||
* </pre>
|
||||
*
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @throws {goog.asserts.AssertionError} Failure.
|
||||
*/
|
||||
goog.asserts.fail = function(opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS) {
|
||||
goog.asserts.errorHandler_(new goog.asserts.AssertionError(
|
||||
'Failure' + (opt_message ? ': ' + opt_message : ''),
|
||||
Array.prototype.slice.call(arguments, 1)));
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is a number if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {number} The value, guaranteed to be a number when asserts enabled.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not a number.
|
||||
*/
|
||||
goog.asserts.assertNumber = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isNumber(value)) {
|
||||
goog.asserts.doAssertFailure_('Expected number but got %s: %s.',
|
||||
[goog.typeOf(value), value], opt_message,
|
||||
Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {number} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is a string if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {string} The value, guaranteed to be a string when asserts enabled.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not a string.
|
||||
*/
|
||||
goog.asserts.assertString = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isString(value)) {
|
||||
goog.asserts.doAssertFailure_('Expected string but got %s: %s.',
|
||||
[goog.typeOf(value), value], opt_message,
|
||||
Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {string} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is a function if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {!Function} The value, guaranteed to be a function when asserts
|
||||
* enabled.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not a function.
|
||||
*/
|
||||
goog.asserts.assertFunction = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isFunction(value)) {
|
||||
goog.asserts.doAssertFailure_('Expected function but got %s: %s.',
|
||||
[goog.typeOf(value), value], opt_message,
|
||||
Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {!Function} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is an Object if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {!Object} The value, guaranteed to be a non-null object.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not an object.
|
||||
*/
|
||||
goog.asserts.assertObject = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isObject(value)) {
|
||||
goog.asserts.doAssertFailure_('Expected object but got %s: %s.',
|
||||
[goog.typeOf(value), value],
|
||||
opt_message, Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {!Object} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is an Array if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {!Array<?>} The value, guaranteed to be a non-null array.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not an array.
|
||||
*/
|
||||
goog.asserts.assertArray = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isArray(value)) {
|
||||
goog.asserts.doAssertFailure_('Expected array but got %s: %s.',
|
||||
[goog.typeOf(value), value], opt_message,
|
||||
Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {!Array<?>} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is a boolean if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {boolean} The value, guaranteed to be a boolean when asserts are
|
||||
* enabled.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not a boolean.
|
||||
*/
|
||||
goog.asserts.assertBoolean = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !goog.isBoolean(value)) {
|
||||
goog.asserts.doAssertFailure_('Expected boolean but got %s: %s.',
|
||||
[goog.typeOf(value), value], opt_message,
|
||||
Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {boolean} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is a DOM Element if goog.asserts.ENABLE_ASSERTS is true.
|
||||
* @param {*} value The value to check.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @return {!Element} The value, likely to be a DOM Element when asserts are
|
||||
* enabled.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not an Element.
|
||||
*/
|
||||
goog.asserts.assertElement = function(value, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && (!goog.isObject(value) ||
|
||||
value.nodeType != goog.dom.NodeType.ELEMENT)) {
|
||||
goog.asserts.doAssertFailure_('Expected Element but got %s: %s.',
|
||||
[goog.typeOf(value), value], opt_message,
|
||||
Array.prototype.slice.call(arguments, 2));
|
||||
}
|
||||
return /** @type {!Element} */ (value);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if the value is an instance of the user-defined type if
|
||||
* goog.asserts.ENABLE_ASSERTS is true.
|
||||
*
|
||||
* The compiler may tighten the type returned by this function.
|
||||
*
|
||||
* @param {*} value The value to check.
|
||||
* @param {function(new: T, ...)} type A user-defined constructor.
|
||||
* @param {string=} opt_message Error message in case of failure.
|
||||
* @param {...*} var_args The items to substitute into the failure message.
|
||||
* @throws {goog.asserts.AssertionError} When the value is not an instance of
|
||||
* type.
|
||||
* @return {T}
|
||||
* @template T
|
||||
*/
|
||||
goog.asserts.assertInstanceof = function(value, type, opt_message, var_args) {
|
||||
if (goog.asserts.ENABLE_ASSERTS && !(value instanceof type)) {
|
||||
goog.asserts.doAssertFailure_('Expected instanceof %s but got %s.',
|
||||
[goog.asserts.getType_(type), goog.asserts.getType_(value)],
|
||||
opt_message, Array.prototype.slice.call(arguments, 3));
|
||||
}
|
||||
return value;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks that no enumerable keys are present in Object.prototype. Such keys
|
||||
* would break most code that use {@code for (var ... in ...)} loops.
|
||||
*/
|
||||
goog.asserts.assertObjectPrototypeIsIntact = function() {
|
||||
for (var key in Object.prototype) {
|
||||
goog.asserts.fail(key + ' should not be enumerable in Object.prototype.');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Returns the type of a value. If a constructor is passed, and a suitable
|
||||
* string cannot be found, 'unknown type name' will be returned.
|
||||
* @param {*} value A constructor, object, or primitive.
|
||||
* @return {string} The best display name for the value, or 'unknown type name'.
|
||||
* @private
|
||||
*/
|
||||
goog.asserts.getType_ = function(value) {
|
||||
if (value instanceof Function) {
|
||||
return value.displayName || value.name || 'unknown type name';
|
||||
} else if (value instanceof Object) {
|
||||
return value.constructor.displayName || value.constructor.name ||
|
||||
Object.prototype.toString.call(value);
|
||||
} else {
|
||||
return value === null ? 'null' : typeof value;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>
|
||||
Closure Unit Tests - goog.asserts.assert
|
||||
</title>
|
||||
<script src="../base.js">
|
||||
</script>
|
||||
<script>
|
||||
goog.require('goog.assertsTest');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
243
vectortile/closure-library/closure/goog/asserts/asserts_test.js
Normal file
243
vectortile/closure-library/closure/goog/asserts/asserts_test.js
Normal file
@@ -0,0 +1,243 @@
|
||||
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.assertsTest');
|
||||
goog.setTestOnly('goog.assertsTest');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.asserts.AssertionError');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.dom.TagName');
|
||||
goog.require('goog.string');
|
||||
goog.require('goog.testing.jsunit');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
function doTestMessage(failFunc, expectedMsg) {
|
||||
var error = assertThrows('failFunc should throw.', failFunc);
|
||||
// Test error message.
|
||||
// Opera 10 adds cruft to the end of the message, so do a startsWith check.
|
||||
assertTrue('Message check failed. Expected: ' + expectedMsg + ' Actual: ' +
|
||||
error.message, goog.string.startsWith(error.message, expectedMsg));
|
||||
}
|
||||
|
||||
function testAssert() {
|
||||
// None of them may throw exception
|
||||
goog.asserts.assert(true);
|
||||
goog.asserts.assert(1);
|
||||
goog.asserts.assert([]);
|
||||
goog.asserts.assert({});
|
||||
|
||||
assertThrows('assert(false)', goog.partial(goog.asserts.assert, false));
|
||||
assertThrows('assert(0)', goog.partial(goog.asserts.assert, 0));
|
||||
assertThrows('assert(null)', goog.partial(goog.asserts.assert, null));
|
||||
assertThrows('assert(undefined)',
|
||||
goog.partial(goog.asserts.assert, undefined));
|
||||
|
||||
// Test error messages.
|
||||
doTestMessage(goog.partial(goog.asserts.assert, false), 'Assertion failed');
|
||||
doTestMessage(goog.partial(goog.asserts.assert, false, 'ouch %s', 1),
|
||||
'Assertion failed: ouch 1');
|
||||
}
|
||||
|
||||
|
||||
function testFail() {
|
||||
assertThrows('fail()', goog.asserts.fail);
|
||||
// Test error messages.
|
||||
doTestMessage(goog.partial(goog.asserts.fail, false), 'Failure');
|
||||
doTestMessage(goog.partial(goog.asserts.fail, 'ouch %s', 1),
|
||||
'Failure: ouch 1');
|
||||
}
|
||||
|
||||
function testNumber() {
|
||||
goog.asserts.assertNumber(1);
|
||||
assertThrows('assertNumber(null)',
|
||||
goog.partial(goog.asserts.assertNumber, null));
|
||||
// Test error messages.
|
||||
doTestMessage(goog.partial(goog.asserts.assertNumber, null),
|
||||
'Assertion failed: Expected number but got null: null.');
|
||||
doTestMessage(goog.partial(goog.asserts.assertNumber, '1234'),
|
||||
'Assertion failed: Expected number but got string: 1234.');
|
||||
doTestMessage(goog.partial(goog.asserts.assertNumber, null, 'ouch %s', 1),
|
||||
'Assertion failed: ouch 1');
|
||||
}
|
||||
|
||||
function testString() {
|
||||
assertEquals('1', goog.asserts.assertString('1'));
|
||||
assertThrows('assertString(null)',
|
||||
goog.partial(goog.asserts.assertString, null));
|
||||
// Test error messages.
|
||||
doTestMessage(goog.partial(goog.asserts.assertString, null),
|
||||
'Assertion failed: Expected string but got null: null.');
|
||||
doTestMessage(goog.partial(goog.asserts.assertString, 1234),
|
||||
'Assertion failed: Expected string but got number: 1234.');
|
||||
doTestMessage(goog.partial(goog.asserts.assertString, null, 'ouch %s', 1),
|
||||
'Assertion failed: ouch 1');
|
||||
}
|
||||
|
||||
function testFunction() {
|
||||
function f() {};
|
||||
assertEquals(f, goog.asserts.assertFunction(f));
|
||||
assertThrows('assertFunction(null)',
|
||||
goog.partial(goog.asserts.assertFunction, null));
|
||||
// Test error messages.
|
||||
doTestMessage(goog.partial(goog.asserts.assertFunction, null),
|
||||
'Assertion failed: Expected function but got null: null.');
|
||||
doTestMessage(goog.partial(goog.asserts.assertFunction, 1234),
|
||||
'Assertion failed: Expected function but got number: 1234.');
|
||||
doTestMessage(goog.partial(goog.asserts.assertFunction, null, 'ouch %s', 1),
|
||||
'Assertion failed: ouch 1');
|
||||
}
|
||||
|
||||
function testObject() {
|
||||
var o = {};
|
||||
assertEquals(o, goog.asserts.assertObject(o));
|
||||
assertThrows('assertObject(null)',
|
||||
goog.partial(goog.asserts.assertObject, null));
|
||||
// Test error messages.
|
||||
doTestMessage(goog.partial(goog.asserts.assertObject, null),
|
||||
'Assertion failed: Expected object but got null: null.');
|
||||
doTestMessage(goog.partial(goog.asserts.assertObject, 1234),
|
||||
'Assertion failed: Expected object but got number: 1234.');
|
||||
doTestMessage(goog.partial(goog.asserts.assertObject, null, 'ouch %s', 1),
|
||||
'Assertion failed: ouch 1');
|
||||
}
|
||||
|
||||
function testArray() {
|
||||
var a = [];
|
||||
assertEquals(a, goog.asserts.assertArray(a));
|
||||
assertThrows('assertArray({})',
|
||||
goog.partial(goog.asserts.assertArray, {}));
|
||||
// Test error messages.
|
||||
doTestMessage(goog.partial(goog.asserts.assertArray, null),
|
||||
'Assertion failed: Expected array but got null: null.');
|
||||
doTestMessage(goog.partial(goog.asserts.assertArray, 1234),
|
||||
'Assertion failed: Expected array but got number: 1234.');
|
||||
doTestMessage(goog.partial(goog.asserts.assertArray, null, 'ouch %s', 1),
|
||||
'Assertion failed: ouch 1');
|
||||
}
|
||||
|
||||
function testBoolean() {
|
||||
assertEquals(true, goog.asserts.assertBoolean(true));
|
||||
assertEquals(false, goog.asserts.assertBoolean(false));
|
||||
assertThrows(goog.partial(goog.asserts.assertBoolean, null));
|
||||
assertThrows(goog.partial(goog.asserts.assertBoolean, 'foo'));
|
||||
|
||||
// Test error messages.
|
||||
doTestMessage(goog.partial(goog.asserts.assertBoolean, null),
|
||||
'Assertion failed: Expected boolean but got null: null.');
|
||||
doTestMessage(goog.partial(goog.asserts.assertBoolean, 1234),
|
||||
'Assertion failed: Expected boolean but got number: 1234.');
|
||||
doTestMessage(goog.partial(goog.asserts.assertBoolean, null, 'ouch %s', 1),
|
||||
'Assertion failed: ouch 1');
|
||||
}
|
||||
|
||||
function testElement() {
|
||||
assertThrows(goog.partial(goog.asserts.assertElement, null));
|
||||
assertThrows(goog.partial(goog.asserts.assertElement, 'foo'));
|
||||
assertThrows(goog.partial(goog.asserts.assertElement,
|
||||
goog.dom.createTextNode('foo')));
|
||||
var elem = goog.dom.createElement(goog.dom.TagName.DIV);
|
||||
assertEquals(elem, goog.asserts.assertElement(elem));
|
||||
}
|
||||
|
||||
function testInstanceof() {
|
||||
/** @constructor */
|
||||
var F = function() {};
|
||||
goog.asserts.assertInstanceof(new F(), F);
|
||||
assertThrows('assertInstanceof({}, F)',
|
||||
goog.partial(goog.asserts.assertInstanceof, {}, F));
|
||||
// IE lacks support for function.name and will fallback to toString().
|
||||
var object = goog.userAgent.IE ? '[object Object]' : 'Object';
|
||||
|
||||
// Test error messages.
|
||||
doTestMessage(goog.partial(goog.asserts.assertInstanceof, {}, F),
|
||||
'Assertion failed: Expected instanceof unknown type name but got ' +
|
||||
object + '.');
|
||||
doTestMessage(goog.partial(goog.asserts.assertInstanceof, {}, F, 'a %s', 1),
|
||||
'Assertion failed: a 1');
|
||||
doTestMessage(goog.partial(goog.asserts.assertInstanceof, null, F),
|
||||
'Assertion failed: Expected instanceof unknown type name but got null.');
|
||||
doTestMessage(goog.partial(goog.asserts.assertInstanceof, 5, F),
|
||||
'Assertion failed: ' +
|
||||
'Expected instanceof unknown type name but got number.');
|
||||
|
||||
// Test a constructor a with a name (IE does not support function.name).
|
||||
if (!goog.userAgent.IE) {
|
||||
F = function foo() {};
|
||||
doTestMessage(goog.partial(goog.asserts.assertInstanceof, {}, F),
|
||||
'Assertion failed: Expected instanceof foo but got ' + object + '.');
|
||||
}
|
||||
|
||||
// Test a constructor with a displayName.
|
||||
F.displayName = 'bar';
|
||||
doTestMessage(goog.partial(goog.asserts.assertInstanceof, {}, F),
|
||||
'Assertion failed: Expected instanceof bar but got ' + object + '.');
|
||||
}
|
||||
|
||||
function testObjectPrototypeIsIntact() {
|
||||
goog.asserts.assertObjectPrototypeIsIntact();
|
||||
var originalToString = Object.prototype.toString;
|
||||
Object.prototype.toString = goog.nullFunction;
|
||||
try {
|
||||
goog.asserts.assertObjectPrototypeIsIntact();
|
||||
Object.prototype.foo = 1;
|
||||
doTestMessage(goog.asserts.assertObjectPrototypeIsIntact,
|
||||
'Failure: foo should not be enumerable in Object.prototype.');
|
||||
} finally {
|
||||
Object.prototype.toString = originalToString;
|
||||
delete Object.prototype.foo;
|
||||
}
|
||||
}
|
||||
|
||||
function testAssertionError() {
|
||||
var error = new goog.asserts.AssertionError('foo %s %s', [1, 'two']);
|
||||
assertEquals('Wrong message', 'foo 1 two', error.message);
|
||||
assertEquals('Wrong messagePattern', 'foo %s %s', error.messagePattern);
|
||||
}
|
||||
|
||||
function testFailWithCustomErrorHandler() {
|
||||
try {
|
||||
var handledException;
|
||||
goog.asserts.setErrorHandler(
|
||||
function(e) { handledException = e; });
|
||||
|
||||
var expectedMessage = 'Failure: Gevalt!';
|
||||
|
||||
goog.asserts.fail('Gevalt!');
|
||||
assertTrue('handledException is null.', handledException != null);
|
||||
assertTrue('Message check failed. Expected: ' + expectedMessage +
|
||||
' Actual: ' + handledException.message,
|
||||
goog.string.startsWith(expectedMessage, handledException.message));
|
||||
} finally {
|
||||
goog.asserts.setErrorHandler(goog.asserts.DEFAULT_ERROR_HANDLER);
|
||||
}
|
||||
}
|
||||
|
||||
function testAssertWithCustomErrorHandler() {
|
||||
try {
|
||||
var handledException;
|
||||
goog.asserts.setErrorHandler(
|
||||
function(e) { handledException = e; });
|
||||
|
||||
var expectedMessage = 'Assertion failed: Gevalt!';
|
||||
|
||||
goog.asserts.assert(false, 'Gevalt!');
|
||||
assertTrue('handledException is null.', handledException != null);
|
||||
assertTrue('Message check failed. Expected: ' + expectedMessage +
|
||||
' Actual: ' + handledException.message,
|
||||
goog.string.startsWith(expectedMessage, handledException.message));
|
||||
} finally {
|
||||
goog.asserts.setErrorHandler(goog.asserts.DEFAULT_ERROR_HANDLER);
|
||||
}
|
||||
}
|
||||
267
vectortile/closure-library/closure/goog/async/animationdelay.js
Normal file
267
vectortile/closure-library/closure/goog/async/animationdelay.js
Normal file
@@ -0,0 +1,267 @@
|
||||
// Copyright 2012 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview A delayed callback that pegs to the next animation frame
|
||||
* instead of a user-configurable timeout.
|
||||
*
|
||||
* @author nicksantos@google.com (Nick Santos)
|
||||
*/
|
||||
|
||||
goog.provide('goog.async.AnimationDelay');
|
||||
|
||||
goog.require('goog.Disposable');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.functions');
|
||||
|
||||
|
||||
|
||||
// TODO(nicksantos): Should we factor out the common code between this and
|
||||
// goog.async.Delay? I'm not sure if there's enough code for this to really
|
||||
// make sense. Subclassing seems like the wrong approach for a variety of
|
||||
// reasons. Maybe there should be a common interface?
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A delayed callback that pegs to the next animation frame
|
||||
* instead of a user configurable timeout. By design, this should have
|
||||
* the same interface as goog.async.Delay.
|
||||
*
|
||||
* Uses requestAnimationFrame and friends when available, but falls
|
||||
* back to a timeout of goog.async.AnimationDelay.TIMEOUT.
|
||||
*
|
||||
* For more on requestAnimationFrame and how you can use it to create smoother
|
||||
* animations, see:
|
||||
* @see http://paulirish.com/2011/requestanimationframe-for-smart-animating/
|
||||
*
|
||||
* @param {function(number)} listener Function to call when the delay completes.
|
||||
* Will be passed the timestamp when it's called, in unix ms.
|
||||
* @param {Window=} opt_window The window object to execute the delay in.
|
||||
* Defaults to the global object.
|
||||
* @param {Object=} opt_handler The object scope to invoke the function in.
|
||||
* @constructor
|
||||
* @struct
|
||||
* @suppress {checkStructDictInheritance}
|
||||
* @extends {goog.Disposable}
|
||||
* @final
|
||||
*/
|
||||
goog.async.AnimationDelay = function(listener, opt_window, opt_handler) {
|
||||
goog.async.AnimationDelay.base(this, 'constructor');
|
||||
|
||||
/**
|
||||
* Identifier of the active delay timeout, or event listener,
|
||||
* or null when inactive.
|
||||
* @private {goog.events.Key|number}
|
||||
*/
|
||||
this.id_ = null;
|
||||
|
||||
/**
|
||||
* If we're using dom listeners.
|
||||
* @private {?boolean}
|
||||
*/
|
||||
this.usingListeners_ = false;
|
||||
|
||||
/**
|
||||
* The function that will be invoked after a delay.
|
||||
* @private {function(number)}
|
||||
*/
|
||||
this.listener_ = listener;
|
||||
|
||||
/**
|
||||
* The object context to invoke the callback in.
|
||||
* @private {Object|undefined}
|
||||
*/
|
||||
this.handler_ = opt_handler;
|
||||
|
||||
/**
|
||||
* @private {Window}
|
||||
*/
|
||||
this.win_ = opt_window || window;
|
||||
|
||||
/**
|
||||
* Cached callback function invoked when the delay finishes.
|
||||
* @private {function()}
|
||||
*/
|
||||
this.callback_ = goog.bind(this.doAction_, this);
|
||||
};
|
||||
goog.inherits(goog.async.AnimationDelay, goog.Disposable);
|
||||
|
||||
|
||||
/**
|
||||
* Default wait timeout for animations (in milliseconds). Only used for timed
|
||||
* animation, which uses a timer (setTimeout) to schedule animation.
|
||||
*
|
||||
* @type {number}
|
||||
* @const
|
||||
*/
|
||||
goog.async.AnimationDelay.TIMEOUT = 20;
|
||||
|
||||
|
||||
/**
|
||||
* Name of event received from the requestAnimationFrame in Firefox.
|
||||
*
|
||||
* @type {string}
|
||||
* @const
|
||||
* @private
|
||||
*/
|
||||
goog.async.AnimationDelay.MOZ_BEFORE_PAINT_EVENT_ = 'MozBeforePaint';
|
||||
|
||||
|
||||
/**
|
||||
* Starts the delay timer. The provided listener function will be called
|
||||
* before the next animation frame.
|
||||
*/
|
||||
goog.async.AnimationDelay.prototype.start = function() {
|
||||
this.stop();
|
||||
this.usingListeners_ = false;
|
||||
|
||||
var raf = this.getRaf_();
|
||||
var cancelRaf = this.getCancelRaf_();
|
||||
if (raf && !cancelRaf && this.win_.mozRequestAnimationFrame) {
|
||||
// Because Firefox (Gecko) runs animation in separate threads, it also saves
|
||||
// time by running the requestAnimationFrame callbacks in that same thread.
|
||||
// Sadly this breaks the assumption of implicit thread-safety in JS, and can
|
||||
// thus create thread-based inconsistencies on counters etc.
|
||||
//
|
||||
// Calling cycleAnimations_ using the MozBeforePaint event instead of as
|
||||
// callback fixes this.
|
||||
//
|
||||
// Trigger this condition only if the mozRequestAnimationFrame is available,
|
||||
// but not the W3C requestAnimationFrame function (as in draft) or the
|
||||
// equivalent cancel functions.
|
||||
this.id_ = goog.events.listen(
|
||||
this.win_,
|
||||
goog.async.AnimationDelay.MOZ_BEFORE_PAINT_EVENT_,
|
||||
this.callback_);
|
||||
this.win_.mozRequestAnimationFrame(null);
|
||||
this.usingListeners_ = true;
|
||||
} else if (raf && cancelRaf) {
|
||||
this.id_ = raf.call(this.win_, this.callback_);
|
||||
} else {
|
||||
this.id_ = this.win_.setTimeout(
|
||||
// Prior to Firefox 13, Gecko passed a non-standard parameter
|
||||
// to the callback that we want to ignore.
|
||||
goog.functions.lock(this.callback_),
|
||||
goog.async.AnimationDelay.TIMEOUT);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Stops the delay timer if it is active. No action is taken if the timer is not
|
||||
* in use.
|
||||
*/
|
||||
goog.async.AnimationDelay.prototype.stop = function() {
|
||||
if (this.isActive()) {
|
||||
var raf = this.getRaf_();
|
||||
var cancelRaf = this.getCancelRaf_();
|
||||
if (raf && !cancelRaf && this.win_.mozRequestAnimationFrame) {
|
||||
goog.events.unlistenByKey(this.id_);
|
||||
} else if (raf && cancelRaf) {
|
||||
cancelRaf.call(this.win_, /** @type {number} */ (this.id_));
|
||||
} else {
|
||||
this.win_.clearTimeout(/** @type {number} */ (this.id_));
|
||||
}
|
||||
}
|
||||
this.id_ = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fires delay's action even if timer has already gone off or has not been
|
||||
* started yet; guarantees action firing. Stops the delay timer.
|
||||
*/
|
||||
goog.async.AnimationDelay.prototype.fire = function() {
|
||||
this.stop();
|
||||
this.doAction_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fires delay's action only if timer is currently active. Stops the delay
|
||||
* timer.
|
||||
*/
|
||||
goog.async.AnimationDelay.prototype.fireIfActive = function() {
|
||||
if (this.isActive()) {
|
||||
this.fire();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} True if the delay is currently active, false otherwise.
|
||||
*/
|
||||
goog.async.AnimationDelay.prototype.isActive = function() {
|
||||
return this.id_ != null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Invokes the callback function after the delay successfully completes.
|
||||
* @private
|
||||
*/
|
||||
goog.async.AnimationDelay.prototype.doAction_ = function() {
|
||||
if (this.usingListeners_ && this.id_) {
|
||||
goog.events.unlistenByKey(this.id_);
|
||||
}
|
||||
this.id_ = null;
|
||||
|
||||
// We are not using the timestamp returned by requestAnimationFrame
|
||||
// because it may be either a Date.now-style time or a
|
||||
// high-resolution time (depending on browser implementation). Using
|
||||
// goog.now() will ensure that the timestamp used is consistent and
|
||||
// compatible with goog.fx.Animation.
|
||||
this.listener_.call(this.handler_, goog.now());
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.async.AnimationDelay.prototype.disposeInternal = function() {
|
||||
this.stop();
|
||||
goog.async.AnimationDelay.base(this, 'disposeInternal');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {?function(function(number)): number} The requestAnimationFrame
|
||||
* function, or null if not available on this browser.
|
||||
* @private
|
||||
*/
|
||||
goog.async.AnimationDelay.prototype.getRaf_ = function() {
|
||||
var win = this.win_;
|
||||
return win.requestAnimationFrame ||
|
||||
win.webkitRequestAnimationFrame ||
|
||||
win.mozRequestAnimationFrame ||
|
||||
win.oRequestAnimationFrame ||
|
||||
win.msRequestAnimationFrame ||
|
||||
null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {?function(number): number} The cancelAnimationFrame function,
|
||||
* or null if not available on this browser.
|
||||
* @private
|
||||
*/
|
||||
goog.async.AnimationDelay.prototype.getCancelRaf_ = function() {
|
||||
var win = this.win_;
|
||||
return win.cancelAnimationFrame ||
|
||||
win.cancelRequestAnimationFrame ||
|
||||
win.webkitCancelRequestAnimationFrame ||
|
||||
win.mozCancelRequestAnimationFrame ||
|
||||
win.oCancelRequestAnimationFrame ||
|
||||
win.msCancelRequestAnimationFrame ||
|
||||
null;
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2012 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
|
||||
Author: nicksantos@google.com (Nick Santos)
|
||||
-->
|
||||
<head>
|
||||
<title>
|
||||
JsUnit tests for goog.async.AnimationDelay
|
||||
</title>
|
||||
<script src="../base.js">
|
||||
</script>
|
||||
<script>
|
||||
goog.require('goog.async.AnimationDelayTest');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright 2012 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.module('goog.async.AnimationDelayTest');
|
||||
goog.setTestOnly('goog.async.AnimationDelayTest');
|
||||
|
||||
goog.require('goog.Timer');
|
||||
goog.require('goog.async.AnimationDelay');
|
||||
goog.require('goog.testing.PropertyReplacer');
|
||||
goog.require('goog.testing.jsunit');
|
||||
goog.require('goog.testing.recordFunction');
|
||||
|
||||
var testSuite = goog.require('goog.testing.testSuite');
|
||||
|
||||
var TEST_DELAY = 20;
|
||||
var stubs = new goog.testing.PropertyReplacer();
|
||||
|
||||
testSuite({
|
||||
tearDown: function() {
|
||||
stubs.reset();
|
||||
},
|
||||
|
||||
testStart: function() {
|
||||
var callCount = 0;
|
||||
var start = goog.now();
|
||||
var delay = new goog.async.AnimationDelay(function(end) {
|
||||
callCount++;
|
||||
});
|
||||
|
||||
delay.start();
|
||||
|
||||
return goog.Timer.promise(TEST_DELAY).then(function() {
|
||||
assertEquals(1, callCount);
|
||||
});
|
||||
},
|
||||
|
||||
testStop: function() {
|
||||
var callCount = 0;
|
||||
var start = goog.now();
|
||||
var delay = new goog.async.AnimationDelay(function(end) {
|
||||
callCount++;
|
||||
});
|
||||
|
||||
delay.start();
|
||||
delay.stop();
|
||||
|
||||
return goog.Timer.promise(TEST_DELAY).then(function() {
|
||||
assertEquals(0, callCount);
|
||||
});
|
||||
},
|
||||
|
||||
testAlwaysUseGoogNowForHandlerTimestamp: function() {
|
||||
var expectedValue = 12345.1;
|
||||
stubs.set(goog, 'now', function() {
|
||||
return expectedValue;
|
||||
});
|
||||
|
||||
var handler = goog.testing.recordFunction(function(timestamp) {
|
||||
assertEquals(expectedValue, timestamp);
|
||||
});
|
||||
var delay = new goog.async.AnimationDelay(handler);
|
||||
|
||||
delay.start();
|
||||
|
||||
return goog.Timer.promise(TEST_DELAY).then(function() {
|
||||
assertEquals(1, handler.getCallCount());
|
||||
});
|
||||
}
|
||||
});
|
||||
@@ -0,0 +1,228 @@
|
||||
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Defines a class useful for handling functions that must be
|
||||
* invoked later when some condition holds. Examples include deferred function
|
||||
* calls that return a boolean flag whether it succedeed or not.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* function deferred() {
|
||||
* var succeeded = false;
|
||||
* // ... custom code
|
||||
* return succeeded;
|
||||
* }
|
||||
*
|
||||
* var deferredCall = new goog.async.ConditionalDelay(deferred);
|
||||
* deferredCall.onSuccess = function() {
|
||||
* alert('Success: The deferred function has been successfully executed.');
|
||||
* }
|
||||
* deferredCall.onFailure = function() {
|
||||
* alert('Failure: Time limit exceeded.');
|
||||
* }
|
||||
*
|
||||
* // Call the deferred() every 100 msec until it returns true,
|
||||
* // or 5 seconds pass.
|
||||
* deferredCall.start(100, 5000);
|
||||
*
|
||||
* // Stop the deferred function call (does nothing if it's not active).
|
||||
* deferredCall.stop();
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.async.ConditionalDelay');
|
||||
|
||||
goog.require('goog.Disposable');
|
||||
goog.require('goog.async.Delay');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A ConditionalDelay object invokes the associated function after a specified
|
||||
* interval delay and checks its return value. If the function returns
|
||||
* {@code true} the conditional delay is cancelled and {@see #onSuccess}
|
||||
* is called. Otherwise this object keeps to invoke the deferred function until
|
||||
* either it returns {@code true} or the timeout is exceeded. In the latter case
|
||||
* the {@see #onFailure} method will be called.
|
||||
*
|
||||
* The interval duration and timeout can be specified each time the delay is
|
||||
* started. Calling start on an active delay will reset the timer.
|
||||
*
|
||||
* @param {function():boolean} listener Function to call when the delay
|
||||
* completes. Should return a value that type-converts to {@code true} if
|
||||
* the call succeeded and this delay should be stopped.
|
||||
* @param {Object=} opt_handler The object scope to invoke the function in.
|
||||
* @constructor
|
||||
* @struct
|
||||
* @suppress {checkStructDictInheritance}
|
||||
* @extends {goog.Disposable}
|
||||
*/
|
||||
goog.async.ConditionalDelay = function(listener, opt_handler) {
|
||||
goog.async.ConditionalDelay.base(this, 'constructor');
|
||||
|
||||
/**
|
||||
* The delay interval in milliseconds to between the calls to the callback.
|
||||
* Note, that the callback may be invoked earlier than this interval if the
|
||||
* timeout is exceeded.
|
||||
* @private {number}
|
||||
*/
|
||||
this.interval_ = 0;
|
||||
|
||||
/**
|
||||
* The timeout timestamp until which the delay is to be executed.
|
||||
* A negative value means no timeout.
|
||||
* @private {number}
|
||||
*/
|
||||
this.runUntil_ = 0;
|
||||
|
||||
/**
|
||||
* True if the listener has been executed, and it returned {@code true}.
|
||||
* @private {boolean}
|
||||
*/
|
||||
this.isDone_ = false;
|
||||
|
||||
/**
|
||||
* The function that will be invoked after a delay.
|
||||
* @private {function():boolean}
|
||||
*/
|
||||
this.listener_ = listener;
|
||||
|
||||
/**
|
||||
* The object context to invoke the callback in.
|
||||
* @private {Object|undefined}
|
||||
*/
|
||||
this.handler_ = opt_handler;
|
||||
|
||||
/**
|
||||
* The underlying goog.async.Delay delegate object.
|
||||
* @private {goog.async.Delay}
|
||||
*/
|
||||
this.delay_ = new goog.async.Delay(
|
||||
goog.bind(this.onTick_, this), 0 /*interval*/, this /*scope*/);
|
||||
};
|
||||
goog.inherits(goog.async.ConditionalDelay, goog.Disposable);
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.async.ConditionalDelay.prototype.disposeInternal = function() {
|
||||
this.delay_.dispose();
|
||||
delete this.listener_;
|
||||
delete this.handler_;
|
||||
goog.async.ConditionalDelay.superClass_.disposeInternal.call(this);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Starts the delay timer. The provided listener function will be called
|
||||
* repeatedly after the specified interval until the function returns
|
||||
* {@code true} or the timeout is exceeded. Calling start on an active timer
|
||||
* will stop the timer first.
|
||||
* @param {number=} opt_interval The time interval between the function
|
||||
* invocations (in milliseconds). Default is 0.
|
||||
* @param {number=} opt_timeout The timeout interval (in milliseconds). Takes
|
||||
* precedence over the {@code opt_interval}, i.e. if the timeout is less
|
||||
* than the invocation interval, the function will be called when the
|
||||
* timeout is exceeded. A negative value means no timeout. Default is 0.
|
||||
*/
|
||||
goog.async.ConditionalDelay.prototype.start = function(opt_interval,
|
||||
opt_timeout) {
|
||||
this.stop();
|
||||
this.isDone_ = false;
|
||||
|
||||
var timeout = opt_timeout || 0;
|
||||
this.interval_ = Math.max(opt_interval || 0, 0);
|
||||
this.runUntil_ = timeout < 0 ? -1 : (goog.now() + timeout);
|
||||
this.delay_.start(
|
||||
timeout < 0 ? this.interval_ : Math.min(this.interval_, timeout));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Stops the delay timer if it is active. No action is taken if the timer is not
|
||||
* in use.
|
||||
*/
|
||||
goog.async.ConditionalDelay.prototype.stop = function() {
|
||||
this.delay_.stop();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} True if the delay is currently active, false otherwise.
|
||||
*/
|
||||
goog.async.ConditionalDelay.prototype.isActive = function() {
|
||||
return this.delay_.isActive();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} True if the listener has been executed and returned
|
||||
* {@code true} since the last call to {@see #start}.
|
||||
*/
|
||||
goog.async.ConditionalDelay.prototype.isDone = function() {
|
||||
return this.isDone_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called when the listener has been successfully executed and returned
|
||||
* {@code true}. The {@see #isDone} method should return {@code true} by now.
|
||||
* Designed for inheritance, should be overridden by subclasses or on the
|
||||
* instances if they care.
|
||||
*/
|
||||
goog.async.ConditionalDelay.prototype.onSuccess = function() {
|
||||
// Do nothing by default.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Called when this delayed call is cancelled because the timeout has been
|
||||
* exceeded, and the listener has never returned {@code true}.
|
||||
* Designed for inheritance, should be overridden by subclasses or on the
|
||||
* instances if they care.
|
||||
*/
|
||||
goog.async.ConditionalDelay.prototype.onFailure = function() {
|
||||
// Do nothing by default.
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A callback function for the underlying {@code goog.async.Delay} object. When
|
||||
* executed the listener function is called, and if it returns {@code true}
|
||||
* the delay is stopped and the {@see #onSuccess} method is invoked.
|
||||
* If the timeout is exceeded the delay is stopped and the
|
||||
* {@see #onFailure} method is called.
|
||||
* @private
|
||||
*/
|
||||
goog.async.ConditionalDelay.prototype.onTick_ = function() {
|
||||
var successful = this.listener_.call(this.handler_);
|
||||
if (successful) {
|
||||
this.isDone_ = true;
|
||||
this.onSuccess();
|
||||
} else {
|
||||
// Try to reschedule the task.
|
||||
if (this.runUntil_ < 0) {
|
||||
// No timeout.
|
||||
this.delay_.start(this.interval_);
|
||||
} else {
|
||||
var timeLeft = this.runUntil_ - goog.now();
|
||||
if (timeLeft <= 0) {
|
||||
this.onFailure();
|
||||
} else {
|
||||
this.delay_.start(Math.min(this.interval_, timeLeft));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>
|
||||
Closure Unit Tests - goog.async.ConditionalDelay
|
||||
</title>
|
||||
<script src="../base.js">
|
||||
</script>
|
||||
<script>
|
||||
goog.require('goog.async.ConditionalDelayTest');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,222 @@
|
||||
// Copyright 2008 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
goog.provide('goog.async.ConditionalDelayTest');
|
||||
goog.setTestOnly('goog.async.ConditionalDelayTest');
|
||||
|
||||
goog.require('goog.async.ConditionalDelay');
|
||||
goog.require('goog.testing.MockClock');
|
||||
goog.require('goog.testing.jsunit');
|
||||
|
||||
var invoked = false;
|
||||
var delay = null;
|
||||
var clock = null;
|
||||
var returnValue = true;
|
||||
var onSuccessCalled = false;
|
||||
var onFailureCalled = false;
|
||||
|
||||
|
||||
function callback() {
|
||||
invoked = true;
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
|
||||
function setUp() {
|
||||
clock = new goog.testing.MockClock(true);
|
||||
invoked = false;
|
||||
returnValue = true;
|
||||
onSuccessCalled = false;
|
||||
onFailureCalled = false;
|
||||
delay = new goog.async.ConditionalDelay(callback);
|
||||
delay.onSuccess = function() {
|
||||
onSuccessCalled = true;
|
||||
};
|
||||
delay.onFailure = function() {
|
||||
onFailureCalled = true;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function tearDown() {
|
||||
clock.dispose();
|
||||
delay.dispose();
|
||||
}
|
||||
|
||||
|
||||
function testDelay() {
|
||||
delay.start(200, 200);
|
||||
assertFalse(invoked);
|
||||
|
||||
clock.tick(100);
|
||||
assertFalse(invoked);
|
||||
|
||||
clock.tick(100);
|
||||
assertTrue(invoked);
|
||||
}
|
||||
|
||||
|
||||
function testStop() {
|
||||
delay.start(200, 500);
|
||||
assertTrue(delay.isActive());
|
||||
|
||||
clock.tick(100);
|
||||
assertFalse(invoked);
|
||||
|
||||
delay.stop();
|
||||
clock.tick(100);
|
||||
assertFalse(invoked);
|
||||
|
||||
assertFalse(delay.isActive());
|
||||
}
|
||||
|
||||
|
||||
function testIsActive() {
|
||||
assertFalse(delay.isActive());
|
||||
delay.start(200, 200);
|
||||
assertTrue(delay.isActive());
|
||||
clock.tick(200);
|
||||
assertFalse(delay.isActive());
|
||||
}
|
||||
|
||||
|
||||
function testRestart() {
|
||||
delay.start(200, 50000);
|
||||
clock.tick(100);
|
||||
|
||||
delay.stop();
|
||||
assertFalse(invoked);
|
||||
|
||||
delay.start(200, 50000);
|
||||
clock.tick(199);
|
||||
assertFalse(invoked);
|
||||
|
||||
clock.tick(1);
|
||||
assertTrue(invoked);
|
||||
|
||||
invoked = false;
|
||||
delay.start(200, 200);
|
||||
clock.tick(200);
|
||||
assertTrue(invoked);
|
||||
|
||||
assertFalse(delay.isActive());
|
||||
}
|
||||
|
||||
|
||||
function testDispose() {
|
||||
delay.start(200, 200);
|
||||
delay.dispose();
|
||||
assertTrue(delay.isDisposed());
|
||||
|
||||
clock.tick(500);
|
||||
assertFalse(invoked);
|
||||
}
|
||||
|
||||
|
||||
function testConditionalDelay_Success() {
|
||||
returnValue = false;
|
||||
delay.start(100, 300);
|
||||
|
||||
clock.tick(99);
|
||||
assertFalse(invoked);
|
||||
clock.tick(1);
|
||||
assertTrue(invoked);
|
||||
|
||||
assertTrue(delay.isActive());
|
||||
assertFalse(delay.isDone());
|
||||
assertFalse(onSuccessCalled);
|
||||
assertFalse(onFailureCalled);
|
||||
|
||||
returnValue = true;
|
||||
|
||||
invoked = false;
|
||||
clock.tick(100);
|
||||
assertTrue(invoked);
|
||||
|
||||
assertFalse(delay.isActive());
|
||||
assertTrue(delay.isDone());
|
||||
assertTrue(onSuccessCalled);
|
||||
assertFalse(onFailureCalled);
|
||||
|
||||
invoked = false;
|
||||
clock.tick(200);
|
||||
assertFalse(invoked);
|
||||
}
|
||||
|
||||
|
||||
function testConditionalDelay_Failure() {
|
||||
returnValue = false;
|
||||
delay.start(100, 300);
|
||||
|
||||
clock.tick(99);
|
||||
assertFalse(invoked);
|
||||
clock.tick(1);
|
||||
assertTrue(invoked);
|
||||
|
||||
assertTrue(delay.isActive());
|
||||
assertFalse(delay.isDone());
|
||||
assertFalse(onSuccessCalled);
|
||||
assertFalse(onFailureCalled);
|
||||
|
||||
invoked = false;
|
||||
clock.tick(100);
|
||||
assertTrue(invoked);
|
||||
assertFalse(onSuccessCalled);
|
||||
assertFalse(onFailureCalled);
|
||||
|
||||
invoked = false;
|
||||
clock.tick(90);
|
||||
assertFalse(invoked);
|
||||
clock.tick(10);
|
||||
assertTrue(invoked);
|
||||
|
||||
assertFalse(delay.isActive());
|
||||
assertFalse(delay.isDone());
|
||||
assertFalse(onSuccessCalled);
|
||||
assertTrue(onFailureCalled);
|
||||
}
|
||||
|
||||
|
||||
function testInfiniteDelay() {
|
||||
returnValue = false;
|
||||
delay.start(100, -1);
|
||||
|
||||
// Test in a big enough loop.
|
||||
for (var i = 0; i < 1000; ++i) {
|
||||
clock.tick(80);
|
||||
assertTrue(delay.isActive());
|
||||
assertFalse(delay.isDone());
|
||||
assertFalse(onSuccessCalled);
|
||||
assertFalse(onFailureCalled);
|
||||
}
|
||||
|
||||
delay.stop();
|
||||
assertFalse(delay.isActive());
|
||||
assertFalse(delay.isDone());
|
||||
assertFalse(onSuccessCalled);
|
||||
assertFalse(onFailureCalled);
|
||||
}
|
||||
|
||||
function testCallbackScope() {
|
||||
var callbackCalled = false;
|
||||
var scopeObject = {};
|
||||
function internalCallback() {
|
||||
assertEquals(this, scopeObject);
|
||||
callbackCalled = true;
|
||||
return true;
|
||||
}
|
||||
delay = new goog.async.ConditionalDelay(internalCallback, scopeObject);
|
||||
delay.start(200, 200);
|
||||
clock.tick(201);
|
||||
assertTrue(callbackCalled);
|
||||
}
|
||||
195
vectortile/closure-library/closure/goog/async/delay.js
Normal file
195
vectortile/closure-library/closure/goog/async/delay.js
Normal file
@@ -0,0 +1,195 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Defines a class useful for handling functions that must be
|
||||
* invoked after a delay, especially when that delay is frequently restarted.
|
||||
* Examples include delaying before displaying a tooltip, menu hysteresis,
|
||||
* idle timers, etc.
|
||||
* @author brenneman@google.com (Shawn Brenneman)
|
||||
* @see ../demos/timers.html
|
||||
*/
|
||||
|
||||
|
||||
goog.provide('goog.Delay');
|
||||
goog.provide('goog.async.Delay');
|
||||
|
||||
goog.require('goog.Disposable');
|
||||
goog.require('goog.Timer');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A Delay object invokes the associated function after a specified delay. The
|
||||
* interval duration can be specified once in the constructor, or can be defined
|
||||
* each time the delay is started. Calling start on an active delay will reset
|
||||
* the timer.
|
||||
*
|
||||
* @param {function(this:THIS)} listener Function to call when the
|
||||
* delay completes.
|
||||
* @param {number=} opt_interval The default length of the invocation delay (in
|
||||
* milliseconds).
|
||||
* @param {THIS=} opt_handler The object scope to invoke the function in.
|
||||
* @template THIS
|
||||
* @constructor
|
||||
* @struct
|
||||
* @suppress {checkStructDictInheritance}
|
||||
* @extends {goog.Disposable}
|
||||
* @final
|
||||
*/
|
||||
goog.async.Delay = function(listener, opt_interval, opt_handler) {
|
||||
goog.async.Delay.base(this, 'constructor');
|
||||
|
||||
/**
|
||||
* The function that will be invoked after a delay.
|
||||
* @private {function(this:THIS)}
|
||||
*/
|
||||
this.listener_ = listener;
|
||||
|
||||
/**
|
||||
* The default amount of time to delay before invoking the callback.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.interval_ = opt_interval || 0;
|
||||
|
||||
/**
|
||||
* The object context to invoke the callback in.
|
||||
* @type {Object|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.handler_ = opt_handler;
|
||||
|
||||
|
||||
/**
|
||||
* Cached callback function invoked when the delay finishes.
|
||||
* @type {Function}
|
||||
* @private
|
||||
*/
|
||||
this.callback_ = goog.bind(this.doAction_, this);
|
||||
};
|
||||
goog.inherits(goog.async.Delay, goog.Disposable);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A deprecated alias.
|
||||
* @deprecated Use goog.async.Delay instead.
|
||||
* @constructor
|
||||
* @final
|
||||
*/
|
||||
goog.Delay = goog.async.Delay;
|
||||
|
||||
|
||||
/**
|
||||
* Identifier of the active delay timeout, or 0 when inactive.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.async.Delay.prototype.id_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Disposes of the object, cancelling the timeout if it is still outstanding and
|
||||
* removing all object references.
|
||||
* @override
|
||||
* @protected
|
||||
*/
|
||||
goog.async.Delay.prototype.disposeInternal = function() {
|
||||
goog.async.Delay.base(this, 'disposeInternal');
|
||||
this.stop();
|
||||
delete this.listener_;
|
||||
delete this.handler_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Starts the delay timer. The provided listener function will be called after
|
||||
* the specified interval. Calling start on an active timer will reset the
|
||||
* delay interval.
|
||||
* @param {number=} opt_interval If specified, overrides the object's default
|
||||
* interval with this one (in milliseconds).
|
||||
*/
|
||||
goog.async.Delay.prototype.start = function(opt_interval) {
|
||||
this.stop();
|
||||
this.id_ = goog.Timer.callOnce(
|
||||
this.callback_,
|
||||
goog.isDef(opt_interval) ? opt_interval : this.interval_);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Starts the delay timer if it's not already active.
|
||||
* @param {number=} opt_interval If specified and the timer is not already
|
||||
* active, overrides the object's default interval with this one (in
|
||||
* milliseconds).
|
||||
*/
|
||||
goog.async.Delay.prototype.startIfNotActive = function(opt_interval) {
|
||||
if (!this.isActive()) {
|
||||
this.start(opt_interval);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Stops the delay timer if it is active. No action is taken if the timer is not
|
||||
* in use.
|
||||
*/
|
||||
goog.async.Delay.prototype.stop = function() {
|
||||
if (this.isActive()) {
|
||||
goog.Timer.clear(this.id_);
|
||||
}
|
||||
this.id_ = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fires delay's action even if timer has already gone off or has not been
|
||||
* started yet; guarantees action firing. Stops the delay timer.
|
||||
*/
|
||||
goog.async.Delay.prototype.fire = function() {
|
||||
this.stop();
|
||||
this.doAction_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fires delay's action only if timer is currently active. Stops the delay
|
||||
* timer.
|
||||
*/
|
||||
goog.async.Delay.prototype.fireIfActive = function() {
|
||||
if (this.isActive()) {
|
||||
this.fire();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {boolean} True if the delay is currently active, false otherwise.
|
||||
*/
|
||||
goog.async.Delay.prototype.isActive = function() {
|
||||
return this.id_ != 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Invokes the callback function after the delay successfully completes.
|
||||
* @private
|
||||
*/
|
||||
goog.async.Delay.prototype.doAction_ = function() {
|
||||
this.id_ = 0;
|
||||
if (this.listener_) {
|
||||
this.listener_.call(this.handler_);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>
|
||||
Closure Unit Tests - goog.async.Delay
|
||||
</title>
|
||||
<script src="../base.js">
|
||||
</script>
|
||||
<script>
|
||||
goog.require('goog.async.DelayTest');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
169
vectortile/closure-library/closure/goog/async/delay_test.js
Normal file
169
vectortile/closure-library/closure/goog/async/delay_test.js
Normal file
@@ -0,0 +1,169 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
goog.provide('goog.async.DelayTest');
|
||||
goog.setTestOnly('goog.async.DelayTest');
|
||||
|
||||
goog.require('goog.async.Delay');
|
||||
goog.require('goog.testing.MockClock');
|
||||
goog.require('goog.testing.jsunit');
|
||||
|
||||
var invoked = false;
|
||||
var delay = null;
|
||||
var clock = null;
|
||||
|
||||
|
||||
function callback() {
|
||||
invoked = true;
|
||||
}
|
||||
|
||||
|
||||
function setUp() {
|
||||
clock = new goog.testing.MockClock(true);
|
||||
invoked = false;
|
||||
delay = new goog.async.Delay(callback, 200);
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
clock.dispose();
|
||||
delay.dispose();
|
||||
}
|
||||
|
||||
|
||||
function testDelay() {
|
||||
delay.start();
|
||||
assertFalse(invoked);
|
||||
|
||||
clock.tick(100);
|
||||
assertFalse(invoked);
|
||||
|
||||
clock.tick(100);
|
||||
assertTrue(invoked);
|
||||
}
|
||||
|
||||
|
||||
function testStop() {
|
||||
delay.start();
|
||||
|
||||
clock.tick(100);
|
||||
assertFalse(invoked);
|
||||
|
||||
delay.stop();
|
||||
clock.tick(100);
|
||||
assertFalse(invoked);
|
||||
}
|
||||
|
||||
|
||||
function testIsActive() {
|
||||
assertFalse(delay.isActive());
|
||||
delay.start();
|
||||
assertTrue(delay.isActive());
|
||||
clock.tick(200);
|
||||
assertFalse(delay.isActive());
|
||||
}
|
||||
|
||||
|
||||
function testRestart() {
|
||||
delay.start();
|
||||
clock.tick(100);
|
||||
|
||||
delay.stop();
|
||||
assertFalse(invoked);
|
||||
|
||||
delay.start();
|
||||
clock.tick(199);
|
||||
assertFalse(invoked);
|
||||
|
||||
clock.tick(1);
|
||||
assertTrue(invoked);
|
||||
|
||||
invoked = false;
|
||||
delay.start();
|
||||
clock.tick(200);
|
||||
assertTrue(invoked);
|
||||
}
|
||||
|
||||
|
||||
function testStartIfNotActive() {
|
||||
delay.startIfNotActive();
|
||||
clock.tick(100);
|
||||
|
||||
delay.stop();
|
||||
assertFalse(invoked);
|
||||
|
||||
delay.startIfNotActive();
|
||||
clock.tick(199);
|
||||
assertFalse(invoked);
|
||||
|
||||
clock.tick(1);
|
||||
assertTrue(invoked);
|
||||
|
||||
invoked = false;
|
||||
delay.start();
|
||||
clock.tick(199);
|
||||
|
||||
assertFalse(invoked);
|
||||
|
||||
delay.startIfNotActive();
|
||||
clock.tick(1);
|
||||
|
||||
assertTrue(invoked);
|
||||
}
|
||||
|
||||
|
||||
function testOverride() {
|
||||
delay.start(50);
|
||||
clock.tick(49);
|
||||
assertFalse(invoked);
|
||||
|
||||
clock.tick(1);
|
||||
assertTrue(invoked);
|
||||
}
|
||||
|
||||
|
||||
function testDispose() {
|
||||
delay.start();
|
||||
delay.dispose();
|
||||
assertTrue(delay.isDisposed());
|
||||
|
||||
clock.tick(500);
|
||||
assertFalse(invoked);
|
||||
}
|
||||
|
||||
|
||||
function testFire() {
|
||||
delay.start();
|
||||
|
||||
clock.tick(50);
|
||||
delay.fire();
|
||||
assertTrue(invoked);
|
||||
assertFalse(delay.isActive());
|
||||
|
||||
invoked = false;
|
||||
clock.tick(200);
|
||||
assertFalse('Delay fired early with fire call, timeout should have been ' +
|
||||
'cleared', invoked);
|
||||
}
|
||||
|
||||
function testFireIfActive() {
|
||||
delay.fireIfActive();
|
||||
assertFalse(invoked);
|
||||
|
||||
delay.start();
|
||||
delay.fireIfActive();
|
||||
assertTrue(invoked);
|
||||
invoked = false;
|
||||
clock.tick(300);
|
||||
assertFalse('Delay fired early with fireIfActive, timeout should have been ' +
|
||||
'cleared', invoked);
|
||||
}
|
||||
88
vectortile/closure-library/closure/goog/async/freelist.js
Normal file
88
vectortile/closure-library/closure/goog/async/freelist.js
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright 2015 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Simple freelist.
|
||||
*
|
||||
* An anterative to goog.structs.SimplePool, it imposes the requirement that the
|
||||
* objects in the list contain a "next" property that can be used to maintain
|
||||
* the pool.
|
||||
*/
|
||||
|
||||
goog.provide('goog.async.FreeList');
|
||||
|
||||
|
||||
/**
|
||||
* @template ITEM
|
||||
*/
|
||||
goog.async.FreeList = goog.defineClass(null, {
|
||||
/**
|
||||
* @param {function():ITEM} create
|
||||
* @param {function(ITEM):void} reset
|
||||
* @param {number} limit
|
||||
*/
|
||||
constructor: function(create, reset, limit) {
|
||||
/** @const {number} */
|
||||
this.limit_ = limit;
|
||||
/** @const {function()} */
|
||||
this.create_ = create;
|
||||
/** @const {function(ITEM):void} */
|
||||
this.reset_ = reset;
|
||||
|
||||
/** @type {number} */
|
||||
this.occupants_ = 0;
|
||||
/** @type {ITEM} */
|
||||
this.head_ = null;
|
||||
},
|
||||
|
||||
/**
|
||||
* @return {ITEM}
|
||||
*/
|
||||
get: function() {
|
||||
var item;
|
||||
if (this.occupants_ > 0) {
|
||||
this.occupants_--;
|
||||
item = this.head_;
|
||||
this.head_ = item.next;
|
||||
item.next = null;
|
||||
} else {
|
||||
item = this.create_();
|
||||
}
|
||||
return item;
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {ITEM} item An item available for possible future reuse.
|
||||
*/
|
||||
put: function(item) {
|
||||
this.reset_(item);
|
||||
if (this.occupants_ < this.limit_) {
|
||||
this.occupants_++;
|
||||
item.next = this.head_;
|
||||
this.head_ = item;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Visible for testing.
|
||||
* @package
|
||||
* @return {number}
|
||||
*/
|
||||
occupants: function() {
|
||||
return this.occupants_;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright 2015 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.async.FreeListTest');
|
||||
goog.setTestOnly('goog.async.FreeListTest');
|
||||
|
||||
goog.require('goog.async.FreeList');
|
||||
goog.require('goog.testing.jsunit');
|
||||
|
||||
|
||||
var id = 0;
|
||||
var list = null;
|
||||
|
||||
function setUp() {
|
||||
var id = 0;
|
||||
var data = 1;
|
||||
list = new goog.async.FreeList(
|
||||
function() {
|
||||
data *= 2;
|
||||
return {id: id++, data: data, next: null};
|
||||
},
|
||||
function(item) {item.data = null;},
|
||||
2); // max occupancy
|
||||
}
|
||||
|
||||
|
||||
function tearDown() {
|
||||
list = null;
|
||||
}
|
||||
|
||||
function testItemsCreatedAsNeeded() {
|
||||
assertEquals(0, list.occupants());
|
||||
var item1 = list.get();
|
||||
assertNotNullNorUndefined(item1);
|
||||
var item2 = list.get();
|
||||
assertNotNullNorUndefined(item2);
|
||||
assertNotEquals(item1, item2);
|
||||
assertEquals(0, list.occupants());
|
||||
}
|
||||
|
||||
function testMaxOccupancy() {
|
||||
assertEquals(0, list.occupants());
|
||||
var item1 = list.get();
|
||||
var item2 = list.get();
|
||||
var item3 = list.get();
|
||||
|
||||
list.put(item1);
|
||||
list.put(item2);
|
||||
list.put(item3);
|
||||
|
||||
assertEquals(2, list.occupants());
|
||||
}
|
||||
|
||||
function testRecycling() {
|
||||
assertEquals(0, list.occupants());
|
||||
var item1 = list.get();
|
||||
assertNotNull(item1.data);
|
||||
|
||||
list.put(item1);
|
||||
|
||||
var item2 = list.get();
|
||||
|
||||
// Item recycled
|
||||
assertEquals(item1, item2);
|
||||
// reset method called
|
||||
assertNull(item2.data);
|
||||
}
|
||||
|
||||
|
||||
241
vectortile/closure-library/closure/goog/async/nexttick.js
Normal file
241
vectortile/closure-library/closure/goog/async/nexttick.js
Normal file
@@ -0,0 +1,241 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Provides a function to schedule running a function as soon
|
||||
* as possible after the current JS execution stops and yields to the event
|
||||
* loop.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.async.nextTick');
|
||||
goog.provide('goog.async.throwException');
|
||||
|
||||
goog.require('goog.debug.entryPointRegistry');
|
||||
goog.require('goog.dom.TagName');
|
||||
goog.require('goog.functions');
|
||||
goog.require('goog.labs.userAgent.browser');
|
||||
goog.require('goog.labs.userAgent.engine');
|
||||
|
||||
|
||||
/**
|
||||
* Throw an item without interrupting the current execution context. For
|
||||
* example, if processing a group of items in a loop, sometimes it is useful
|
||||
* to report an error while still allowing the rest of the batch to be
|
||||
* processed.
|
||||
* @param {*} exception
|
||||
*/
|
||||
goog.async.throwException = function(exception) {
|
||||
// Each throw needs to be in its own context.
|
||||
goog.global.setTimeout(function() { throw exception; }, 0);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Fires the provided callbacks as soon as possible after the current JS
|
||||
* execution context. setTimeout(…, 0) takes at least 4ms when called from
|
||||
* within another setTimeout(…, 0) for legacy reasons.
|
||||
*
|
||||
* This will not schedule the callback as a microtask (i.e. a task that can
|
||||
* preempt user input or networking callbacks). It is meant to emulate what
|
||||
* setTimeout(_, 0) would do if it were not throttled. If you desire microtask
|
||||
* behavior, use {@see goog.Promise} instead.
|
||||
*
|
||||
* @param {function(this:SCOPE)} callback Callback function to fire as soon as
|
||||
* possible.
|
||||
* @param {SCOPE=} opt_context Object in whose scope to call the listener.
|
||||
* @param {boolean=} opt_useSetImmediate Avoid the IE workaround that
|
||||
* ensures correctness at the cost of speed. See comments for details.
|
||||
* @template SCOPE
|
||||
*/
|
||||
goog.async.nextTick = function(callback, opt_context, opt_useSetImmediate) {
|
||||
var cb = callback;
|
||||
if (opt_context) {
|
||||
cb = goog.bind(callback, opt_context);
|
||||
}
|
||||
cb = goog.async.nextTick.wrapCallback_(cb);
|
||||
// window.setImmediate was introduced and currently only supported by IE10+,
|
||||
// but due to a bug in the implementation it is not guaranteed that
|
||||
// setImmediate is faster than setTimeout nor that setImmediate N is before
|
||||
// setImmediate N+1. That is why we do not use the native version if
|
||||
// available. We do, however, call setImmediate if it is a normal function
|
||||
// because that indicates that it has been replaced by goog.testing.MockClock
|
||||
// which we do want to support.
|
||||
// See
|
||||
// http://connect.microsoft.com/IE/feedback/details/801823/setimmediate-and-messagechannel-are-broken-in-ie10
|
||||
//
|
||||
// Note we do allow callers to also request setImmediate if they are willing
|
||||
// to accept the possible tradeoffs of incorrectness in exchange for speed.
|
||||
// The IE fallback of readystate change is much slower.
|
||||
if (goog.isFunction(goog.global.setImmediate) &&
|
||||
// Opt in.
|
||||
(opt_useSetImmediate ||
|
||||
// or it isn't a browser or the environment is weird
|
||||
!goog.global.Window || !goog.global.Window.prototype ||
|
||||
// or something redefined setImmediate in which case we (YOLO) decide
|
||||
// to use it (This is so that we use the mockClock setImmediate. sigh).
|
||||
goog.global.Window.prototype.setImmediate != goog.global.setImmediate)) {
|
||||
goog.global.setImmediate(cb);
|
||||
return;
|
||||
}
|
||||
|
||||
// Look for and cache the custom fallback version of setImmediate.
|
||||
if (!goog.async.nextTick.setImmediate_) {
|
||||
goog.async.nextTick.setImmediate_ =
|
||||
goog.async.nextTick.getSetImmediateEmulator_();
|
||||
}
|
||||
goog.async.nextTick.setImmediate_(cb);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Cache for the setImmediate implementation.
|
||||
* @type {function(function())}
|
||||
* @private
|
||||
*/
|
||||
goog.async.nextTick.setImmediate_;
|
||||
|
||||
|
||||
/**
|
||||
* Determines the best possible implementation to run a function as soon as
|
||||
* the JS event loop is idle.
|
||||
* @return {function(function())} The "setImmediate" implementation.
|
||||
* @private
|
||||
*/
|
||||
goog.async.nextTick.getSetImmediateEmulator_ = function() {
|
||||
// Create a private message channel and use it to postMessage empty messages
|
||||
// to ourselves.
|
||||
var Channel = goog.global['MessageChannel'];
|
||||
// If MessageChannel is not available and we are in a browser, implement
|
||||
// an iframe based polyfill in browsers that have postMessage and
|
||||
// document.addEventListener. The latter excludes IE8 because it has a
|
||||
// synchronous postMessage implementation.
|
||||
if (typeof Channel === 'undefined' && typeof window !== 'undefined' &&
|
||||
window.postMessage && window.addEventListener &&
|
||||
// Presto (The old pre-blink Opera engine) has problems with iframes
|
||||
// and contentWindow.
|
||||
!goog.labs.userAgent.engine.isPresto()) {
|
||||
/** @constructor */
|
||||
Channel = function() {
|
||||
// Make an empty, invisible iframe.
|
||||
var iframe = document.createElement(goog.dom.TagName.IFRAME);
|
||||
iframe.style.display = 'none';
|
||||
iframe.src = '';
|
||||
document.documentElement.appendChild(iframe);
|
||||
var win = iframe.contentWindow;
|
||||
var doc = win.document;
|
||||
doc.open();
|
||||
doc.write('');
|
||||
doc.close();
|
||||
// Do not post anything sensitive over this channel, as the workaround for
|
||||
// pages with file: origin could allow that information to be modified or
|
||||
// intercepted.
|
||||
var message = 'callImmediate' + Math.random();
|
||||
// The same origin policy rejects attempts to postMessage from file: urls
|
||||
// unless the origin is '*'.
|
||||
// TODO(b/16335441): Use '*' origin for data: and other similar protocols.
|
||||
var origin = win.location.protocol == 'file:' ?
|
||||
'*' : win.location.protocol + '//' + win.location.host;
|
||||
var onmessage = goog.bind(function(e) {
|
||||
// Validate origin and message to make sure that this message was
|
||||
// intended for us. If the origin is set to '*' (see above) only the
|
||||
// message needs to match since, for example, '*' != 'file://'. Allowing
|
||||
// the wildcard is ok, as we are not concerned with security here.
|
||||
if ((origin != '*' && e.origin != origin) || e.data != message) {
|
||||
return;
|
||||
}
|
||||
this['port1'].onmessage();
|
||||
}, this);
|
||||
win.addEventListener('message', onmessage, false);
|
||||
this['port1'] = {};
|
||||
this['port2'] = {
|
||||
postMessage: function() {
|
||||
win.postMessage(message, origin);
|
||||
}
|
||||
};
|
||||
};
|
||||
}
|
||||
if (typeof Channel !== 'undefined' &&
|
||||
(!goog.labs.userAgent.browser.isIE())) {
|
||||
// Exclude all of IE due to
|
||||
// http://codeforhire.com/2013/09/21/setimmediate-and-messagechannel-broken-on-internet-explorer-10/
|
||||
// which allows starving postMessage with a busy setTimeout loop.
|
||||
// This currently affects IE10 and IE11 which would otherwise be able
|
||||
// to use the postMessage based fallbacks.
|
||||
var channel = new Channel();
|
||||
// Use a fifo linked list to call callbacks in the right order.
|
||||
var head = {};
|
||||
var tail = head;
|
||||
channel['port1'].onmessage = function() {
|
||||
if (goog.isDef(head.next)) {
|
||||
head = head.next;
|
||||
var cb = head.cb;
|
||||
head.cb = null;
|
||||
cb();
|
||||
}
|
||||
};
|
||||
return function(cb) {
|
||||
tail.next = {
|
||||
cb: cb
|
||||
};
|
||||
tail = tail.next;
|
||||
channel['port2'].postMessage(0);
|
||||
};
|
||||
}
|
||||
// Implementation for IE6+: Script elements fire an asynchronous
|
||||
// onreadystatechange event when inserted into the DOM.
|
||||
if (typeof document !== 'undefined' && 'onreadystatechange' in
|
||||
document.createElement(goog.dom.TagName.SCRIPT)) {
|
||||
return function(cb) {
|
||||
var script = document.createElement(goog.dom.TagName.SCRIPT);
|
||||
script.onreadystatechange = function() {
|
||||
// Clean up and call the callback.
|
||||
script.onreadystatechange = null;
|
||||
script.parentNode.removeChild(script);
|
||||
script = null;
|
||||
cb();
|
||||
cb = null;
|
||||
};
|
||||
document.documentElement.appendChild(script);
|
||||
};
|
||||
}
|
||||
// Fall back to setTimeout with 0. In browsers this creates a delay of 5ms
|
||||
// or more.
|
||||
return function(cb) {
|
||||
goog.global.setTimeout(cb, 0);
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper function that is overrided to protect callbacks with entry point
|
||||
* monitor if the application monitors entry points.
|
||||
* @param {function()} callback Callback function to fire as soon as possible.
|
||||
* @return {function()} The wrapped callback.
|
||||
* @private
|
||||
*/
|
||||
goog.async.nextTick.wrapCallback_ = goog.functions.identity;
|
||||
|
||||
|
||||
// Register the callback function as an entry point, so that it can be
|
||||
// monitored for exception handling, etc. This has to be done in this file
|
||||
// since it requires special code to handle all browsers.
|
||||
goog.debug.entryPointRegistry.register(
|
||||
/**
|
||||
* @param {function(!Function): !Function} transformer The transforming
|
||||
* function.
|
||||
*/
|
||||
function(transformer) {
|
||||
goog.async.nextTick.wrapCallback_ = transformer;
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>
|
||||
Closure Unit Tests - goog.async.nextTick
|
||||
</title>
|
||||
<script src="../base.js">
|
||||
</script>
|
||||
<script>
|
||||
goog.require('goog.async.nextTickTest');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
252
vectortile/closure-library/closure/goog/async/nexttick_test.js
Normal file
252
vectortile/closure-library/closure/goog/async/nexttick_test.js
Normal file
@@ -0,0 +1,252 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
goog.provide('goog.async.nextTickTest');
|
||||
goog.setTestOnly('goog.async.nextTickTest');
|
||||
|
||||
goog.require('goog.Promise');
|
||||
goog.require('goog.Timer');
|
||||
goog.require('goog.async.nextTick');
|
||||
goog.require('goog.debug.ErrorHandler');
|
||||
goog.require('goog.debug.entryPointRegistry');
|
||||
goog.require('goog.dom');
|
||||
goog.require('goog.dom.TagName');
|
||||
goog.require('goog.labs.userAgent.browser');
|
||||
goog.require('goog.testing.MockClock');
|
||||
goog.require('goog.testing.PropertyReplacer');
|
||||
goog.require('goog.testing.jsunit');
|
||||
|
||||
var clock;
|
||||
var propertyReplacer = new goog.testing.PropertyReplacer();
|
||||
|
||||
function setUp() {
|
||||
clock = null;
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
if (clock) {
|
||||
clock.uninstall();
|
||||
}
|
||||
// Unset the cached setImmediate_ behavior so it's re-evaluated for each test.
|
||||
goog.async.nextTick.setImmediate_ = undefined;
|
||||
propertyReplacer.reset();
|
||||
}
|
||||
|
||||
|
||||
function testNextTick() {
|
||||
return new goog.Promise(function(resolve, reject) {
|
||||
var c = 0;
|
||||
var max = 100;
|
||||
var async = true;
|
||||
var counterStep = function(i) {
|
||||
async = false;
|
||||
assertEquals('Order correct', i, c);
|
||||
c++;
|
||||
if (c === max) {
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
for (var i = 0; i < max; i++) {
|
||||
goog.async.nextTick(goog.partial(counterStep, i));
|
||||
}
|
||||
assertTrue(async);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function testNextTickSetImmediate() {
|
||||
return new goog.Promise(function(resolve, reject) {
|
||||
var c = 0;
|
||||
var max = 100;
|
||||
var async = true;
|
||||
var counterStep = function(i) {
|
||||
async = false;
|
||||
assertEquals('Order correct', i, c);
|
||||
c++;
|
||||
if (c === max) {
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
for (var i = 0; i < max; i++) {
|
||||
goog.async.nextTick(goog.partial(counterStep, i), undefined,
|
||||
/* opt_useSetImmediate */ true);
|
||||
}
|
||||
assertTrue(async);
|
||||
});
|
||||
}
|
||||
|
||||
function testNextTickContext() {
|
||||
return new goog.Promise(function(resolve, reject) {
|
||||
var context = {};
|
||||
var c = 0;
|
||||
var max = 10;
|
||||
var async = true;
|
||||
var counterStep = function(i) {
|
||||
async = false;
|
||||
assertEquals('Order correct', i, c);
|
||||
assertEquals(context, this);
|
||||
c++;
|
||||
if (c === max) {
|
||||
resolve();
|
||||
}
|
||||
};
|
||||
for (var i = 0; i < max; i++) {
|
||||
goog.async.nextTick(goog.partial(counterStep, i), context);
|
||||
}
|
||||
assertTrue(async);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function testNextTickMockClock() {
|
||||
clock = new goog.testing.MockClock(true);
|
||||
var result = '';
|
||||
goog.async.nextTick(function() {
|
||||
result += 'a';
|
||||
});
|
||||
goog.async.nextTick(function() {
|
||||
result += 'b';
|
||||
});
|
||||
goog.async.nextTick(function() {
|
||||
result += 'c';
|
||||
});
|
||||
assertEquals('', result);
|
||||
clock.tick(0);
|
||||
assertEquals('abc', result);
|
||||
}
|
||||
|
||||
|
||||
function testNextTickDoesntSwallowError() {
|
||||
return new goog.Promise(function(resolve, reject) {
|
||||
var sentinel = 'sentinel';
|
||||
|
||||
propertyReplacer.replace(window, 'onerror', function(e) {
|
||||
e = '' + e;
|
||||
// Don't test for contents in IE7, which does not preserve the exception
|
||||
// message.
|
||||
if (e.indexOf('Exception thrown and not caught') == -1) {
|
||||
assertContains(sentinel, e);
|
||||
}
|
||||
resolve();
|
||||
return false;
|
||||
});
|
||||
|
||||
goog.async.nextTick(function() {
|
||||
throw sentinel;
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function testNextTickProtectEntryPoint() {
|
||||
return new goog.Promise(function(resolve, reject) {
|
||||
var errorHandlerCallbackCalled = false;
|
||||
var errorHandler = new goog.debug.ErrorHandler(function() {
|
||||
errorHandlerCallbackCalled = true;
|
||||
});
|
||||
|
||||
// This is only testing wrapping the callback with the protected entry
|
||||
// point, so it's okay to replace this function with a fake.
|
||||
propertyReplacer.set(goog.async.nextTick, 'setImmediate_', function(cb) {
|
||||
try {
|
||||
cb();
|
||||
fail('The callback should have thrown an error.');
|
||||
} catch (e) {
|
||||
assertTrue(errorHandlerCallbackCalled);
|
||||
assertTrue(
|
||||
e instanceof goog.debug.ErrorHandler.ProtectedFunctionError);
|
||||
} finally {
|
||||
// Restore setImmediate so it doesn't interfere with Promise behavior.
|
||||
propertyReplacer.reset();
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
|
||||
goog.debug.entryPointRegistry.monitorAll(errorHandler);
|
||||
goog.async.nextTick(function() {
|
||||
throw Error('This should be caught by the protected function.');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function testNextTick_notStarvedBySetTimeout() {
|
||||
// This test will timeout when affected by
|
||||
// http://codeforhire.com/2013/09/21/setimmediate-and-messagechannel-broken-on-internet-explorer-10/
|
||||
// This test would fail without the fix introduced in cl/72472221
|
||||
// It keeps scheduling 0 timeouts and a single nextTick. If the nextTick
|
||||
// ever fires, the IE specific problem does not occur.
|
||||
var timeout;
|
||||
function busy() {
|
||||
timeout = setTimeout(function() {
|
||||
busy();
|
||||
}, 0);
|
||||
}
|
||||
busy();
|
||||
|
||||
return new goog.Promise(function(resolve, reject) {
|
||||
goog.async.nextTick(function() {
|
||||
if (timeout) {
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Test a scenario in which the iframe used by the postMessage polyfill gets a
|
||||
* message that does not have match what is expected. In this case, the polyfill
|
||||
* should not try to invoke a callback (which would result in an error because
|
||||
* there would be no callbacks in the linked list).
|
||||
*/
|
||||
function testPostMessagePolyfillDoesNotPumpCallbackQueueIfMessageIsIncorrect() {
|
||||
// IE does not use the postMessage polyfill.
|
||||
if (goog.labs.userAgent.browser.isIE()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Force postMessage polyfill for setImmediate.
|
||||
propertyReplacer.set(window, 'setImmediate', undefined);
|
||||
propertyReplacer.set(window, 'MessageChannel', undefined);
|
||||
|
||||
var callbackCalled = false;
|
||||
goog.async.nextTick(function() {
|
||||
callbackCalled = true;
|
||||
});
|
||||
|
||||
var frame = document.getElementsByTagName(goog.dom.TagName.IFRAME)[0];
|
||||
frame.contentWindow.postMessage('bogus message',
|
||||
window.location.protocol + '//' + window.location.host);
|
||||
|
||||
var error = null;
|
||||
frame.contentWindow.onerror = function(e) {
|
||||
error = e;
|
||||
};
|
||||
|
||||
return goog.Timer.promise(0).then(function() {
|
||||
assert('Callback should have been called.', callbackCalled);
|
||||
assertNull('An unexpected error was thrown.', error);
|
||||
}).thenAlways(function() {
|
||||
goog.dom.removeNode(frame);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function testBehaviorOnPagesWithOverriddenWindowConstructor() {
|
||||
propertyReplacer.set(goog.global, 'Window', {});
|
||||
testNextTick();
|
||||
testNextTickSetImmediate();
|
||||
testNextTickMockClock();
|
||||
}
|
||||
139
vectortile/closure-library/closure/goog/async/run.js
Normal file
139
vectortile/closure-library/closure/goog/async/run.js
Normal file
@@ -0,0 +1,139 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.async.run');
|
||||
|
||||
goog.require('goog.async.WorkQueue');
|
||||
goog.require('goog.async.nextTick');
|
||||
goog.require('goog.async.throwException');
|
||||
goog.require('goog.testing.watchers');
|
||||
|
||||
|
||||
/**
|
||||
* Fires the provided callback just before the current callstack unwinds, or as
|
||||
* soon as possible after the current JS execution context.
|
||||
* @param {function(this:THIS)} callback
|
||||
* @param {THIS=} opt_context Object to use as the "this value" when calling
|
||||
* the provided function.
|
||||
* @template THIS
|
||||
*/
|
||||
goog.async.run = function(callback, opt_context) {
|
||||
if (!goog.async.run.schedule_) {
|
||||
goog.async.run.initializeRunner_();
|
||||
}
|
||||
if (!goog.async.run.workQueueScheduled_) {
|
||||
// Nothing is currently scheduled, schedule it now.
|
||||
goog.async.run.schedule_();
|
||||
goog.async.run.workQueueScheduled_ = true;
|
||||
}
|
||||
|
||||
goog.async.run.workQueue_.add(callback, opt_context);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Initializes the function to use to process the work queue.
|
||||
* @private
|
||||
*/
|
||||
goog.async.run.initializeRunner_ = function() {
|
||||
// If native Promises are available in the browser, just schedule the callback
|
||||
// on a fulfilled promise, which is specified to be async, but as fast as
|
||||
// possible.
|
||||
if (goog.global.Promise && goog.global.Promise.resolve) {
|
||||
var promise = goog.global.Promise.resolve(undefined);
|
||||
goog.async.run.schedule_ = function() {
|
||||
promise.then(goog.async.run.processWorkQueue);
|
||||
};
|
||||
} else {
|
||||
goog.async.run.schedule_ = function() {
|
||||
goog.async.nextTick(goog.async.run.processWorkQueue);
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Forces goog.async.run to use nextTick instead of Promise.
|
||||
*
|
||||
* This should only be done in unit tests. It's useful because MockClock
|
||||
* replaces nextTick, but not the browser Promise implementation, so it allows
|
||||
* Promise-based code to be tested with MockClock.
|
||||
*
|
||||
* However, we also want to run promises if the MockClock is no longer in
|
||||
* control so we schedule a backup "setTimeout" to the unmocked timeout if
|
||||
* provided.
|
||||
*
|
||||
* @param {function(function())=} opt_realSetTimeout
|
||||
*/
|
||||
goog.async.run.forceNextTick = function(opt_realSetTimeout) {
|
||||
goog.async.run.schedule_ = function() {
|
||||
goog.async.nextTick(goog.async.run.processWorkQueue);
|
||||
if (opt_realSetTimeout) {
|
||||
opt_realSetTimeout(goog.async.run.processWorkQueue);
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* The function used to schedule work asynchronousely.
|
||||
* @private {function()}
|
||||
*/
|
||||
goog.async.run.schedule_;
|
||||
|
||||
|
||||
/** @private {boolean} */
|
||||
goog.async.run.workQueueScheduled_ = false;
|
||||
|
||||
|
||||
/** @private {!goog.async.WorkQueue} */
|
||||
goog.async.run.workQueue_ = new goog.async.WorkQueue();
|
||||
|
||||
|
||||
if (goog.DEBUG) {
|
||||
/**
|
||||
* Reset the work queue.
|
||||
* @private
|
||||
*/
|
||||
goog.async.run.resetQueue_ = function() {
|
||||
goog.async.run.workQueueScheduled_ = false;
|
||||
goog.async.run.workQueue_ = new goog.async.WorkQueue();
|
||||
};
|
||||
|
||||
// If there is a clock implemenation in use for testing
|
||||
// and it is reset, reset the queue.
|
||||
goog.testing.watchers.watchClockReset(goog.async.run.resetQueue_);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Run any pending goog.async.run work items. This function is not intended
|
||||
* for general use, but for use by entry point handlers to run items ahead of
|
||||
* goog.async.nextTick.
|
||||
*/
|
||||
goog.async.run.processWorkQueue = function() {
|
||||
// NOTE: additional work queue items may be added while processing.
|
||||
var item = null;
|
||||
while (item = goog.async.run.workQueue_.remove()) {
|
||||
try {
|
||||
item.fn.call(item.scope);
|
||||
} catch (e) {
|
||||
goog.async.throwException(e);
|
||||
}
|
||||
goog.async.run.workQueue_.returnUnused(item);
|
||||
}
|
||||
|
||||
// There are no more work items, allow processing to be scheduled again.
|
||||
goog.async.run.workQueueScheduled_ = false;
|
||||
};
|
||||
147
vectortile/closure-library/closure/goog/async/run_test.js
Normal file
147
vectortile/closure-library/closure/goog/async/run_test.js
Normal file
@@ -0,0 +1,147 @@
|
||||
// Copyright 2013 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.async.runTest');
|
||||
|
||||
goog.require('goog.async.run');
|
||||
goog.require('goog.testing.MockClock');
|
||||
goog.require('goog.testing.jsunit');
|
||||
goog.require('goog.testing.recordFunction');
|
||||
|
||||
goog.setTestOnly('goog.async.runTest');
|
||||
|
||||
|
||||
var mockClock;
|
||||
var futureCallback1, futureCallback2;
|
||||
|
||||
function setUpPage() {
|
||||
mockClock = new goog.testing.MockClock();
|
||||
mockClock.install();
|
||||
}
|
||||
|
||||
function setUp() {
|
||||
mockClock.reset();
|
||||
futureCallback1 = new goog.testing.recordFunction();
|
||||
futureCallback2 = new goog.testing.recordFunction();
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
futureCallback1 = null;
|
||||
futureCallback2 = null;
|
||||
}
|
||||
|
||||
function tearDownPage() {
|
||||
mockClock.uninstall();
|
||||
goog.dispose(mockClock);
|
||||
}
|
||||
|
||||
function testCalledAsync() {
|
||||
goog.async.run(futureCallback1);
|
||||
goog.async.run(futureCallback2);
|
||||
|
||||
assertEquals(0, futureCallback1.getCallCount());
|
||||
assertEquals(0, futureCallback2.getCallCount());
|
||||
|
||||
// but the callbacks are scheduled...
|
||||
mockClock.tick();
|
||||
|
||||
// and called.
|
||||
assertEquals(1, futureCallback1.getCallCount());
|
||||
assertEquals(1, futureCallback2.getCallCount());
|
||||
|
||||
// and aren't called a second time.
|
||||
assertEquals(1, futureCallback1.getCallCount());
|
||||
assertEquals(1, futureCallback2.getCallCount());
|
||||
}
|
||||
|
||||
function testSequenceCalledInOrder() {
|
||||
futureCallback1 = new goog.testing.recordFunction(
|
||||
function() {
|
||||
// called before futureCallback2
|
||||
assertEquals(0, futureCallback2.getCallCount());
|
||||
});
|
||||
futureCallback2 = new goog.testing.recordFunction(
|
||||
function() {
|
||||
// called after futureCallback1
|
||||
assertEquals(1, futureCallback1.getCallCount());
|
||||
});
|
||||
goog.async.run(futureCallback1);
|
||||
goog.async.run(futureCallback2);
|
||||
|
||||
// goog.async.run doesn't call the top callback immediately.
|
||||
assertEquals(0, futureCallback1.getCallCount());
|
||||
|
||||
// but the callbacks are scheduled...
|
||||
mockClock.tick();
|
||||
|
||||
// and called during the same "tick".
|
||||
assertEquals(1, futureCallback1.getCallCount());
|
||||
assertEquals(1, futureCallback2.getCallCount());
|
||||
}
|
||||
|
||||
function testSequenceScheduledTwice() {
|
||||
goog.async.run(futureCallback1);
|
||||
goog.async.run(futureCallback1);
|
||||
|
||||
// goog.async.run doesn't call the top callback immediately.
|
||||
assertEquals(0, futureCallback1.getCallCount());
|
||||
|
||||
// but the callbacks are scheduled...
|
||||
mockClock.tick();
|
||||
|
||||
// and called twice during the same "tick".
|
||||
assertEquals(2, futureCallback1.getCallCount());
|
||||
}
|
||||
|
||||
function testSequenceCalledSync() {
|
||||
futureCallback1 = new goog.testing.recordFunction(
|
||||
function() {
|
||||
goog.async.run(futureCallback2);
|
||||
// goog.async.run doesn't call the inner callback immediately.
|
||||
assertEquals(0, futureCallback2.getCallCount());
|
||||
});
|
||||
goog.async.run(futureCallback1);
|
||||
|
||||
// goog.async.run doesn't call the top callback immediately.
|
||||
assertEquals(0, futureCallback1.getCallCount());
|
||||
|
||||
// but the callbacks are scheduled...
|
||||
mockClock.tick();
|
||||
|
||||
// and called during the same "tick".
|
||||
assertEquals(1, futureCallback1.getCallCount());
|
||||
assertEquals(1, futureCallback2.getCallCount());
|
||||
}
|
||||
|
||||
function testScope() {
|
||||
var aScope = {};
|
||||
goog.async.run(futureCallback1);
|
||||
goog.async.run(futureCallback2, aScope);
|
||||
|
||||
// the callbacks are scheduled...
|
||||
mockClock.tick();
|
||||
|
||||
// and called.
|
||||
assertEquals(1, futureCallback1.getCallCount());
|
||||
assertEquals(1, futureCallback2.getCallCount());
|
||||
|
||||
// and get the correct scope.
|
||||
var last1 = futureCallback1.popLastCall();
|
||||
assertEquals(0, last1.getArguments().length);
|
||||
assertEquals(goog.global, last1.getThis());
|
||||
|
||||
var last2 = futureCallback2.popLastCall();
|
||||
assertEquals(0, last2.getArguments().length);
|
||||
assertEquals(aScope, last2.getThis());
|
||||
}
|
||||
195
vectortile/closure-library/closure/goog/async/throttle.js
Normal file
195
vectortile/closure-library/closure/goog/async/throttle.js
Normal file
@@ -0,0 +1,195 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Definition of the goog.async.Throttle class.
|
||||
*
|
||||
* @see ../demos/timers.html
|
||||
*/
|
||||
|
||||
goog.provide('goog.Throttle');
|
||||
goog.provide('goog.async.Throttle');
|
||||
|
||||
goog.require('goog.Disposable');
|
||||
goog.require('goog.Timer');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Throttle will perform an action that is passed in no more than once
|
||||
* per interval (specified in milliseconds). If it gets multiple signals
|
||||
* to perform the action while it is waiting, it will only perform the action
|
||||
* once at the end of the interval.
|
||||
* @param {function(this: T)} listener Function to callback when the action is
|
||||
* triggered.
|
||||
* @param {number} interval Interval over which to throttle. The listener can
|
||||
* only be called once per interval.
|
||||
* @param {T=} opt_handler Object in whose scope to call the listener.
|
||||
* @constructor
|
||||
* @struct
|
||||
* @suppress {checkStructDictInheritance}
|
||||
* @extends {goog.Disposable}
|
||||
* @final
|
||||
* @template T
|
||||
*/
|
||||
goog.async.Throttle = function(listener, interval, opt_handler) {
|
||||
goog.async.Throttle.base(this, 'constructor');
|
||||
|
||||
/**
|
||||
* Function to callback
|
||||
* @type {function(this: T)}
|
||||
* @private
|
||||
*/
|
||||
this.listener_ = listener;
|
||||
|
||||
/**
|
||||
* Interval for the throttle time
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.interval_ = interval;
|
||||
|
||||
/**
|
||||
* "this" context for the listener
|
||||
* @type {Object|undefined}
|
||||
* @private
|
||||
*/
|
||||
this.handler_ = opt_handler;
|
||||
|
||||
/**
|
||||
* Cached callback function invoked after the throttle timeout completes
|
||||
* @type {Function}
|
||||
* @private
|
||||
*/
|
||||
this.callback_ = goog.bind(this.onTimer_, this);
|
||||
};
|
||||
goog.inherits(goog.async.Throttle, goog.Disposable);
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A deprecated alias.
|
||||
* @deprecated Use goog.async.Throttle instead.
|
||||
* @constructor
|
||||
* @final
|
||||
*/
|
||||
goog.Throttle = goog.async.Throttle;
|
||||
|
||||
|
||||
/**
|
||||
* Indicates that the action is pending and needs to be fired.
|
||||
* @type {boolean}
|
||||
* @private
|
||||
*/
|
||||
goog.async.Throttle.prototype.shouldFire_ = false;
|
||||
|
||||
|
||||
/**
|
||||
* Indicates the count of nested pauses currently in effect on the throttle.
|
||||
* When this count is not zero, fired actions will be postponed until the
|
||||
* throttle is resumed enough times to drop the pause count to zero.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
goog.async.Throttle.prototype.pauseCount_ = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Timer for scheduling the next callback
|
||||
* @type {?number}
|
||||
* @private
|
||||
*/
|
||||
goog.async.Throttle.prototype.timer_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Notifies the throttle that the action has happened. It will throttle the call
|
||||
* so that the callback is not called too often according to the interval
|
||||
* parameter passed to the constructor.
|
||||
*/
|
||||
goog.async.Throttle.prototype.fire = function() {
|
||||
if (!this.timer_ && !this.pauseCount_) {
|
||||
this.doAction_();
|
||||
} else {
|
||||
this.shouldFire_ = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Cancels any pending action callback. The throttle can be restarted by
|
||||
* calling {@link #fire}.
|
||||
*/
|
||||
goog.async.Throttle.prototype.stop = function() {
|
||||
if (this.timer_) {
|
||||
goog.Timer.clear(this.timer_);
|
||||
this.timer_ = null;
|
||||
this.shouldFire_ = false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Pauses the throttle. All pending and future action callbacks will be
|
||||
* delayed until the throttle is resumed. Pauses can be nested.
|
||||
*/
|
||||
goog.async.Throttle.prototype.pause = function() {
|
||||
this.pauseCount_++;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Resumes the throttle. If doing so drops the pausing count to zero, pending
|
||||
* action callbacks will be executed as soon as possible, but still no sooner
|
||||
* than an interval's delay after the previous call. Future action callbacks
|
||||
* will be executed as normal.
|
||||
*/
|
||||
goog.async.Throttle.prototype.resume = function() {
|
||||
this.pauseCount_--;
|
||||
if (!this.pauseCount_ && this.shouldFire_ && !this.timer_) {
|
||||
this.shouldFire_ = false;
|
||||
this.doAction_();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/** @override */
|
||||
goog.async.Throttle.prototype.disposeInternal = function() {
|
||||
goog.async.Throttle.base(this, 'disposeInternal');
|
||||
this.stop();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handler for the timer to fire the throttle
|
||||
* @private
|
||||
*/
|
||||
goog.async.Throttle.prototype.onTimer_ = function() {
|
||||
this.timer_ = null;
|
||||
|
||||
if (this.shouldFire_ && !this.pauseCount_) {
|
||||
this.shouldFire_ = false;
|
||||
this.doAction_();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calls the callback
|
||||
* @private
|
||||
*/
|
||||
goog.async.Throttle.prototype.doAction_ = function() {
|
||||
this.timer_ = goog.Timer.callOnce(this.callback_, this.interval_);
|
||||
this.listener_.call(this.handler_);
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>
|
||||
Closure Unit Tests - goog.async.Throttle
|
||||
</title>
|
||||
<script src="../base.js">
|
||||
</script>
|
||||
<script>
|
||||
goog.require('goog.async.ThrottleTest');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,95 @@
|
||||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
goog.provide('goog.async.ThrottleTest');
|
||||
goog.setTestOnly('goog.async.ThrottleTest');
|
||||
|
||||
goog.require('goog.async.Throttle');
|
||||
goog.require('goog.testing.MockClock');
|
||||
goog.require('goog.testing.jsunit');
|
||||
|
||||
function testThrottle() {
|
||||
var clock = new goog.testing.MockClock(true);
|
||||
|
||||
var callBackCount = 0;
|
||||
var callBackFunction = function() {
|
||||
callBackCount++;
|
||||
};
|
||||
|
||||
var throttle = new goog.async.Throttle(callBackFunction, 100);
|
||||
assertEquals(0, callBackCount);
|
||||
throttle.fire();
|
||||
assertEquals(1, callBackCount);
|
||||
throttle.fire();
|
||||
assertEquals(1, callBackCount);
|
||||
throttle.fire();
|
||||
throttle.fire();
|
||||
assertEquals(1, callBackCount);
|
||||
clock.tick(101);
|
||||
assertEquals(2, callBackCount);
|
||||
clock.tick(101);
|
||||
assertEquals(2, callBackCount);
|
||||
|
||||
throttle.fire();
|
||||
assertEquals(3, callBackCount);
|
||||
throttle.fire();
|
||||
assertEquals(3, callBackCount);
|
||||
throttle.stop();
|
||||
clock.tick(101);
|
||||
assertEquals(3, callBackCount);
|
||||
throttle.fire();
|
||||
assertEquals(4, callBackCount);
|
||||
clock.tick(101);
|
||||
assertEquals(4, callBackCount);
|
||||
|
||||
throttle.fire();
|
||||
throttle.fire();
|
||||
assertEquals(5, callBackCount);
|
||||
throttle.pause();
|
||||
throttle.resume();
|
||||
assertEquals(5, callBackCount);
|
||||
throttle.pause();
|
||||
clock.tick(101);
|
||||
assertEquals(5, callBackCount);
|
||||
throttle.resume();
|
||||
assertEquals(6, callBackCount);
|
||||
clock.tick(101);
|
||||
assertEquals(6, callBackCount);
|
||||
throttle.pause();
|
||||
throttle.fire();
|
||||
assertEquals(6, callBackCount);
|
||||
clock.tick(101);
|
||||
assertEquals(6, callBackCount);
|
||||
throttle.resume();
|
||||
assertEquals(7, callBackCount);
|
||||
|
||||
throttle.pause();
|
||||
throttle.pause();
|
||||
clock.tick(101);
|
||||
throttle.fire();
|
||||
throttle.resume();
|
||||
assertEquals(7, callBackCount);
|
||||
throttle.resume();
|
||||
assertEquals(8, callBackCount);
|
||||
|
||||
throttle.pause();
|
||||
throttle.pause();
|
||||
throttle.fire();
|
||||
throttle.resume();
|
||||
clock.tick(101);
|
||||
assertEquals(8, callBackCount);
|
||||
throttle.resume();
|
||||
assertEquals(9, callBackCount);
|
||||
|
||||
clock.uninstall();
|
||||
}
|
||||
139
vectortile/closure-library/closure/goog/async/workqueue.js
Normal file
139
vectortile/closure-library/closure/goog/async/workqueue.js
Normal file
@@ -0,0 +1,139 @@
|
||||
// Copyright 2015 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.async.WorkItem');
|
||||
goog.provide('goog.async.WorkQueue');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.async.FreeList');
|
||||
|
||||
|
||||
// TODO(johnlenz): generalize the WorkQueue if this is used by more
|
||||
// than goog.async.run.
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* A low GC workqueue. The key elements of this design:
|
||||
* - avoids the need for goog.bind or equivalent by carrying scope
|
||||
* - avoids the need for array reallocation by using a linked list
|
||||
* - minimizes work entry objects allocation by recycling objects
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
*/
|
||||
goog.async.WorkQueue = function() {
|
||||
this.workHead_ = null;
|
||||
this.workTail_ = null;
|
||||
};
|
||||
|
||||
|
||||
/** @define {number} The maximum number of entries to keep for recycling. */
|
||||
goog.define('goog.async.WorkQueue.DEFAULT_MAX_UNUSED', 100);
|
||||
|
||||
|
||||
/** @const @private {goog.async.FreeList<goog.async.WorkItem>} */
|
||||
goog.async.WorkQueue.freelist_ = new goog.async.FreeList(
|
||||
function() {return new goog.async.WorkItem(); },
|
||||
function(item) {item.reset()},
|
||||
goog.async.WorkQueue.DEFAULT_MAX_UNUSED);
|
||||
|
||||
|
||||
/**
|
||||
* @param {function()} fn
|
||||
* @param {Object|null|undefined} scope
|
||||
*/
|
||||
goog.async.WorkQueue.prototype.add = function(fn, scope) {
|
||||
var item = this.getUnusedItem_();
|
||||
item.set(fn, scope);
|
||||
|
||||
if (this.workTail_) {
|
||||
this.workTail_.next = item;
|
||||
this.workTail_ = item;
|
||||
} else {
|
||||
goog.asserts.assert(!this.workHead_);
|
||||
this.workHead_ = item;
|
||||
this.workTail_ = item;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.async.WorkItem}
|
||||
*/
|
||||
goog.async.WorkQueue.prototype.remove = function() {
|
||||
var item = null;
|
||||
|
||||
if (this.workHead_) {
|
||||
item = this.workHead_;
|
||||
this.workHead_ = this.workHead_.next;
|
||||
if (!this.workHead_) {
|
||||
this.workTail_ = null;
|
||||
}
|
||||
item.next = null;
|
||||
}
|
||||
return item;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {goog.async.WorkItem} item
|
||||
*/
|
||||
goog.async.WorkQueue.prototype.returnUnused = function(item) {
|
||||
goog.async.WorkQueue.freelist_.put(item);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {goog.async.WorkItem}
|
||||
* @private
|
||||
*/
|
||||
goog.async.WorkQueue.prototype.getUnusedItem_ = function() {
|
||||
return goog.async.WorkQueue.freelist_.get();
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
*/
|
||||
goog.async.WorkItem = function() {
|
||||
/** @type {?function()} */
|
||||
this.fn = null;
|
||||
/** @type {Object|null|undefined} */
|
||||
this.scope = null;
|
||||
/** @type {?goog.async.WorkItem} */
|
||||
this.next = null;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @param {function()} fn
|
||||
* @param {Object|null|undefined} scope
|
||||
*/
|
||||
goog.async.WorkItem.prototype.set = function(fn, scope) {
|
||||
this.fn = fn;
|
||||
this.scope = scope;
|
||||
this.next = null;
|
||||
};
|
||||
|
||||
|
||||
/** Reset the work item so they don't prevent GC before reuse */
|
||||
goog.async.WorkItem.prototype.reset = function() {
|
||||
this.fn = null;
|
||||
this.scope = null;
|
||||
this.next = null;
|
||||
};
|
||||
@@ -0,0 +1,90 @@
|
||||
// Copyright 2015 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.async.WorkQueueTest');
|
||||
goog.setTestOnly('goog.async.WorkQueueTest');
|
||||
|
||||
goog.require('goog.async.WorkQueue');
|
||||
goog.require('goog.testing.jsunit');
|
||||
|
||||
|
||||
var id = 0;
|
||||
var queue = null;
|
||||
|
||||
|
||||
function setUp() {
|
||||
queue = new goog.async.WorkQueue();
|
||||
}
|
||||
|
||||
|
||||
function tearDown() {
|
||||
queue = null;
|
||||
}
|
||||
|
||||
|
||||
function testEntriesReturnedInOrder() {
|
||||
var fn1 = function one() {};
|
||||
var scope1 = {};
|
||||
var fn2 = function two() {};
|
||||
var scope2 = {};
|
||||
queue.add(fn1, scope1);
|
||||
queue.add(fn2, scope2);
|
||||
|
||||
var item = queue.remove();
|
||||
assertEquals(fn1, item.fn);
|
||||
assertEquals(scope1, item.scope);
|
||||
assertNull(item.next);
|
||||
|
||||
item = queue.remove();
|
||||
assertEquals(fn2, item.fn);
|
||||
assertEquals(scope2, item.scope);
|
||||
assertNull(item.next);
|
||||
|
||||
item = queue.remove();
|
||||
assertNull(item);
|
||||
}
|
||||
|
||||
|
||||
function testReturnedItemReused() {
|
||||
var fn1 = function() {};
|
||||
var scope1 = {};
|
||||
|
||||
var fn2 = function() {};
|
||||
var scope2 = {};
|
||||
|
||||
assertEquals(0, goog.async.WorkQueue.freelist_.occupants());
|
||||
|
||||
queue.add(fn1, scope1);
|
||||
var item1 = queue.remove();
|
||||
|
||||
assertEquals(0, goog.async.WorkQueue.freelist_.occupants());
|
||||
|
||||
queue.returnUnused(item1);
|
||||
|
||||
assertEquals(1, goog.async.WorkQueue.freelist_.occupants());
|
||||
|
||||
queue.add(fn2, scope2);
|
||||
|
||||
assertEquals(0, goog.async.WorkQueue.freelist_.occupants());
|
||||
|
||||
var item2 = queue.remove();
|
||||
|
||||
assertEquals(item1, item2);
|
||||
}
|
||||
|
||||
|
||||
function testEmptyQueueReturnNull() {
|
||||
var item1 = queue.remove();
|
||||
assertNull(item1);
|
||||
}
|
||||
2527
vectortile/closure-library/closure/goog/base.js
Normal file
2527
vectortile/closure-library/closure/goog/base.js
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,20 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Closure Unit Tests - goog.module</title>
|
||||
<script src="base.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script>
|
||||
goog.require('goog.baseModuleTest');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
113
vectortile/closure-library/closure/goog/base_module_test.js
Normal file
113
vectortile/closure-library/closure/goog/base_module_test.js
Normal file
@@ -0,0 +1,113 @@
|
||||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
|
||||
/**
|
||||
* @fileoverview Unit tests for Closure's base.js's goog.module support.
|
||||
*/
|
||||
|
||||
goog.module('goog.baseModuleTest');
|
||||
goog.setTestOnly('goog.baseModuleTest');
|
||||
|
||||
|
||||
// Used to test dynamic loading works, see testRequire*
|
||||
var Timer = goog.require('goog.Timer');
|
||||
var Replacer = goog.require('goog.testing.PropertyReplacer');
|
||||
var jsunit = goog.require('goog.testing.jsunit');
|
||||
var testSuite = goog.require('goog.testing.testSuite');
|
||||
|
||||
var testModule = goog.require('goog.test_module');
|
||||
|
||||
var stubs = new Replacer();
|
||||
|
||||
function assertProvideFails(namespace) {
|
||||
assertThrows('goog.provide(' + namespace + ') should have failed',
|
||||
goog.partial(goog.provide, namespace));
|
||||
}
|
||||
|
||||
function assertModuleFails(namespace) {
|
||||
assertThrows('goog.module(' + namespace + ') should have failed',
|
||||
goog.partial(goog.module, namespace));
|
||||
}
|
||||
|
||||
testSuite({
|
||||
teardown: function() {
|
||||
stubs.reset();
|
||||
},
|
||||
|
||||
testModuleDecl: function() {
|
||||
// assert that goog.module doesn't modify the global namespace
|
||||
assertUndefined('module failed to protect global namespace: ' +
|
||||
'goog.baseModuleTest', goog.baseModuleTest);
|
||||
},
|
||||
|
||||
testModuleScoping: function() {
|
||||
// assert test functions are not exported to the global namespace
|
||||
assertNotUndefined('module failed: testModule', testModule);
|
||||
assertFalse('module failed: testModule',
|
||||
goog.isFunction(goog.global.testModuleScoping));
|
||||
},
|
||||
|
||||
testProvideStrictness1: function() {
|
||||
assertModuleFails('goog.xy'); // not in goog.loadModule
|
||||
|
||||
assertProvideFails('goog.baseModuleTest'); // this file.
|
||||
},
|
||||
|
||||
testProvideStrictness2: function() {
|
||||
// goog.module "provides" a namespace
|
||||
assertTrue(goog.isProvided_('goog.baseModuleTest'));
|
||||
},
|
||||
|
||||
testExportSymbol: function() {
|
||||
// Assert that export symbol works from within a goog.module.
|
||||
var date = new Date();
|
||||
|
||||
assertTrue(typeof nodots == 'undefined');
|
||||
goog.exportSymbol('nodots', date);
|
||||
assertEquals(date, nodots); // globals are accessible from within a module.
|
||||
nodots = undefined;
|
||||
},
|
||||
|
||||
//=== tests for Require logic ===
|
||||
|
||||
testLegacyRequire: function() {
|
||||
// goog.Timer is a legacy module loaded above
|
||||
assertNotUndefined('goog.Timer should be available', goog.Timer);
|
||||
|
||||
// Verify that a legacy module can be aliases with goog.require
|
||||
assertTrue('Timer should be the goog.Timer namespace object',
|
||||
goog.Timer === Timer);
|
||||
|
||||
// and its dependencies
|
||||
assertNotUndefined(
|
||||
'goog.events.EventTarget should be available',
|
||||
/** @suppress {missingRequire} */ goog.events.EventTarget);
|
||||
},
|
||||
|
||||
testRequireModule: function() {
|
||||
assertEquals('module failed to export legacy namespace: ' +
|
||||
'goog.test_module', testModule, goog.test_module);
|
||||
assertUndefined('module failed to protect global namespace: ' +
|
||||
'goog.test_module_dep', goog.test_module_dep);
|
||||
|
||||
// The test module is available under its alias
|
||||
assertNotUndefined('testModule is loaded', testModule);
|
||||
assertTrue('module failed: testModule', goog.isFunction(testModule));
|
||||
},
|
||||
|
||||
testThisInModule: goog.bind(function() {
|
||||
assertEquals(this, goog.global);
|
||||
}, this)
|
||||
});
|
||||
33
vectortile/closure-library/closure/goog/base_test.html
Normal file
33
vectortile/closure-library/closure/goog/base_test.html
Normal file
@@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Closure Unit Tests - goog.*</title>
|
||||
<script>
|
||||
var CLOSURE_DEFINES = {
|
||||
'SOME_DEFINE': 456,
|
||||
'ns.SOME_DEFINE': 456
|
||||
};
|
||||
</script>
|
||||
<script src="base.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="elem">
|
||||
<span>One</span>
|
||||
<span id="text">Two</span>
|
||||
<span>Three</span>
|
||||
</div>
|
||||
|
||||
<iframe name="f1" id="f1" src=""></iframe>
|
||||
<iframe name="f2" id="f2" src=""></iframe>
|
||||
<script>
|
||||
goog.require('goog.baseTest');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
1528
vectortile/closure-library/closure/goog/base_test.js
Normal file
1528
vectortile/closure-library/closure/goog/base_test.js
Normal file
File diff suppressed because it is too large
Load Diff
110
vectortile/closure-library/closure/goog/bootstrap/nodejs.js
Normal file
110
vectortile/closure-library/closure/goog/bootstrap/nodejs.js
Normal file
@@ -0,0 +1,110 @@
|
||||
// Copyright 2013 The Closure Library Authors.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview A nodejs script for dynamically requiring Closure within
|
||||
* nodejs.
|
||||
*
|
||||
* Example of usage:
|
||||
* <code>
|
||||
* require('./bootstrap/nodejs')
|
||||
* goog.require('goog.ui.Component')
|
||||
* </code>
|
||||
*
|
||||
* This loads goog.ui.Component in the global scope.
|
||||
*
|
||||
* If you want to load custom libraries, you can require the custom deps file
|
||||
* directly. If your custom libraries introduce new globals, you may
|
||||
* need to run goog.nodeGlobalRequire to get them to load correctly.
|
||||
*
|
||||
* <code>
|
||||
* require('./path/to/my/deps.js')
|
||||
* goog.bootstrap.nodeJs.nodeGlobalRequire('./path/to/my/base.js')
|
||||
* goog.require('my.Class')
|
||||
* </code>
|
||||
*
|
||||
* @author nick@medium.com (Nick Santos)
|
||||
*
|
||||
* @nocompile
|
||||
*/
|
||||
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
var vm = require('vm');
|
||||
|
||||
|
||||
/**
|
||||
* The goog namespace in the global scope.
|
||||
*/
|
||||
global.goog = {};
|
||||
|
||||
|
||||
/**
|
||||
* Imports a script using Node's require() API.
|
||||
*
|
||||
* @param {string} src The script source.
|
||||
* @param {string=} opt_sourceText The optional source text to evaluate.
|
||||
* @return {boolean} True if the script was imported, false otherwise.
|
||||
*/
|
||||
global.CLOSURE_IMPORT_SCRIPT = function(src, opt_sourceText) {
|
||||
// Sources are always expressed relative to closure's base.js, but
|
||||
// require() is always relative to the current source.
|
||||
if (opt_sourceText === undefined) {
|
||||
require('./../' + src);
|
||||
} else {
|
||||
eval(opt_sourceText);
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Loads a file when using Closure's goog.require() API with goog.modules.
|
||||
*
|
||||
* @param {string} src The file source.
|
||||
* @return {string} The file contents.
|
||||
*/
|
||||
|
||||
global.CLOSURE_LOAD_FILE_SYNC = function(src) {
|
||||
return fs.readFileSync(
|
||||
path.resolve(__dirname, '..', src), { encoding: 'utf-8' });
|
||||
};
|
||||
|
||||
|
||||
// Declared here so it can be used to require base.js
|
||||
function nodeGlobalRequire(file) {
|
||||
vm.runInThisContext.call(
|
||||
global, fs.readFileSync(file), file);
|
||||
}
|
||||
|
||||
|
||||
// Load Closure's base.js into memory. It is assumed base.js is in the
|
||||
// directory above this directory given this script's location in
|
||||
// bootstrap/nodejs.js.
|
||||
nodeGlobalRequire(path.resolve(__dirname, '..', 'base.js'));
|
||||
|
||||
|
||||
/**
|
||||
* Bootstraps a file into the global scope.
|
||||
*
|
||||
* This is strictly for cases where normal require() won't work,
|
||||
* because the file declares global symbols with 'var' that need to
|
||||
* be added to the global scope.
|
||||
* @suppress {missingProvide}
|
||||
*
|
||||
* @param {string} file The path to the file.
|
||||
*/
|
||||
goog.nodeGlobalRequire = nodeGlobalRequire;
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
// Copyright 2010 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview A bootstrap for dynamically requiring Closure within an HTML5
|
||||
* Web Worker context. To use this, first set CLOSURE_BASE_PATH to the directory
|
||||
* containing base.js (relative to the main script), then use importScripts to
|
||||
* load this file and base.js (in that order). After this you can use
|
||||
* goog.require for further imports.
|
||||
*
|
||||
* @nocompile
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* Imports a script using the Web Worker importScript API.
|
||||
*
|
||||
* @param {string} src The script source.
|
||||
* @return {boolean} True if the script was imported, false otherwise.
|
||||
*/
|
||||
this.CLOSURE_IMPORT_SCRIPT = (function(global) {
|
||||
return function(src) {
|
||||
global['importScripts'](src);
|
||||
return true;
|
||||
};
|
||||
})(this);
|
||||
472
vectortile/closure-library/closure/goog/color/alpha.js
Normal file
472
vectortile/closure-library/closure/goog/color/alpha.js
Normal file
@@ -0,0 +1,472 @@
|
||||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utilities related to alpha/transparent colors and alpha color
|
||||
* conversion.
|
||||
*/
|
||||
|
||||
goog.provide('goog.color.alpha');
|
||||
|
||||
goog.require('goog.color');
|
||||
|
||||
|
||||
/**
|
||||
* Parses an alpha color out of a string.
|
||||
* @param {string} str Color in some format.
|
||||
* @return {{hex: string, type: string}} 'hex' is a string containing
|
||||
* a hex representation of the color, and 'type' is a string
|
||||
* containing the type of color format passed in ('hex', 'rgb', 'named').
|
||||
*/
|
||||
goog.color.alpha.parse = function(str) {
|
||||
var result = {};
|
||||
str = String(str);
|
||||
|
||||
var maybeHex = goog.color.prependHashIfNecessaryHelper(str);
|
||||
if (goog.color.alpha.isValidAlphaHexColor_(maybeHex)) {
|
||||
result.hex = goog.color.alpha.normalizeAlphaHex_(maybeHex);
|
||||
result.type = 'hex';
|
||||
return result;
|
||||
} else {
|
||||
var rgba = goog.color.alpha.isValidRgbaColor_(str);
|
||||
if (rgba.length) {
|
||||
result.hex = goog.color.alpha.rgbaArrayToHex(rgba);
|
||||
result.type = 'rgba';
|
||||
return result;
|
||||
} else {
|
||||
var hsla = goog.color.alpha.isValidHslaColor_(str);
|
||||
if (hsla.length) {
|
||||
result.hex = goog.color.alpha.hslaArrayToHex(hsla);
|
||||
result.type = 'hsla';
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw Error(str + ' is not a valid color string');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a hex representation of a color to RGBA.
|
||||
* @param {string} hexColor Color to convert.
|
||||
* @return {string} string of the form 'rgba(R,G,B,A)' which can be used in
|
||||
* styles.
|
||||
*/
|
||||
goog.color.alpha.hexToRgbaStyle = function(hexColor) {
|
||||
return goog.color.alpha.rgbaStyle_(goog.color.alpha.hexToRgba(hexColor));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the hex color part of an alpha hex color. For example, from '#abcdef55'
|
||||
* return '#abcdef'.
|
||||
* @param {string} colorWithAlpha The alpha hex color to get the hex color from.
|
||||
* @return {string} The hex color where the alpha part has been stripped off.
|
||||
*/
|
||||
goog.color.alpha.extractHexColor = function(colorWithAlpha) {
|
||||
if (goog.color.alpha.isValidAlphaHexColor_(colorWithAlpha)) {
|
||||
var fullColor = goog.color.prependHashIfNecessaryHelper(colorWithAlpha);
|
||||
var normalizedColor = goog.color.alpha.normalizeAlphaHex_(fullColor);
|
||||
return normalizedColor.substring(0, 7);
|
||||
} else {
|
||||
throw Error(colorWithAlpha + ' is not a valid 8-hex color string');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Gets the alpha color part of an alpha hex color. For example, from
|
||||
* '#abcdef55' return '55'. The result is guaranteed to be two characters long.
|
||||
* @param {string} colorWithAlpha The alpha hex color to get the hex color from.
|
||||
* @return {string} The hex color where the alpha part has been stripped off.
|
||||
*/
|
||||
goog.color.alpha.extractAlpha = function(colorWithAlpha) {
|
||||
if (goog.color.alpha.isValidAlphaHexColor_(colorWithAlpha)) {
|
||||
var fullColor = goog.color.prependHashIfNecessaryHelper(colorWithAlpha);
|
||||
var normalizedColor = goog.color.alpha.normalizeAlphaHex_(fullColor);
|
||||
return normalizedColor.substring(7, 9);
|
||||
} else {
|
||||
throw Error(colorWithAlpha + ' is not a valid 8-hex color string');
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for extracting the digits in a hex color quadruplet.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.color.alpha.hexQuadrupletRe_ = /#(.)(.)(.)(.)/;
|
||||
|
||||
|
||||
/**
|
||||
* Normalize a hex representation of an alpha color.
|
||||
* @param {string} hexColor an alpha hex color string.
|
||||
* @return {string} hex color in the format '#rrggbbaa' with all lowercase
|
||||
* literals.
|
||||
* @private
|
||||
*/
|
||||
goog.color.alpha.normalizeAlphaHex_ = function(hexColor) {
|
||||
if (!goog.color.alpha.isValidAlphaHexColor_(hexColor)) {
|
||||
throw Error("'" + hexColor + "' is not a valid alpha hex color");
|
||||
}
|
||||
if (hexColor.length == 5) { // of the form #RGBA
|
||||
hexColor = hexColor.replace(goog.color.alpha.hexQuadrupletRe_,
|
||||
'#$1$1$2$2$3$3$4$4');
|
||||
}
|
||||
return hexColor.toLowerCase();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts an 8-hex representation of a color to RGBA.
|
||||
* @param {string} hexColor Color to convert.
|
||||
* @return {!Array<number>} array containing [r, g, b, a].
|
||||
* r, g, b are ints between 0
|
||||
* and 255, and a is a value between 0 and 1.
|
||||
*/
|
||||
goog.color.alpha.hexToRgba = function(hexColor) {
|
||||
// TODO(user): Enhance code sharing with goog.color, for example by
|
||||
// adding a goog.color.genericHexToRgb method.
|
||||
hexColor = goog.color.alpha.normalizeAlphaHex_(hexColor);
|
||||
var r = parseInt(hexColor.substr(1, 2), 16);
|
||||
var g = parseInt(hexColor.substr(3, 2), 16);
|
||||
var b = parseInt(hexColor.substr(5, 2), 16);
|
||||
var a = parseInt(hexColor.substr(7, 2), 16);
|
||||
|
||||
return [r, g, b, a / 255];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a color from RGBA to hex representation.
|
||||
* @param {number} r Amount of red, int between 0 and 255.
|
||||
* @param {number} g Amount of green, int between 0 and 255.
|
||||
* @param {number} b Amount of blue, int between 0 and 255.
|
||||
* @param {number} a Amount of alpha, float between 0 and 1.
|
||||
* @return {string} hex representation of the color.
|
||||
*/
|
||||
goog.color.alpha.rgbaToHex = function(r, g, b, a) {
|
||||
var intAlpha = Math.floor(a * 255);
|
||||
if (isNaN(intAlpha) || intAlpha < 0 || intAlpha > 255) {
|
||||
// TODO(user): The CSS spec says the value should be clamped.
|
||||
throw Error('"(' + r + ',' + g + ',' + b + ',' + a +
|
||||
'") is not a valid RGBA color');
|
||||
}
|
||||
var hexA = goog.color.prependZeroIfNecessaryHelper(intAlpha.toString(16));
|
||||
return goog.color.rgbToHex(r, g, b) + hexA;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a color from HSLA to hex representation.
|
||||
* @param {number} h Amount of hue, int between 0 and 360.
|
||||
* @param {number} s Amount of saturation, int between 0 and 100.
|
||||
* @param {number} l Amount of lightness, int between 0 and 100.
|
||||
* @param {number} a Amount of alpha, float between 0 and 1.
|
||||
* @return {string} hex representation of the color.
|
||||
*/
|
||||
goog.color.alpha.hslaToHex = function(h, s, l, a) {
|
||||
var intAlpha = Math.floor(a * 255);
|
||||
if (isNaN(intAlpha) || intAlpha < 0 || intAlpha > 255) {
|
||||
// TODO(user): The CSS spec says the value should be clamped.
|
||||
throw Error('"(' + h + ',' + s + ',' + l + ',' + a +
|
||||
'") is not a valid HSLA color');
|
||||
}
|
||||
var hexA = goog.color.prependZeroIfNecessaryHelper(intAlpha.toString(16));
|
||||
return goog.color.hslToHex(h, s / 100, l / 100) + hexA;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a color from RGBA to hex representation.
|
||||
* @param {Array<number>} rgba Array of [r, g, b, a], with r, g, b in [0, 255]
|
||||
* and a in [0, 1].
|
||||
* @return {string} hex representation of the color.
|
||||
*/
|
||||
goog.color.alpha.rgbaArrayToHex = function(rgba) {
|
||||
return goog.color.alpha.rgbaToHex(rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a color from RGBA to an RGBA style string.
|
||||
* @param {number} r Value of red, in [0, 255].
|
||||
* @param {number} g Value of green, in [0, 255].
|
||||
* @param {number} b Value of blue, in [0, 255].
|
||||
* @param {number} a Value of alpha, in [0, 1].
|
||||
* @return {string} An 'rgba(r,g,b,a)' string ready for use in a CSS rule.
|
||||
*/
|
||||
goog.color.alpha.rgbaToRgbaStyle = function(r, g, b, a) {
|
||||
if (isNaN(r) || r < 0 || r > 255 ||
|
||||
isNaN(g) || g < 0 || g > 255 ||
|
||||
isNaN(b) || b < 0 || b > 255 ||
|
||||
isNaN(a) || a < 0 || a > 1) {
|
||||
throw Error('"(' + r + ',' + g + ',' + b + ',' + a +
|
||||
')" is not a valid RGBA color');
|
||||
}
|
||||
return goog.color.alpha.rgbaStyle_([r, g, b, a]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a color from RGBA to an RGBA style string.
|
||||
* @param {(Array<number>|Float32Array)} rgba Array of [r, g, b, a],
|
||||
* with r, g, b in [0, 255] and a in [0, 1].
|
||||
* @return {string} An 'rgba(r,g,b,a)' string ready for use in a CSS rule.
|
||||
*/
|
||||
goog.color.alpha.rgbaArrayToRgbaStyle = function(rgba) {
|
||||
return goog.color.alpha.rgbaToRgbaStyle(rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a color from HSLA to hex representation.
|
||||
* @param {Array<number>} hsla Array of [h, s, l, a], where h is an integer in
|
||||
* [0, 360], s and l are integers in [0, 100], and a is in [0, 1].
|
||||
* @return {string} hex representation of the color, such as '#af457eff'.
|
||||
*/
|
||||
goog.color.alpha.hslaArrayToHex = function(hsla) {
|
||||
return goog.color.alpha.hslaToHex(hsla[0], hsla[1], hsla[2], hsla[3]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a color from HSLA to an RGBA style string.
|
||||
* @param {Array<number>} hsla Array of [h, s, l, a], where h is and integer in
|
||||
* [0, 360], s and l are integers in [0, 100], and a is in [0, 1].
|
||||
* @return {string} An 'rgba(r,g,b,a)' string ready for use in a CSS rule.
|
||||
*/
|
||||
goog.color.alpha.hslaArrayToRgbaStyle = function(hsla) {
|
||||
return goog.color.alpha.hslaToRgbaStyle(hsla[0], hsla[1], hsla[2], hsla[3]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a color from HSLA to an RGBA style string.
|
||||
* @param {number} h Amount of hue, int between 0 and 360.
|
||||
* @param {number} s Amount of saturation, int between 0 and 100.
|
||||
* @param {number} l Amount of lightness, int between 0 and 100.
|
||||
* @param {number} a Amount of alpha, float between 0 and 1.
|
||||
* @return {string} An 'rgba(r,g,b,a)' string ready for use in a CSS rule.
|
||||
* styles.
|
||||
*/
|
||||
goog.color.alpha.hslaToRgbaStyle = function(h, s, l, a) {
|
||||
return goog.color.alpha.rgbaStyle_(goog.color.alpha.hslaToRgba(h, s, l, a));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a color from HSLA color space to RGBA color space.
|
||||
* @param {number} h Amount of hue, int between 0 and 360.
|
||||
* @param {number} s Amount of saturation, int between 0 and 100.
|
||||
* @param {number} l Amount of lightness, int between 0 and 100.
|
||||
* @param {number} a Amount of alpha, float between 0 and 1.
|
||||
* @return {!Array<number>} [r, g, b, a] values for the color, where r, g, b
|
||||
* are integers in [0, 255] and a is a float in [0, 1].
|
||||
*/
|
||||
goog.color.alpha.hslaToRgba = function(h, s, l, a) {
|
||||
return goog.color.hslToRgb(h, s / 100, l / 100).concat(a);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a color from RGBA color space to HSLA color space.
|
||||
* Modified from {@link http://en.wikipedia.org/wiki/HLS_color_space}.
|
||||
* @param {number} r Value of red, in [0, 255].
|
||||
* @param {number} g Value of green, in [0, 255].
|
||||
* @param {number} b Value of blue, in [0, 255].
|
||||
* @param {number} a Value of alpha, in [0, 255].
|
||||
* @return {!Array<number>} [h, s, l, a] values for the color, with h an int in
|
||||
* [0, 360] and s, l and a in [0, 1].
|
||||
*/
|
||||
goog.color.alpha.rgbaToHsla = function(r, g, b, a) {
|
||||
return goog.color.rgbToHsl(r, g, b).concat(a);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a color from RGBA color space to HSLA color space.
|
||||
* @param {Array<number>} rgba [r, g, b, a] values for the color, each in
|
||||
* [0, 255].
|
||||
* @return {!Array<number>} [h, s, l, a] values for the color, with h in
|
||||
* [0, 360] and s, l and a in [0, 1].
|
||||
*/
|
||||
goog.color.alpha.rgbaArrayToHsla = function(rgba) {
|
||||
return goog.color.alpha.rgbaToHsla(rgba[0], rgba[1], rgba[2], rgba[3]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper for isValidAlphaHexColor_.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.color.alpha.validAlphaHexColorRe_ = /^#(?:[0-9a-f]{4}){1,2}$/i;
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a string is a valid alpha hex color. We expect strings of the
|
||||
* format #RRGGBBAA (ex: #1b3d5f5b) or #RGBA (ex: #3CAF == #33CCAAFF).
|
||||
* @param {string} str String to check.
|
||||
* @return {boolean} Whether the string is a valid alpha hex color.
|
||||
* @private
|
||||
*/
|
||||
// TODO(user): Support percentages when goog.color also supports them.
|
||||
goog.color.alpha.isValidAlphaHexColor_ = function(str) {
|
||||
return goog.color.alpha.validAlphaHexColorRe_.test(str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper for isNormalizedAlphaHexColor_.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.color.alpha.normalizedAlphaHexColorRe_ = /^#[0-9a-f]{8}$/;
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a string is a normalized alpha hex color.
|
||||
* We expect strings of the format #RRGGBBAA (ex: #1b3d5f5b)
|
||||
* using only lowercase letters.
|
||||
* @param {string} str String to check.
|
||||
* @return {boolean} Whether the string is a normalized hex color.
|
||||
* @private
|
||||
*/
|
||||
goog.color.alpha.isNormalizedAlphaHexColor_ = function(str) {
|
||||
return goog.color.alpha.normalizedAlphaHexColorRe_.test(str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for matching and capturing RGBA style strings. Helper for
|
||||
* isValidRgbaColor_.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.color.alpha.rgbaColorRe_ =
|
||||
/^(?:rgba)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|1|0\.\d{0,10})\)$/i;
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for matching and capturing HSLA style strings. Helper for
|
||||
* isValidHslaColor_.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.color.alpha.hslaColorRe_ =
|
||||
/^(?:hsla)\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2})\%,\s?(0|[1-9]\d{0,2})\%,\s?(0|1|0\.\d{0,10})\)$/i;
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a string is a valid rgba color. We expect strings of the format
|
||||
* '(r, g, b, a)', or 'rgba(r, g, b, a)', where r, g, b are ints in [0, 255]
|
||||
* and a is a float in [0, 1].
|
||||
* @param {string} str String to check.
|
||||
* @return {!Array<number>} the integers [r, g, b, a] for valid colors or the
|
||||
* empty array for invalid colors.
|
||||
* @private
|
||||
*/
|
||||
goog.color.alpha.isValidRgbaColor_ = function(str) {
|
||||
// Each component is separate (rather than using a repeater) so we can
|
||||
// capture the match. Also, we explicitly set each component to be either 0,
|
||||
// or start with a non-zero, to prevent octal numbers from slipping through.
|
||||
var regExpResultArray = str.match(goog.color.alpha.rgbaColorRe_);
|
||||
if (regExpResultArray) {
|
||||
var r = Number(regExpResultArray[1]);
|
||||
var g = Number(regExpResultArray[2]);
|
||||
var b = Number(regExpResultArray[3]);
|
||||
var a = Number(regExpResultArray[4]);
|
||||
if (r >= 0 && r <= 255 &&
|
||||
g >= 0 && g <= 255 &&
|
||||
b >= 0 && b <= 255 &&
|
||||
a >= 0 && a <= 1) {
|
||||
return [r, g, b, a];
|
||||
}
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a string is a valid hsla color. We expect strings of the format
|
||||
* 'hsla(h, s, l, a)', where s in an int in [0, 360], s and l are percentages
|
||||
* between 0 and 100 such as '50%' or '70%', and a is a float in [0, 1].
|
||||
* @param {string} str String to check.
|
||||
* @return {!Array<number>} the integers [h, s, l, a] for valid colors or the
|
||||
* empty array for invalid colors.
|
||||
* @private
|
||||
*/
|
||||
goog.color.alpha.isValidHslaColor_ = function(str) {
|
||||
// Each component is separate (rather than using a repeater) so we can
|
||||
// capture the match. Also, we explicitly set each component to be either 0,
|
||||
// or start with a non-zero, to prevent octal numbers from slipping through.
|
||||
var regExpResultArray = str.match(goog.color.alpha.hslaColorRe_);
|
||||
if (regExpResultArray) {
|
||||
var h = Number(regExpResultArray[1]);
|
||||
var s = Number(regExpResultArray[2]);
|
||||
var l = Number(regExpResultArray[3]);
|
||||
var a = Number(regExpResultArray[4]);
|
||||
if (h >= 0 && h <= 360 &&
|
||||
s >= 0 && s <= 100 &&
|
||||
l >= 0 && l <= 100 &&
|
||||
a >= 0 && a <= 1) {
|
||||
return [h, s, l, a];
|
||||
}
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Takes an array of [r, g, b, a] and converts it into a string appropriate for
|
||||
* CSS styles. The alpha channel value is rounded to 3 decimal places to make
|
||||
* sure the produced string is not too long.
|
||||
* @param {Array<number>} rgba [r, g, b, a] with r, g, b in [0, 255] and a
|
||||
* in [0, 1].
|
||||
* @return {string} string of the form 'rgba(r,g,b,a)'.
|
||||
* @private
|
||||
*/
|
||||
goog.color.alpha.rgbaStyle_ = function(rgba) {
|
||||
var roundedRgba = rgba.slice(0);
|
||||
roundedRgba[3] = Math.round(rgba[3] * 1000) / 1000;
|
||||
return 'rgba(' + roundedRgba.join(',') + ')';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts from h,s,v,a values to a hex string
|
||||
* @param {number} h Hue, in [0, 1].
|
||||
* @param {number} s Saturation, in [0, 1].
|
||||
* @param {number} v Value, in [0, 255].
|
||||
* @param {number} a Alpha, in [0, 1].
|
||||
* @return {string} hex representation of the color.
|
||||
*/
|
||||
goog.color.alpha.hsvaToHex = function(h, s, v, a) {
|
||||
var alpha = Math.floor(a * 255);
|
||||
return goog.color.hsvArrayToHex([h, s, v]) +
|
||||
goog.color.prependZeroIfNecessaryHelper(alpha.toString(16));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts from an HSVA array to a hex string
|
||||
* @param {Array<number>} hsva Array of [h, s, v, a] in
|
||||
* [[0, 1], [0, 1], [0, 255], [0, 1]].
|
||||
* @return {string} hex representation of the color.
|
||||
*/
|
||||
goog.color.alpha.hsvaArrayToHex = function(hsva) {
|
||||
return goog.color.alpha.hsvaToHex(hsva[0], hsva[1], hsva[2], hsva[3]);
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>
|
||||
Closure Unit Tests - goog.color.alpha
|
||||
</title>
|
||||
<script src="../base.js">
|
||||
</script>
|
||||
<script>
|
||||
goog.require('goog.color.alphaTest');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
321
vectortile/closure-library/closure/goog/color/alpha_test.js
Normal file
321
vectortile/closure-library/closure/goog/color/alpha_test.js
Normal file
@@ -0,0 +1,321 @@
|
||||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
goog.provide('goog.color.alphaTest');
|
||||
goog.setTestOnly('goog.color.alphaTest');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.color');
|
||||
goog.require('goog.color.alpha');
|
||||
goog.require('goog.testing.jsunit');
|
||||
|
||||
function testIsValidAlphaHexColor() {
|
||||
var goodAlphaHexColors = ['#ffffffff', '#ff781259', '#01234567', '#Ff003DaB',
|
||||
'#3CAF', '#abcdefab', '#3CAB'];
|
||||
var badAlphaHexColors = ['#xxxxxxxx', '88990077', 'not_color', '#123456789',
|
||||
'fffffgfg'];
|
||||
for (var i = 0; i < goodAlphaHexColors.length; i++) {
|
||||
assertTrue(goodAlphaHexColors[i],
|
||||
goog.color.alpha.isValidAlphaHexColor_(goodAlphaHexColors[i]));
|
||||
}
|
||||
for (var i = 0; i < badAlphaHexColors.length; i++) {
|
||||
assertFalse(badAlphaHexColors[i],
|
||||
goog.color.alpha.isValidAlphaHexColor_(badAlphaHexColors[i]));
|
||||
}
|
||||
}
|
||||
|
||||
function testIsValidRgbaColor() {
|
||||
var goodRgbaColors = ['rgba(255, 0, 0, 1)', 'rgba(255,127,0,1)',
|
||||
'rgba(0,0,255,0.5)', '(255, 26, 75, 0.2)',
|
||||
'RGBA(0, 55, 0, 0.6)', 'rgba(0, 200, 0, 0.123456789)'];
|
||||
var badRgbaColors = ['(255, 0, 0)', '(2555,0,0, 0)', '(1,2,3,4,5)',
|
||||
'rgba(1,20,)', 'RGBA(20,20,20,)', 'RGBA',
|
||||
'rgba(255, 0, 0, 1.1)'];
|
||||
for (var i = 0; i < goodRgbaColors.length; i++) {
|
||||
assertEquals(goodRgbaColors[i], 4,
|
||||
goog.color.alpha.isValidRgbaColor_(goodRgbaColors[i]).length);
|
||||
}
|
||||
for (var i = 0; i < badRgbaColors.length; i++) {
|
||||
assertEquals(badRgbaColors[i], 0,
|
||||
goog.color.alpha.isValidRgbaColor_(badRgbaColors[i]).length);
|
||||
}
|
||||
}
|
||||
|
||||
function testIsValidHslaColor() {
|
||||
var goodHslaColors = ['hsla(120, 0%, 0%, 1)', 'hsla(360,20%,0%,1)',
|
||||
'hsla(0,0%,50%,0.5)', 'HSLA(0, 55%, 0%, 0.6)',
|
||||
'hsla(0, 85%, 0%, 0.123456789)'];
|
||||
var badHslaColors = ['(255, 0, 0, 0)', 'hsla(2555,0,0, 0)', 'hsla(1,2,3,4,5)',
|
||||
'hsla(1,20,)', 'HSLA(20,20,20,)',
|
||||
'hsla(255, 0, 0, 1.1)', 'HSLA'];
|
||||
for (var i = 0; i < goodHslaColors.length; i++) {
|
||||
assertEquals(goodHslaColors[i], 4,
|
||||
goog.color.alpha.isValidHslaColor_(goodHslaColors[i]).length);
|
||||
}
|
||||
for (var i = 0; i < badHslaColors.length; i++) {
|
||||
assertEquals(badHslaColors[i], 0,
|
||||
goog.color.alpha.isValidHslaColor_(badHslaColors[i]).length);
|
||||
}
|
||||
}
|
||||
|
||||
function testParse() {
|
||||
var colors = ['rgba(15, 250, 77, 0.5)', '(127, 127, 127, 0.8)', '#ffeeddaa',
|
||||
'12345678', 'hsla(160, 50%, 90%, 0.2)'];
|
||||
var parsed = goog.array.map(colors, goog.color.alpha.parse);
|
||||
assertEquals('rgba', parsed[0].type);
|
||||
assertEquals(goog.color.alpha.rgbaToHex(15, 250, 77, 0.5), parsed[0].hex);
|
||||
assertEquals('rgba', parsed[1].type);
|
||||
assertEquals(goog.color.alpha.rgbaToHex(127, 127, 127, 0.8), parsed[1].hex);
|
||||
assertEquals('hex', parsed[2].type);
|
||||
assertEquals('#ffeeddaa', parsed[2].hex);
|
||||
assertEquals('hex', parsed[3].type);
|
||||
assertEquals('#12345678', parsed[3].hex);
|
||||
assertEquals('hsla', parsed[4].type);
|
||||
assertEquals('#d9f2ea33', parsed[4].hex);
|
||||
|
||||
var badColors = ['rgb(01, 1, 23)', '(256, 256, 256)', '#ffeeddaa'];
|
||||
for (var i = 0; i < badColors.length; i++) {
|
||||
var e = assertThrows(badColors[i] + ' is not a valid color string',
|
||||
goog.partial(goog.color.parse, badColors[i]));
|
||||
assertContains('Error processing ' + badColors[i],
|
||||
'is not a valid color string', e.message);
|
||||
}
|
||||
}
|
||||
|
||||
function testHexToRgba() {
|
||||
var testColors = [['#B0FF2D66', [176, 255, 45, 0.4]],
|
||||
['#b26e5fcc', [178, 110, 95, 0.8]],
|
||||
['#66f3', [102, 102, 255, 0.2]]];
|
||||
|
||||
for (var i = 0; i < testColors.length; i++) {
|
||||
var r = goog.color.alpha.hexToRgba(testColors[i][0]);
|
||||
var t = testColors[i][1];
|
||||
|
||||
assertEquals('Red channel should match.', t[0], r[0]);
|
||||
assertEquals('Green channel should match.', t[1], r[1]);
|
||||
assertEquals('Blue channel should match.', t[2], r[2]);
|
||||
assertEquals('Alpha channel should match.', t[3], r[3]);
|
||||
}
|
||||
|
||||
var badColors = ['', '#g00', 'some words'];
|
||||
for (var i = 0; i < badColors.length; i++) {
|
||||
var e = assertThrows(
|
||||
goog.partial(goog.color.alpha.hexToRgba, badColors[i]));
|
||||
assertEquals("'" + badColors[i] + "' is not a valid alpha hex color",
|
||||
e.message);
|
||||
}
|
||||
}
|
||||
|
||||
function testHexToRgbaStyle() {
|
||||
assertEquals('rgba(255,0,0,1)',
|
||||
goog.color.alpha.hexToRgbaStyle('#ff0000ff'));
|
||||
assertEquals('rgba(206,206,206,0.8)',
|
||||
goog.color.alpha.hexToRgbaStyle('#cecececc'));
|
||||
assertEquals('rgba(51,204,170,0.2)',
|
||||
goog.color.alpha.hexToRgbaStyle('#3CA3'));
|
||||
assertEquals('rgba(1,2,3,0.016)',
|
||||
goog.color.alpha.hexToRgbaStyle('#01020304'));
|
||||
assertEquals('rgba(255,255,0,0.333)',
|
||||
goog.color.alpha.hexToRgbaStyle('#FFFF0055'));
|
||||
|
||||
var badHexColors = ['#12345', null, undefined, '#.1234567890'];
|
||||
for (var i = 0; i < badHexColors.length; ++i) {
|
||||
var e = assertThrows(badHexColors[i] + ' is an invalid hex color',
|
||||
goog.partial(goog.color.alpha.hexToRgbaStyle, badHexColors[i]));
|
||||
assertEquals("'" + badHexColors[i] + "' is not a valid alpha hex color",
|
||||
e.message);
|
||||
}
|
||||
}
|
||||
|
||||
function testRgbaToHex() {
|
||||
assertEquals('#af13ffff', goog.color.alpha.rgbaToHex(175, 19, 255, 1));
|
||||
assertEquals('#357cf099', goog.color.alpha.rgbaToHex(53, 124, 240, 0.6));
|
||||
var badRgba = [[-1, -1, -1, -1], [0, 0, 0, 2], ['a', 'b', 'c', 'd'],
|
||||
[undefined, 5, 5, 5]];
|
||||
for (var i = 0; i < badRgba.length; ++i) {
|
||||
var e = assertThrows(badRgba[i] + ' is not a valid rgba color',
|
||||
goog.partial(goog.color.alpha.rgbaArrayToHex, badRgba[i]));
|
||||
assertContains('is not a valid RGBA color', e.message);
|
||||
}
|
||||
}
|
||||
|
||||
function testRgbaToRgbaStyle() {
|
||||
var testColors = [[[175, 19, 255, 1], 'rgba(175,19,255,1)'],
|
||||
[[53, 124, 240, .6], 'rgba(53,124,240,0.6)'],
|
||||
[[10, 20, 30, .1234567], 'rgba(10,20,30,0.123)'],
|
||||
[[20, 30, 40, 1 / 3], 'rgba(20,30,40,0.333)']];
|
||||
|
||||
for (var i = 0; i < testColors.length; ++i) {
|
||||
var r = goog.color.alpha.rgbaToRgbaStyle(testColors[i][0][0],
|
||||
testColors[i][0][1],
|
||||
testColors[i][0][2],
|
||||
testColors[i][0][3]);
|
||||
assertEquals(testColors[i][1], r);
|
||||
}
|
||||
|
||||
var badColors = [[0, 0, 0, 2]];
|
||||
for (var i = 0; i < badColors.length; ++i) {
|
||||
var e = assertThrows(goog.partial(goog.color.alpha.rgbaToRgbaStyle,
|
||||
badColors[i][0], badColors[i][1], badColors[i][2], badColors[i][3]));
|
||||
|
||||
assertContains('is not a valid RGBA color', e.message);
|
||||
}
|
||||
|
||||
// Loop through all bad color values and ensure they fail in each channel.
|
||||
var badValues = [-1, 300, 'a', undefined, null, NaN];
|
||||
var color = [0, 0, 0, 0];
|
||||
for (var i = 0; i < badValues.length; ++i) {
|
||||
for (var channel = 0; channel < color.length; ++channel) {
|
||||
color[channel] = badValues[i];
|
||||
var e = assertThrows(color + ' is not a valid rgba color',
|
||||
goog.partial(goog.color.alpha.rgbaToRgbaStyle, color));
|
||||
assertContains('is not a valid RGBA color', e.message);
|
||||
|
||||
color[channel] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testRgbaArrayToRgbaStyle() {
|
||||
var testColors = [[[175, 19, 255, 1], 'rgba(175,19,255,1)'],
|
||||
[[53, 124, 240, .6], 'rgba(53,124,240,0.6)']];
|
||||
|
||||
for (var i = 0; i < testColors.length; ++i) {
|
||||
var r = goog.color.alpha.rgbaArrayToRgbaStyle(testColors[i][0]);
|
||||
assertEquals(testColors[i][1], r);
|
||||
}
|
||||
|
||||
var badColors = [[0, 0, 0, 2]];
|
||||
for (var i = 0; i < badColors.length; ++i) {
|
||||
var e = assertThrows(goog.partial(goog.color.alpha.rgbaArrayToRgbaStyle,
|
||||
badColors[i]));
|
||||
|
||||
assertContains('is not a valid RGBA color', e.message);
|
||||
}
|
||||
|
||||
// Loop through all bad color values and ensure they fail in each channel.
|
||||
var badValues = [-1, 300, 'a', undefined, null, NaN];
|
||||
var color = [0, 0, 0, 0];
|
||||
for (var i = 0; i < badValues.length; ++i) {
|
||||
for (var channel = 0; channel < color.length; ++channel) {
|
||||
color[channel] = badValues[i];
|
||||
var e = assertThrows(color + ' is not a valid rgba color',
|
||||
goog.partial(goog.color.alpha.rgbaToRgbaStyle, color));
|
||||
assertContains('is not a valid RGBA color', e.message);
|
||||
|
||||
color[channel] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function testRgbaArrayToHsla() {
|
||||
var opaqueBlueRgb = [0, 0, 255, 1];
|
||||
var opaqueBlueHsl = goog.color.alpha.rgbaArrayToHsla(opaqueBlueRgb);
|
||||
assertArrayEquals('Conversion from RGBA to HSLA should be as expected',
|
||||
[240, 1, 0.5, 1], opaqueBlueHsl);
|
||||
|
||||
var nearlyOpaqueYellowRgb = [255, 190, 0, 0.7];
|
||||
var nearlyOpaqueYellowHsl =
|
||||
goog.color.alpha.rgbaArrayToHsla(nearlyOpaqueYellowRgb);
|
||||
assertArrayEquals('Conversion from RGBA to HSLA should be as expected',
|
||||
[45, 1, 0.5, 0.7], nearlyOpaqueYellowHsl);
|
||||
|
||||
var transparentPurpleRgb = [180, 0, 255, 0];
|
||||
var transparentPurpleHsl =
|
||||
goog.color.alpha.rgbaArrayToHsla(transparentPurpleRgb);
|
||||
assertArrayEquals('Conversion from RGBA to HSLA should be as expected',
|
||||
[282, 1, 0.5, 0], transparentPurpleHsl);
|
||||
}
|
||||
|
||||
function testNormalizeAlphaHex() {
|
||||
var compactColor = '#abcd';
|
||||
var normalizedCompactColor =
|
||||
goog.color.alpha.normalizeAlphaHex_(compactColor);
|
||||
assertEquals('The color should have been normalized to the right length',
|
||||
'#aabbccdd', normalizedCompactColor);
|
||||
|
||||
var uppercaseColor = '#ABCDEF01';
|
||||
var normalizedUppercaseColor =
|
||||
goog.color.alpha.normalizeAlphaHex_(uppercaseColor);
|
||||
assertEquals('The color should have been normalized to lowercase',
|
||||
'#abcdef01', normalizedUppercaseColor);
|
||||
}
|
||||
|
||||
function testHsvaArrayToHex() {
|
||||
var opaqueSkyBlueHsv = [190, 1, 255, 1];
|
||||
var opaqueSkyBlueHex = goog.color.alpha.hsvaArrayToHex(opaqueSkyBlueHsv);
|
||||
assertEquals('The HSVA array should have been properly converted to hex',
|
||||
'#00d4ffff', opaqueSkyBlueHex);
|
||||
|
||||
var halfTransparentPinkHsv = [300, 1, 255, 0.5];
|
||||
var halfTransparentPinkHex =
|
||||
goog.color.alpha.hsvaArrayToHex(halfTransparentPinkHsv);
|
||||
assertEquals('The HSVA array should have been properly converted to hex',
|
||||
'#ff00ff7f', halfTransparentPinkHex);
|
||||
|
||||
var transparentDarkTurquoiseHsv = [175, 1, 127, 0.5];
|
||||
var transparentDarkTurquoiseHex =
|
||||
goog.color.alpha.hsvaArrayToHex(transparentDarkTurquoiseHsv);
|
||||
assertEquals('The HSVA array should have been properly converted to hex',
|
||||
'#007f747f', transparentDarkTurquoiseHex);
|
||||
}
|
||||
|
||||
function testExtractHexColor() {
|
||||
var opaqueRed = '#ff0000ff';
|
||||
var red = goog.color.alpha.extractHexColor(opaqueRed);
|
||||
assertEquals('The hex part of the color should have been extracted correctly',
|
||||
'#ff0000', red);
|
||||
|
||||
var halfOpaqueDarkGreenCompact = '#0507';
|
||||
var darkGreen =
|
||||
goog.color.alpha.extractHexColor(halfOpaqueDarkGreenCompact);
|
||||
assertEquals('The hex part of the color should have been extracted correctly',
|
||||
'#005500', darkGreen);
|
||||
|
||||
}
|
||||
|
||||
function testExtractAlpha() {
|
||||
var colors = ['#ff0000ff', '#0507', '#ff000005'];
|
||||
var expectedOpacities = ['ff', '77', '05'];
|
||||
|
||||
for (var i = 0; i < colors.length; i++) {
|
||||
var opacity = goog.color.alpha.extractAlpha(colors[i]);
|
||||
assertEquals('The alpha transparency should have been extracted correctly',
|
||||
expectedOpacities[i], opacity);
|
||||
}
|
||||
}
|
||||
|
||||
function testHslaArrayToRgbaStyle() {
|
||||
assertEquals('rgba(102,255,102,0.5)',
|
||||
goog.color.alpha.hslaArrayToRgbaStyle([120, 100, 70, 0.5]));
|
||||
assertEquals('rgba(28,23,23,0.9)',
|
||||
goog.color.alpha.hslaArrayToRgbaStyle([0, 10, 10, 0.9]));
|
||||
}
|
||||
|
||||
function testRgbaStyleParsableResult() {
|
||||
var testColors = [[175, 19, 255, 1],
|
||||
[53, 124, 240, .6],
|
||||
[20, 30, 40, 0.3333333],
|
||||
[255, 255, 255, 0.7071067811865476]];
|
||||
|
||||
for (var i = 0, testColor; testColor = testColors[i]; i++) {
|
||||
var rgbaStyle = goog.color.alpha.rgbaStyle_(testColor);
|
||||
var parsedColor = goog.color.alpha.hexToRgba(
|
||||
goog.color.alpha.parse(rgbaStyle).hex);
|
||||
assertEquals(testColor[0], parsedColor[0]);
|
||||
assertEquals(testColor[1], parsedColor[1]);
|
||||
assertEquals(testColor[2], parsedColor[2]);
|
||||
// Parsing keeps a 1/255 accuracy on the alpha channel.
|
||||
assertRoughlyEquals(testColor[3], parsedColor[3], 0.005);
|
||||
}
|
||||
}
|
||||
776
vectortile/closure-library/closure/goog/color/color.js
Normal file
776
vectortile/closure-library/closure/goog/color/color.js
Normal file
@@ -0,0 +1,776 @@
|
||||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Utilities related to color and color conversion.
|
||||
*/
|
||||
|
||||
goog.provide('goog.color');
|
||||
goog.provide('goog.color.Hsl');
|
||||
goog.provide('goog.color.Hsv');
|
||||
goog.provide('goog.color.Rgb');
|
||||
|
||||
goog.require('goog.color.names');
|
||||
goog.require('goog.math');
|
||||
|
||||
|
||||
/**
|
||||
* RGB color representation. An array containing three elements [r, g, b],
|
||||
* each an integer in [0, 255], representing the red, green, and blue components
|
||||
* of the color respectively.
|
||||
* @typedef {Array<number>}
|
||||
*/
|
||||
goog.color.Rgb;
|
||||
|
||||
|
||||
/**
|
||||
* HSV color representation. An array containing three elements [h, s, v]:
|
||||
* h (hue) must be an integer in [0, 360], cyclic.
|
||||
* s (saturation) must be a number in [0, 1].
|
||||
* v (value/brightness) must be an integer in [0, 255].
|
||||
* @typedef {Array<number>}
|
||||
*/
|
||||
goog.color.Hsv;
|
||||
|
||||
|
||||
/**
|
||||
* HSL color representation. An array containing three elements [h, s, l]:
|
||||
* h (hue) must be an integer in [0, 360], cyclic.
|
||||
* s (saturation) must be a number in [0, 1].
|
||||
* l (lightness) must be a number in [0, 1].
|
||||
* @typedef {Array<number>}
|
||||
*/
|
||||
goog.color.Hsl;
|
||||
|
||||
|
||||
/**
|
||||
* Parses a color out of a string.
|
||||
* @param {string} str Color in some format.
|
||||
* @return {{hex: string, type: string}} 'hex' is a string containing a hex
|
||||
* representation of the color, 'type' is a string containing the type
|
||||
* of color format passed in ('hex', 'rgb', 'named').
|
||||
*/
|
||||
goog.color.parse = function(str) {
|
||||
var result = {};
|
||||
str = String(str);
|
||||
|
||||
var maybeHex = goog.color.prependHashIfNecessaryHelper(str);
|
||||
if (goog.color.isValidHexColor_(maybeHex)) {
|
||||
result.hex = goog.color.normalizeHex(maybeHex);
|
||||
result.type = 'hex';
|
||||
return result;
|
||||
} else {
|
||||
var rgb = goog.color.isValidRgbColor_(str);
|
||||
if (rgb.length) {
|
||||
result.hex = goog.color.rgbArrayToHex(rgb);
|
||||
result.type = 'rgb';
|
||||
return result;
|
||||
} else if (goog.color.names) {
|
||||
var hex = goog.color.names[str.toLowerCase()];
|
||||
if (hex) {
|
||||
result.hex = hex;
|
||||
result.type = 'named';
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw Error(str + ' is not a valid color string');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Determines if the given string can be parsed as a color.
|
||||
* {@see goog.color.parse}.
|
||||
* @param {string} str Potential color string.
|
||||
* @return {boolean} True if str is in a format that can be parsed to a color.
|
||||
*/
|
||||
goog.color.isValidColor = function(str) {
|
||||
var maybeHex = goog.color.prependHashIfNecessaryHelper(str);
|
||||
return !!(goog.color.isValidHexColor_(maybeHex) ||
|
||||
goog.color.isValidRgbColor_(str).length ||
|
||||
goog.color.names && goog.color.names[str.toLowerCase()]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parses red, green, blue components out of a valid rgb color string.
|
||||
* Throws Error if the color string is invalid.
|
||||
* @param {string} str RGB representation of a color.
|
||||
* {@see goog.color.isValidRgbColor_}.
|
||||
* @return {!goog.color.Rgb} rgb representation of the color.
|
||||
*/
|
||||
goog.color.parseRgb = function(str) {
|
||||
var rgb = goog.color.isValidRgbColor_(str);
|
||||
if (!rgb.length) {
|
||||
throw Error(str + ' is not a valid RGB color');
|
||||
}
|
||||
return rgb;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a hex representation of a color to RGB.
|
||||
* @param {string} hexColor Color to convert.
|
||||
* @return {string} string of the form 'rgb(R,G,B)' which can be used in
|
||||
* styles.
|
||||
*/
|
||||
goog.color.hexToRgbStyle = function(hexColor) {
|
||||
return goog.color.rgbStyle_(goog.color.hexToRgb(hexColor));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for extracting the digits in a hex color triplet.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.color.hexTripletRe_ = /#(.)(.)(.)/;
|
||||
|
||||
|
||||
/**
|
||||
* Normalize an hex representation of a color
|
||||
* @param {string} hexColor an hex color string.
|
||||
* @return {string} hex color in the format '#rrggbb' with all lowercase
|
||||
* literals.
|
||||
*/
|
||||
goog.color.normalizeHex = function(hexColor) {
|
||||
if (!goog.color.isValidHexColor_(hexColor)) {
|
||||
throw Error("'" + hexColor + "' is not a valid hex color");
|
||||
}
|
||||
if (hexColor.length == 4) { // of the form #RGB
|
||||
hexColor = hexColor.replace(goog.color.hexTripletRe_, '#$1$1$2$2$3$3');
|
||||
}
|
||||
return hexColor.toLowerCase();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a hex representation of a color to RGB.
|
||||
* @param {string} hexColor Color to convert.
|
||||
* @return {!goog.color.Rgb} rgb representation of the color.
|
||||
*/
|
||||
goog.color.hexToRgb = function(hexColor) {
|
||||
hexColor = goog.color.normalizeHex(hexColor);
|
||||
var r = parseInt(hexColor.substr(1, 2), 16);
|
||||
var g = parseInt(hexColor.substr(3, 2), 16);
|
||||
var b = parseInt(hexColor.substr(5, 2), 16);
|
||||
|
||||
return [r, g, b];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a color from RGB to hex representation.
|
||||
* @param {number} r Amount of red, int between 0 and 255.
|
||||
* @param {number} g Amount of green, int between 0 and 255.
|
||||
* @param {number} b Amount of blue, int between 0 and 255.
|
||||
* @return {string} hex representation of the color.
|
||||
*/
|
||||
goog.color.rgbToHex = function(r, g, b) {
|
||||
r = Number(r);
|
||||
g = Number(g);
|
||||
b = Number(b);
|
||||
if (isNaN(r) || r < 0 || r > 255 ||
|
||||
isNaN(g) || g < 0 || g > 255 ||
|
||||
isNaN(b) || b < 0 || b > 255) {
|
||||
throw Error('"(' + r + ',' + g + ',' + b + '") is not a valid RGB color');
|
||||
}
|
||||
var hexR = goog.color.prependZeroIfNecessaryHelper(r.toString(16));
|
||||
var hexG = goog.color.prependZeroIfNecessaryHelper(g.toString(16));
|
||||
var hexB = goog.color.prependZeroIfNecessaryHelper(b.toString(16));
|
||||
return '#' + hexR + hexG + hexB;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a color from RGB to hex representation.
|
||||
* @param {goog.color.Rgb} rgb rgb representation of the color.
|
||||
* @return {string} hex representation of the color.
|
||||
*/
|
||||
goog.color.rgbArrayToHex = function(rgb) {
|
||||
return goog.color.rgbToHex(rgb[0], rgb[1], rgb[2]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a color from RGB color space to HSL color space.
|
||||
* Modified from {@link http://en.wikipedia.org/wiki/HLS_color_space}.
|
||||
* @param {number} r Value of red, in [0, 255].
|
||||
* @param {number} g Value of green, in [0, 255].
|
||||
* @param {number} b Value of blue, in [0, 255].
|
||||
* @return {!goog.color.Hsl} hsl representation of the color.
|
||||
*/
|
||||
goog.color.rgbToHsl = function(r, g, b) {
|
||||
// First must normalize r, g, b to be between 0 and 1.
|
||||
var normR = r / 255;
|
||||
var normG = g / 255;
|
||||
var normB = b / 255;
|
||||
var max = Math.max(normR, normG, normB);
|
||||
var min = Math.min(normR, normG, normB);
|
||||
var h = 0;
|
||||
var s = 0;
|
||||
|
||||
// Luminosity is the average of the max and min rgb color intensities.
|
||||
var l = 0.5 * (max + min);
|
||||
|
||||
// The hue and saturation are dependent on which color intensity is the max.
|
||||
// If max and min are equal, the color is gray and h and s should be 0.
|
||||
if (max != min) {
|
||||
if (max == normR) {
|
||||
h = 60 * (normG - normB) / (max - min);
|
||||
} else if (max == normG) {
|
||||
h = 60 * (normB - normR) / (max - min) + 120;
|
||||
} else if (max == normB) {
|
||||
h = 60 * (normR - normG) / (max - min) + 240;
|
||||
}
|
||||
|
||||
if (0 < l && l <= 0.5) {
|
||||
s = (max - min) / (2 * l);
|
||||
} else {
|
||||
s = (max - min) / (2 - 2 * l);
|
||||
}
|
||||
}
|
||||
|
||||
// Make sure the hue falls between 0 and 360.
|
||||
return [Math.round(h + 360) % 360, s, l];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a color from RGB color space to HSL color space.
|
||||
* @param {goog.color.Rgb} rgb rgb representation of the color.
|
||||
* @return {!goog.color.Hsl} hsl representation of the color.
|
||||
*/
|
||||
goog.color.rgbArrayToHsl = function(rgb) {
|
||||
return goog.color.rgbToHsl(rgb[0], rgb[1], rgb[2]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper for hslToRgb.
|
||||
* @param {number} v1 Helper variable 1.
|
||||
* @param {number} v2 Helper variable 2.
|
||||
* @param {number} vH Helper variable 3.
|
||||
* @return {number} Appropriate RGB value, given the above.
|
||||
* @private
|
||||
*/
|
||||
goog.color.hueToRgb_ = function(v1, v2, vH) {
|
||||
if (vH < 0) {
|
||||
vH += 1;
|
||||
} else if (vH > 1) {
|
||||
vH -= 1;
|
||||
}
|
||||
if ((6 * vH) < 1) {
|
||||
return (v1 + (v2 - v1) * 6 * vH);
|
||||
} else if (2 * vH < 1) {
|
||||
return v2;
|
||||
} else if (3 * vH < 2) {
|
||||
return (v1 + (v2 - v1) * ((2 / 3) - vH) * 6);
|
||||
}
|
||||
return v1;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a color from HSL color space to RGB color space.
|
||||
* Modified from {@link http://www.easyrgb.com/math.html}
|
||||
* @param {number} h Hue, in [0, 360].
|
||||
* @param {number} s Saturation, in [0, 1].
|
||||
* @param {number} l Luminosity, in [0, 1].
|
||||
* @return {!goog.color.Rgb} rgb representation of the color.
|
||||
*/
|
||||
goog.color.hslToRgb = function(h, s, l) {
|
||||
var r = 0;
|
||||
var g = 0;
|
||||
var b = 0;
|
||||
var normH = h / 360; // normalize h to fall in [0, 1]
|
||||
|
||||
if (s == 0) {
|
||||
r = g = b = l * 255;
|
||||
} else {
|
||||
var temp1 = 0;
|
||||
var temp2 = 0;
|
||||
if (l < 0.5) {
|
||||
temp2 = l * (1 + s);
|
||||
} else {
|
||||
temp2 = l + s - (s * l);
|
||||
}
|
||||
temp1 = 2 * l - temp2;
|
||||
r = 255 * goog.color.hueToRgb_(temp1, temp2, normH + (1 / 3));
|
||||
g = 255 * goog.color.hueToRgb_(temp1, temp2, normH);
|
||||
b = 255 * goog.color.hueToRgb_(temp1, temp2, normH - (1 / 3));
|
||||
}
|
||||
|
||||
return [Math.round(r), Math.round(g), Math.round(b)];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a color from HSL color space to RGB color space.
|
||||
* @param {goog.color.Hsl} hsl hsl representation of the color.
|
||||
* @return {!goog.color.Rgb} rgb representation of the color.
|
||||
*/
|
||||
goog.color.hslArrayToRgb = function(hsl) {
|
||||
return goog.color.hslToRgb(hsl[0], hsl[1], hsl[2]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper for isValidHexColor_.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.color.validHexColorRe_ = /^#(?:[0-9a-f]{3}){1,2}$/i;
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a string is a valid hex color. We expect strings of the format
|
||||
* #RRGGBB (ex: #1b3d5f) or #RGB (ex: #3CA == #33CCAA).
|
||||
* @param {string} str String to check.
|
||||
* @return {boolean} Whether the string is a valid hex color.
|
||||
* @private
|
||||
*/
|
||||
goog.color.isValidHexColor_ = function(str) {
|
||||
return goog.color.validHexColorRe_.test(str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper for isNormalizedHexColor_.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.color.normalizedHexColorRe_ = /^#[0-9a-f]{6}$/;
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a string is a normalized hex color.
|
||||
* We expect strings of the format #RRGGBB (ex: #1b3d5f)
|
||||
* using only lowercase letters.
|
||||
* @param {string} str String to check.
|
||||
* @return {boolean} Whether the string is a normalized hex color.
|
||||
* @private
|
||||
*/
|
||||
goog.color.isNormalizedHexColor_ = function(str) {
|
||||
return goog.color.normalizedHexColorRe_.test(str);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Regular expression for matching and capturing RGB style strings. Helper for
|
||||
* isValidRgbColor_.
|
||||
* @type {RegExp}
|
||||
* @private
|
||||
*/
|
||||
goog.color.rgbColorRe_ =
|
||||
/^(?:rgb)?\((0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2}),\s?(0|[1-9]\d{0,2})\)$/i;
|
||||
|
||||
|
||||
/**
|
||||
* Checks if a string is a valid rgb color. We expect strings of the format
|
||||
* '(r, g, b)', or 'rgb(r, g, b)', where each color component is an int in
|
||||
* [0, 255].
|
||||
* @param {string} str String to check.
|
||||
* @return {!goog.color.Rgb} the rgb representation of the color if it is
|
||||
* a valid color, or the empty array otherwise.
|
||||
* @private
|
||||
*/
|
||||
goog.color.isValidRgbColor_ = function(str) {
|
||||
// Each component is separate (rather than using a repeater) so we can
|
||||
// capture the match. Also, we explicitly set each component to be either 0,
|
||||
// or start with a non-zero, to prevent octal numbers from slipping through.
|
||||
var regExpResultArray = str.match(goog.color.rgbColorRe_);
|
||||
if (regExpResultArray) {
|
||||
var r = Number(regExpResultArray[1]);
|
||||
var g = Number(regExpResultArray[2]);
|
||||
var b = Number(regExpResultArray[3]);
|
||||
if (r >= 0 && r <= 255 &&
|
||||
g >= 0 && g <= 255 &&
|
||||
b >= 0 && b <= 255) {
|
||||
return [r, g, b];
|
||||
}
|
||||
}
|
||||
return [];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Takes a hex value and prepends a zero if it's a single digit.
|
||||
* Small helper method for use by goog.color and friends.
|
||||
* @param {string} hex Hex value to prepend if single digit.
|
||||
* @return {string} hex value prepended with zero if it was single digit,
|
||||
* otherwise the same value that was passed in.
|
||||
*/
|
||||
goog.color.prependZeroIfNecessaryHelper = function(hex) {
|
||||
return hex.length == 1 ? '0' + hex : hex;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Takes a string a prepends a '#' sign if one doesn't exist.
|
||||
* Small helper method for use by goog.color and friends.
|
||||
* @param {string} str String to check.
|
||||
* @return {string} The value passed in, prepended with a '#' if it didn't
|
||||
* already have one.
|
||||
*/
|
||||
goog.color.prependHashIfNecessaryHelper = function(str) {
|
||||
return str.charAt(0) == '#' ? str : '#' + str;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Takes an array of [r, g, b] and converts it into a string appropriate for
|
||||
* CSS styles.
|
||||
* @param {goog.color.Rgb} rgb rgb representation of the color.
|
||||
* @return {string} string of the form 'rgb(r,g,b)'.
|
||||
* @private
|
||||
*/
|
||||
goog.color.rgbStyle_ = function(rgb) {
|
||||
return 'rgb(' + rgb.join(',') + ')';
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts an HSV triplet to an RGB array. V is brightness because b is
|
||||
* reserved for blue in RGB.
|
||||
* @param {number} h Hue value in [0, 360].
|
||||
* @param {number} s Saturation value in [0, 1].
|
||||
* @param {number} brightness brightness in [0, 255].
|
||||
* @return {!goog.color.Rgb} rgb representation of the color.
|
||||
*/
|
||||
goog.color.hsvToRgb = function(h, s, brightness) {
|
||||
var red = 0;
|
||||
var green = 0;
|
||||
var blue = 0;
|
||||
if (s == 0) {
|
||||
red = brightness;
|
||||
green = brightness;
|
||||
blue = brightness;
|
||||
} else {
|
||||
var sextant = Math.floor(h / 60);
|
||||
var remainder = (h / 60) - sextant;
|
||||
var val1 = brightness * (1 - s);
|
||||
var val2 = brightness * (1 - (s * remainder));
|
||||
var val3 = brightness * (1 - (s * (1 - remainder)));
|
||||
switch (sextant) {
|
||||
case 1:
|
||||
red = val2;
|
||||
green = brightness;
|
||||
blue = val1;
|
||||
break;
|
||||
case 2:
|
||||
red = val1;
|
||||
green = brightness;
|
||||
blue = val3;
|
||||
break;
|
||||
case 3:
|
||||
red = val1;
|
||||
green = val2;
|
||||
blue = brightness;
|
||||
break;
|
||||
case 4:
|
||||
red = val3;
|
||||
green = val1;
|
||||
blue = brightness;
|
||||
break;
|
||||
case 5:
|
||||
red = brightness;
|
||||
green = val1;
|
||||
blue = val2;
|
||||
break;
|
||||
case 6:
|
||||
case 0:
|
||||
red = brightness;
|
||||
green = val3;
|
||||
blue = val1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return [Math.floor(red), Math.floor(green), Math.floor(blue)];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts from RGB values to an array of HSV values.
|
||||
* @param {number} red Red value in [0, 255].
|
||||
* @param {number} green Green value in [0, 255].
|
||||
* @param {number} blue Blue value in [0, 255].
|
||||
* @return {!goog.color.Hsv} hsv representation of the color.
|
||||
*/
|
||||
goog.color.rgbToHsv = function(red, green, blue) {
|
||||
|
||||
var max = Math.max(Math.max(red, green), blue);
|
||||
var min = Math.min(Math.min(red, green), blue);
|
||||
var hue;
|
||||
var saturation;
|
||||
var value = max;
|
||||
if (min == max) {
|
||||
hue = 0;
|
||||
saturation = 0;
|
||||
} else {
|
||||
var delta = (max - min);
|
||||
saturation = delta / max;
|
||||
|
||||
if (red == max) {
|
||||
hue = (green - blue) / delta;
|
||||
} else if (green == max) {
|
||||
hue = 2 + ((blue - red) / delta);
|
||||
} else {
|
||||
hue = 4 + ((red - green) / delta);
|
||||
}
|
||||
hue *= 60;
|
||||
if (hue < 0) {
|
||||
hue += 360;
|
||||
}
|
||||
if (hue > 360) {
|
||||
hue -= 360;
|
||||
}
|
||||
}
|
||||
|
||||
return [hue, saturation, value];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts from an array of RGB values to an array of HSV values.
|
||||
* @param {goog.color.Rgb} rgb rgb representation of the color.
|
||||
* @return {!goog.color.Hsv} hsv representation of the color.
|
||||
*/
|
||||
goog.color.rgbArrayToHsv = function(rgb) {
|
||||
return goog.color.rgbToHsv(rgb[0], rgb[1], rgb[2]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts an HSV triplet to an RGB array.
|
||||
* @param {goog.color.Hsv} hsv hsv representation of the color.
|
||||
* @return {!goog.color.Rgb} rgb representation of the color.
|
||||
*/
|
||||
goog.color.hsvArrayToRgb = function(hsv) {
|
||||
return goog.color.hsvToRgb(hsv[0], hsv[1], hsv[2]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a hex representation of a color to HSL.
|
||||
* @param {string} hex Color to convert.
|
||||
* @return {!goog.color.Hsv} hsv representation of the color.
|
||||
*/
|
||||
goog.color.hexToHsl = function(hex) {
|
||||
var rgb = goog.color.hexToRgb(hex);
|
||||
return goog.color.rgbToHsl(rgb[0], rgb[1], rgb[2]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts from h,s,l values to a hex string
|
||||
* @param {number} h Hue, in [0, 360].
|
||||
* @param {number} s Saturation, in [0, 1].
|
||||
* @param {number} l Luminosity, in [0, 1].
|
||||
* @return {string} hex representation of the color.
|
||||
*/
|
||||
goog.color.hslToHex = function(h, s, l) {
|
||||
return goog.color.rgbArrayToHex(goog.color.hslToRgb(h, s, l));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts from an hsl array to a hex string
|
||||
* @param {goog.color.Hsl} hsl hsl representation of the color.
|
||||
* @return {string} hex representation of the color.
|
||||
*/
|
||||
goog.color.hslArrayToHex = function(hsl) {
|
||||
return goog.color.rgbArrayToHex(goog.color.hslToRgb(hsl[0], hsl[1], hsl[2]));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a hex representation of a color to HSV
|
||||
* @param {string} hex Color to convert.
|
||||
* @return {!goog.color.Hsv} hsv representation of the color.
|
||||
*/
|
||||
goog.color.hexToHsv = function(hex) {
|
||||
return goog.color.rgbArrayToHsv(goog.color.hexToRgb(hex));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts from h,s,v values to a hex string
|
||||
* @param {number} h Hue, in [0, 360].
|
||||
* @param {number} s Saturation, in [0, 1].
|
||||
* @param {number} v Value, in [0, 255].
|
||||
* @return {string} hex representation of the color.
|
||||
*/
|
||||
goog.color.hsvToHex = function(h, s, v) {
|
||||
return goog.color.rgbArrayToHex(goog.color.hsvToRgb(h, s, v));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts from an HSV array to a hex string
|
||||
* @param {goog.color.Hsv} hsv hsv representation of the color.
|
||||
* @return {string} hex representation of the color.
|
||||
*/
|
||||
goog.color.hsvArrayToHex = function(hsv) {
|
||||
return goog.color.hsvToHex(hsv[0], hsv[1], hsv[2]);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calculates the Euclidean distance between two color vectors on an HSL sphere.
|
||||
* A demo of the sphere can be found at:
|
||||
* http://en.wikipedia.org/wiki/HSL_color_space
|
||||
* In short, a vector for color (H, S, L) in this system can be expressed as
|
||||
* (S*L'*cos(2*PI*H), S*L'*sin(2*PI*H), L), where L' = abs(L - 0.5), and we
|
||||
* simply calculate the 1-2 distance using these coordinates
|
||||
* @param {goog.color.Hsl} hsl1 First color in hsl representation.
|
||||
* @param {goog.color.Hsl} hsl2 Second color in hsl representation.
|
||||
* @return {number} Distance between the two colors, in the range [0, 1].
|
||||
*/
|
||||
goog.color.hslDistance = function(hsl1, hsl2) {
|
||||
var sl1, sl2;
|
||||
if (hsl1[2] <= 0.5) {
|
||||
sl1 = hsl1[1] * hsl1[2];
|
||||
} else {
|
||||
sl1 = hsl1[1] * (1.0 - hsl1[2]);
|
||||
}
|
||||
|
||||
if (hsl2[2] <= 0.5) {
|
||||
sl2 = hsl2[1] * hsl2[2];
|
||||
} else {
|
||||
sl2 = hsl2[1] * (1.0 - hsl2[2]);
|
||||
}
|
||||
|
||||
var h1 = hsl1[0] / 360.0;
|
||||
var h2 = hsl2[0] / 360.0;
|
||||
var dh = (h1 - h2) * 2.0 * Math.PI;
|
||||
return (hsl1[2] - hsl2[2]) * (hsl1[2] - hsl2[2]) +
|
||||
sl1 * sl1 + sl2 * sl2 - 2 * sl1 * sl2 * Math.cos(dh);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Blend two colors together, using the specified factor to indicate the weight
|
||||
* given to the first color
|
||||
* @param {goog.color.Rgb} rgb1 First color represented in rgb.
|
||||
* @param {goog.color.Rgb} rgb2 Second color represented in rgb.
|
||||
* @param {number} factor The weight to be given to rgb1 over rgb2. Values
|
||||
* should be in the range [0, 1]. If less than 0, factor will be set to 0.
|
||||
* If greater than 1, factor will be set to 1.
|
||||
* @return {!goog.color.Rgb} Combined color represented in rgb.
|
||||
*/
|
||||
goog.color.blend = function(rgb1, rgb2, factor) {
|
||||
factor = goog.math.clamp(factor, 0, 1);
|
||||
|
||||
return [
|
||||
Math.round(factor * rgb1[0] + (1.0 - factor) * rgb2[0]),
|
||||
Math.round(factor * rgb1[1] + (1.0 - factor) * rgb2[1]),
|
||||
Math.round(factor * rgb1[2] + (1.0 - factor) * rgb2[2])
|
||||
];
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds black to the specified color, darkening it
|
||||
* @param {goog.color.Rgb} rgb rgb representation of the color.
|
||||
* @param {number} factor Number in the range [0, 1]. 0 will do nothing, while
|
||||
* 1 will return black. If less than 0, factor will be set to 0. If greater
|
||||
* than 1, factor will be set to 1.
|
||||
* @return {!goog.color.Rgb} Combined rgb color.
|
||||
*/
|
||||
goog.color.darken = function(rgb, factor) {
|
||||
var black = [0, 0, 0];
|
||||
return goog.color.blend(black, rgb, factor);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Adds white to the specified color, lightening it
|
||||
* @param {goog.color.Rgb} rgb rgb representation of the color.
|
||||
* @param {number} factor Number in the range [0, 1]. 0 will do nothing, while
|
||||
* 1 will return white. If less than 0, factor will be set to 0. If greater
|
||||
* than 1, factor will be set to 1.
|
||||
* @return {!goog.color.Rgb} Combined rgb color.
|
||||
*/
|
||||
goog.color.lighten = function(rgb, factor) {
|
||||
var white = [255, 255, 255];
|
||||
return goog.color.blend(white, rgb, factor);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Find the "best" (highest-contrast) of the suggested colors for the prime
|
||||
* color. Uses W3C formula for judging readability and visual accessibility:
|
||||
* http://www.w3.org/TR/AERT#color-contrast
|
||||
* @param {goog.color.Rgb} prime Color represented as a rgb array.
|
||||
* @param {Array<goog.color.Rgb>} suggestions Array of colors,
|
||||
* each representing a rgb array.
|
||||
* @return {!goog.color.Rgb} Highest-contrast color represented by an array..
|
||||
*/
|
||||
goog.color.highContrast = function(prime, suggestions) {
|
||||
var suggestionsWithDiff = [];
|
||||
for (var i = 0; i < suggestions.length; i++) {
|
||||
suggestionsWithDiff.push({
|
||||
color: suggestions[i],
|
||||
diff: goog.color.yiqBrightnessDiff_(suggestions[i], prime) +
|
||||
goog.color.colorDiff_(suggestions[i], prime)
|
||||
});
|
||||
}
|
||||
suggestionsWithDiff.sort(function(a, b) {
|
||||
return b.diff - a.diff;
|
||||
});
|
||||
return suggestionsWithDiff[0].color;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calculate brightness of a color according to YIQ formula (brightness is Y).
|
||||
* More info on YIQ here: http://en.wikipedia.org/wiki/YIQ. Helper method for
|
||||
* goog.color.highContrast()
|
||||
* @param {goog.color.Rgb} rgb Color represented by a rgb array.
|
||||
* @return {number} brightness (Y).
|
||||
* @private
|
||||
*/
|
||||
goog.color.yiqBrightness_ = function(rgb) {
|
||||
return Math.round((rgb[0] * 299 + rgb[1] * 587 + rgb[2] * 114) / 1000);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calculate difference in brightness of two colors. Helper method for
|
||||
* goog.color.highContrast()
|
||||
* @param {goog.color.Rgb} rgb1 Color represented by a rgb array.
|
||||
* @param {goog.color.Rgb} rgb2 Color represented by a rgb array.
|
||||
* @return {number} Brightness difference.
|
||||
* @private
|
||||
*/
|
||||
goog.color.yiqBrightnessDiff_ = function(rgb1, rgb2) {
|
||||
return Math.abs(goog.color.yiqBrightness_(rgb1) -
|
||||
goog.color.yiqBrightness_(rgb2));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Calculate color difference between two colors. Helper method for
|
||||
* goog.color.highContrast()
|
||||
* @param {goog.color.Rgb} rgb1 Color represented by a rgb array.
|
||||
* @param {goog.color.Rgb} rgb2 Color represented by a rgb array.
|
||||
* @return {number} Color difference.
|
||||
* @private
|
||||
*/
|
||||
goog.color.colorDiff_ = function(rgb1, rgb2) {
|
||||
return Math.abs(rgb1[0] - rgb2[0]) + Math.abs(rgb1[1] - rgb2[1]) +
|
||||
Math.abs(rgb1[2] - rgb2[2]);
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>
|
||||
Closure Unit Tests - goog.color
|
||||
</title>
|
||||
<script src="../base.js">
|
||||
</script>
|
||||
<script>
|
||||
goog.require('goog.colorTest');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
667
vectortile/closure-library/closure/goog/color/color_test.js
Normal file
667
vectortile/closure-library/closure/goog/color/color_test.js
Normal file
@@ -0,0 +1,667 @@
|
||||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
goog.provide('goog.colorTest');
|
||||
goog.setTestOnly('goog.colorTest');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.color');
|
||||
goog.require('goog.color.names');
|
||||
goog.require('goog.testing.jsunit');
|
||||
|
||||
function testIsValidColor() {
|
||||
var goodColors = ['#ffffff', '#ff7812', '#012345', '#Ff003D', '#3CA',
|
||||
'(255, 26, 75)', 'RGB(2, 3, 4)', '(0,0,0)', 'white',
|
||||
'blue'];
|
||||
var badColors = ['#xxxxxx', '8899000', 'not_color', '#1234567', 'fffffg',
|
||||
'(2555,0,0)', '(1,2,3,4)', 'rgb(1,20,)', 'RGB(20,20,20,)',
|
||||
'omgwtfbbq'];
|
||||
for (var i = 0; i < goodColors.length; i++) {
|
||||
assertTrue(goodColors[i], goog.color.isValidColor(goodColors[i]));
|
||||
}
|
||||
for (var i = 0; i < badColors.length; i++) {
|
||||
assertFalse(badColors[i], goog.color.isValidColor(badColors[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function testIsValidHexColor() {
|
||||
var goodHexColors = ['#ffffff', '#ff7812', '#012345', '#Ff003D', '#3CA'];
|
||||
var badHexColors = ['#xxxxxx', '889900', 'not_color', '#1234567', 'fffffg'];
|
||||
for (var i = 0; i < goodHexColors.length; i++) {
|
||||
assertTrue(goodHexColors[i], goog.color.isValidHexColor_(goodHexColors[i]));
|
||||
}
|
||||
for (var i = 0; i < badHexColors.length; i++) {
|
||||
assertFalse(badHexColors[i], goog.color.isValidHexColor_(badHexColors[i]));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function testIsValidRgbColor() {
|
||||
var goodRgbColors = ['(255, 26, 75)', 'RGB(2, 3, 4)', '(0,0,0)',
|
||||
'rgb(255,255,255)'];
|
||||
var badRgbColors = ['(2555,0,0)', '(1,2,3,4)', 'rgb(1,20,)',
|
||||
'RGB(20,20,20,)'];
|
||||
for (var i = 0; i < goodRgbColors.length; i++) {
|
||||
assertEquals(goodRgbColors[i],
|
||||
goog.color.isValidRgbColor_(goodRgbColors[i]).length, 3);
|
||||
}
|
||||
for (var i = 0; i < badRgbColors.length; i++) {
|
||||
assertEquals(badRgbColors[i],
|
||||
goog.color.isValidRgbColor_(badRgbColors[i]).length, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function testParse() {
|
||||
var colors = ['rgb(15, 250, 77)', '(127, 127, 127)', '#ffeedd', '123456',
|
||||
'magenta'];
|
||||
var parsed = goog.array.map(colors, goog.color.parse);
|
||||
assertEquals('rgb', parsed[0].type);
|
||||
assertEquals(goog.color.rgbToHex(15, 250, 77), parsed[0].hex);
|
||||
assertEquals('rgb', parsed[1].type);
|
||||
assertEquals(goog.color.rgbToHex(127, 127, 127), parsed[1].hex);
|
||||
assertEquals('hex', parsed[2].type);
|
||||
assertEquals('#ffeedd', parsed[2].hex);
|
||||
assertEquals('hex', parsed[3].type);
|
||||
assertEquals('#123456', parsed[3].hex);
|
||||
assertEquals('named', parsed[4].type);
|
||||
assertEquals('#ff00ff', parsed[4].hex);
|
||||
|
||||
var badColors = ['rgb(01, 1, 23)', '(256, 256, 256)', '#ffeeddaa'];
|
||||
for (var i = 0; i < badColors.length; i++) {
|
||||
var e = assertThrows(goog.partial(goog.color.parse, badColors[i]));
|
||||
assertContains('is not a valid color string', e.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function testHexToRgb() {
|
||||
var testColors = [['#B0FF2D', [176, 255, 45]],
|
||||
['#b26e5f', [178, 110, 95]],
|
||||
['#66f', [102, 102, 255]]];
|
||||
|
||||
for (var i = 0; i < testColors.length; i++) {
|
||||
var r = goog.color.hexToRgb(testColors[i][0]);
|
||||
var t = testColors[i][1];
|
||||
|
||||
assertEquals('Red channel should match.', t[0], r[0]);
|
||||
assertEquals('Green channel should match.', t[1], r[1]);
|
||||
assertEquals('Blue channel should match.', t[2], r[2]);
|
||||
}
|
||||
|
||||
var badColors = ['', '#g00', 'some words'];
|
||||
for (var i = 0; i < badColors.length; i++) {
|
||||
var e = assertThrows(goog.partial(goog.color.hexToRgb, badColors[i]));
|
||||
assertEquals("'" + badColors[i] + "' is not a valid hex color", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function testHexToRgbStyle() {
|
||||
assertEquals('rgb(255,0,0)', goog.color.hexToRgbStyle(goog.color.names.red));
|
||||
assertEquals('rgb(206,206,206)', goog.color.hexToRgbStyle('#cecece'));
|
||||
assertEquals('rgb(51,204,170)', goog.color.hexToRgbStyle('#3CA'));
|
||||
var badHexColors = ['#1234', null, undefined, '#.1234567890'];
|
||||
for (var i = 0; i < badHexColors.length; ++i) {
|
||||
var badHexColor = badHexColors[i];
|
||||
var e = assertThrows(goog.partial(goog.color.hexToRgbStyle, badHexColor));
|
||||
assertEquals("'" + badHexColor + "' is not a valid hex color", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function testRgbToHex() {
|
||||
assertEquals(goog.color.names.red, goog.color.rgbToHex(255, 0, 0));
|
||||
assertEquals('#af13ff', goog.color.rgbToHex(175, 19, 255));
|
||||
var badRgb = [[-1, -1, -1], [256, 0, 0], ['a', 'b', 'c'], [undefined, 5, 5]];
|
||||
for (var i = 0; i < badRgb.length; ++i) {
|
||||
var e = assertThrows(goog.partial(goog.color.rgbArrayToHex, badRgb[i]));
|
||||
assertContains('is not a valid RGB color', e.message);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function testRgbToHsl() {
|
||||
var rgb = [255, 171, 32];
|
||||
var hsl = goog.color.rgbArrayToHsl(rgb);
|
||||
assertEquals(37, hsl[0]);
|
||||
assertTrue(1.0 - hsl[1] < 0.01);
|
||||
assertTrue(hsl[2] - .5625 < 0.01);
|
||||
}
|
||||
|
||||
|
||||
function testHslToRgb() {
|
||||
var hsl = [60, 0.5, 0.1];
|
||||
var rgb = goog.color.hslArrayToRgb(hsl);
|
||||
assertEquals(38, rgb[0]);
|
||||
assertEquals(38, rgb[1]);
|
||||
assertEquals(13, rgb[2]);
|
||||
}
|
||||
|
||||
|
||||
// Tests accuracy of HSL to RGB conversion
|
||||
function testHSLBidiToRGB() {
|
||||
var DELTA = 1;
|
||||
|
||||
var color = [[100, 56, 200],
|
||||
[255, 0, 0],
|
||||
[0, 0, 255],
|
||||
[0, 255, 0],
|
||||
[255, 255, 255],
|
||||
[0, 0, 0]];
|
||||
|
||||
for (var i = 0; i < color.length; i++) {
|
||||
colorConversionTestHelper(
|
||||
function(color) {
|
||||
return goog.color.rgbToHsl(color[0], color[1], color[2]);
|
||||
},
|
||||
function(color) {
|
||||
return goog.color.hslToRgb(color[0], color[1], color[2]);
|
||||
},
|
||||
color[i], DELTA);
|
||||
|
||||
colorConversionTestHelper(
|
||||
function(color) { return goog.color.rgbArrayToHsl(color); },
|
||||
function(color) { return goog.color.hslArrayToRgb(color); },
|
||||
color[i], DELTA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Tests HSV to RGB conversion
|
||||
function testHSVToRGB() {
|
||||
var DELTA = 1;
|
||||
|
||||
var color = [[100, 56, 200],
|
||||
[255, 0, 0],
|
||||
[0, 0, 255],
|
||||
[0, 255, 0],
|
||||
[255, 255, 255],
|
||||
[0, 0, 0]];
|
||||
|
||||
for (var i = 0; i < color.length; i++) {
|
||||
colorConversionTestHelper(
|
||||
function(color) {
|
||||
return goog.color.rgbToHsv(color[0], color[1], color[2]);
|
||||
},
|
||||
function(color) {
|
||||
return goog.color.hsvToRgb(color[0], color[1], color[2]);
|
||||
},
|
||||
color[i], DELTA);
|
||||
|
||||
colorConversionTestHelper(
|
||||
function(color) { return goog.color.rgbArrayToHsv(color); },
|
||||
function(color) { return goog.color.hsvArrayToRgb(color); },
|
||||
color[i], DELTA);
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that HSV space is (0-360) for hue
|
||||
function testHSVSpecRangeIsCorrect() {
|
||||
var color = [0, 0, 255]; // Blue is in the middle of hue range
|
||||
|
||||
var hsv = goog.color.rgbToHsv(color[0], color[1], color[2]);
|
||||
|
||||
assertTrue("H in HSV space looks like it's not 0-360", hsv[0] > 1);
|
||||
}
|
||||
|
||||
// Tests conversion between HSL and Hex
|
||||
function testHslToHex() {
|
||||
var DELTA = 1;
|
||||
|
||||
var color = [[0, 0, 0],
|
||||
[20, 0.5, 0.5],
|
||||
[0, 0, 1],
|
||||
[255, .45, .76]];
|
||||
|
||||
for (var i = 0; i < color.length; i++) {
|
||||
colorConversionTestHelper(
|
||||
function(hsl) { return goog.color.hslToHex(hsl[0], hsl[1], hsl[2]); },
|
||||
function(hex) { return goog.color.hexToHsl(hex); },
|
||||
color[i], DELTA);
|
||||
|
||||
colorConversionTestHelper(
|
||||
function(hsl) { return goog.color.hslArrayToHex(hsl); },
|
||||
function(hex) { return goog.color.hexToHsl(hex); },
|
||||
color[i], DELTA);
|
||||
}
|
||||
}
|
||||
|
||||
// Tests conversion between HSV and Hex
|
||||
function testHsvToHex() {
|
||||
var DELTA = 1;
|
||||
|
||||
var color = [[0, 0, 0],
|
||||
[.5, 0.5, 155],
|
||||
[0, 0, 255],
|
||||
[.7, .45, 21]];
|
||||
|
||||
for (var i = 0; i < color.length; i++) {
|
||||
colorConversionTestHelper(
|
||||
function(hsl) { return goog.color.hsvToHex(hsl[0], hsl[1], hsl[2]); },
|
||||
function(hex) { return goog.color.hexToHsv(hex); },
|
||||
color[i], DELTA);
|
||||
|
||||
colorConversionTestHelper(
|
||||
function(hsl) { return goog.color.hsvArrayToHex(hsl); },
|
||||
function(hex) { return goog.color.hexToHsv(hex); },
|
||||
color[i], DELTA);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This helper method compares two RGB colors, checking that each color
|
||||
* component is the same.
|
||||
* @param {Array<number>} rgb1 Color represented by a 3-element array with
|
||||
* red, green, and blue values respectively, in the range [0, 255].
|
||||
* @param {Array<number>} rgb2 Color represented by a 3-element array with
|
||||
* red, green, and blue values respectively, in the range [0, 255].
|
||||
* @return {boolean} True if the colors are the same, false otherwise.
|
||||
*/
|
||||
function rgbColorsAreEqual(rgb1, rgb2) {
|
||||
return (rgb1[0] == rgb2[0] &&
|
||||
rgb1[1] == rgb2[1] &&
|
||||
rgb1[2] == rgb2[2]);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method runs unit tests against goog.color.blend(). Test cases include:
|
||||
* blending arbitrary colors with factors of 0 and 1, blending the same colors
|
||||
* using arbitrary factors, blending different colors of varying factors,
|
||||
* and blending colors using factors outside the expected range.
|
||||
*/
|
||||
function testColorBlend() {
|
||||
// Define some RGB colors for our tests.
|
||||
var black = [0, 0, 0];
|
||||
var blue = [0, 0, 255];
|
||||
var gray = [128, 128, 128];
|
||||
var green = [0, 255, 0];
|
||||
var purple = [128, 0, 128];
|
||||
var red = [255, 0, 0];
|
||||
var yellow = [255, 255, 0];
|
||||
var white = [255, 255, 255];
|
||||
|
||||
// Blend arbitrary colors, using 0 and 1 for factors. Using 0 should return
|
||||
// the first color, while using 1 should return the second color.
|
||||
var redWithNoGreen = goog.color.blend(red, green, 1);
|
||||
assertTrue('red + 0 * green = red',
|
||||
rgbColorsAreEqual(red, redWithNoGreen));
|
||||
var whiteWithAllBlue = goog.color.blend(white, blue, 0);
|
||||
assertTrue('white + 1 * blue = blue',
|
||||
rgbColorsAreEqual(blue, whiteWithAllBlue));
|
||||
|
||||
// Blend the same colors using arbitrary factors. This should return the
|
||||
// same colors.
|
||||
var greenWithGreen = goog.color.blend(green, green, .25);
|
||||
assertTrue('green + .25 * green = green',
|
||||
rgbColorsAreEqual(green, greenWithGreen));
|
||||
|
||||
// Blend different colors using varying factors.
|
||||
var blackWithWhite = goog.color.blend(black, white, .5);
|
||||
assertTrue('black + .5 * white = gray',
|
||||
rgbColorsAreEqual(gray, blackWithWhite));
|
||||
var redAndBlue = goog.color.blend(red, blue, .5);
|
||||
assertTrue('red + .5 * blue = purple',
|
||||
rgbColorsAreEqual(purple, redAndBlue));
|
||||
var lightGreen = goog.color.blend(green, white, .75);
|
||||
assertTrue('green + .25 * white = a lighter shade of white',
|
||||
lightGreen[0] > 0 &&
|
||||
lightGreen[1] == 255 &&
|
||||
lightGreen[2] > 0);
|
||||
|
||||
// Blend arbitrary colors using factors outside the expected range.
|
||||
var noGreenAllPurple = goog.color.blend(green, purple, -0.5);
|
||||
assertTrue('green * -0.5 + purple = purple.',
|
||||
rgbColorsAreEqual(purple, noGreenAllPurple));
|
||||
var allBlueNoYellow = goog.color.blend(blue, yellow, 1.37);
|
||||
assertTrue('blue * 1.37 + yellow = blue.',
|
||||
rgbColorsAreEqual(blue, allBlueNoYellow));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method runs unit tests against goog.color.darken(). Test cases
|
||||
* include darkening black with arbitrary factors, edge cases (using 0 and 1),
|
||||
* darkening colors using various factors, and darkening colors using factors
|
||||
* outside the expected range.
|
||||
*/
|
||||
function testColorDarken() {
|
||||
// Define some RGB colors
|
||||
var black = [0, 0, 0];
|
||||
var green = [0, 255, 0];
|
||||
var darkGray = [68, 68, 68];
|
||||
var olive = [128, 128, 0];
|
||||
var purple = [128, 0, 128];
|
||||
var white = [255, 255, 255];
|
||||
|
||||
// Darken black by an arbitrary factor, which should still return black.
|
||||
var darkBlack = goog.color.darken(black, .63);
|
||||
assertTrue('black darkened by .63 is still black.',
|
||||
rgbColorsAreEqual(black, darkBlack));
|
||||
|
||||
// Call darken() with edge-case factors (0 and 1).
|
||||
var greenNotDarkened = goog.color.darken(green, 0);
|
||||
assertTrue('green darkened by 0 is still green.',
|
||||
rgbColorsAreEqual(green, greenNotDarkened));
|
||||
var whiteFullyDarkened = goog.color.darken(white, 1);
|
||||
assertTrue('white darkened by 1 is black.',
|
||||
rgbColorsAreEqual(black, whiteFullyDarkened));
|
||||
|
||||
// Call darken() with various colors and factors. The result should be
|
||||
// a color with less luminance.
|
||||
var whiteHsl = goog.color.rgbToHsl(white[0],
|
||||
white[1],
|
||||
white[2]);
|
||||
var whiteDarkened = goog.color.darken(white, .43);
|
||||
var whiteDarkenedHsl = goog.color.rgbToHsl(whiteDarkened[0],
|
||||
whiteDarkened[1],
|
||||
whiteDarkened[2]);
|
||||
assertTrue('White that\'s darkened has less luminance than white.',
|
||||
whiteDarkenedHsl[2] < whiteHsl[2]);
|
||||
var purpleHsl = goog.color.rgbToHsl(purple[0],
|
||||
purple[1],
|
||||
purple[2]);
|
||||
var purpleDarkened = goog.color.darken(purple, .1);
|
||||
var purpleDarkenedHsl = goog.color.rgbToHsl(purpleDarkened[0],
|
||||
purpleDarkened[1],
|
||||
purpleDarkened[2]);
|
||||
assertTrue('Purple that\'s darkened has less luminance than purple.',
|
||||
purpleDarkenedHsl[2] < purpleHsl[2]);
|
||||
|
||||
// Call darken() with factors outside the expected range.
|
||||
var darkGrayTurnedBlack = goog.color.darken(darkGray, 2.1);
|
||||
assertTrue('Darkening dark gray by 2.1 returns black.',
|
||||
rgbColorsAreEqual(black, darkGrayTurnedBlack));
|
||||
var whiteNotDarkened = goog.color.darken(white, -0.62);
|
||||
assertTrue('Darkening white by -0.62 returns white.',
|
||||
rgbColorsAreEqual(white, whiteNotDarkened));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method runs unit tests against goog.color.lighten(). Test cases
|
||||
* include lightening white with arbitrary factors, edge cases (using 0 and 1),
|
||||
* lightening colors using various factors, and lightening colors using factors
|
||||
* outside the expected range.
|
||||
*/
|
||||
function testColorLighten() {
|
||||
// Define some RGB colors
|
||||
var black = [0, 0, 0];
|
||||
var brown = [165, 42, 42];
|
||||
var navy = [0, 0, 128];
|
||||
var orange = [255, 165, 0];
|
||||
var white = [255, 255, 255];
|
||||
|
||||
// Lighten white by an arbitrary factor, which should still return white.
|
||||
var lightWhite = goog.color.lighten(white, .41);
|
||||
assertTrue('white lightened by .41 is still white.',
|
||||
rgbColorsAreEqual(white, lightWhite));
|
||||
|
||||
// Call lighten() with edge-case factors(0 and 1).
|
||||
var navyNotLightened = goog.color.lighten(navy, 0);
|
||||
assertTrue('navy lightened by 0 is still navy.',
|
||||
rgbColorsAreEqual(navy, navyNotLightened));
|
||||
var orangeFullyLightened = goog.color.lighten(orange, 1);
|
||||
assertTrue('orange lightened by 1 is white.',
|
||||
rgbColorsAreEqual(white, orangeFullyLightened));
|
||||
|
||||
// Call lighten() with various colors and factors. The result should be
|
||||
// a color with greater luminance.
|
||||
var blackHsl = goog.color.rgbToHsl(black[0],
|
||||
black[1],
|
||||
black[2]);
|
||||
var blackLightened = goog.color.lighten(black, .33);
|
||||
var blackLightenedHsl = goog.color.rgbToHsl(blackLightened[0],
|
||||
blackLightened[1],
|
||||
blackLightened[2]);
|
||||
assertTrue('Black that\'s lightened has more luminance than black.',
|
||||
blackLightenedHsl[2] >= blackHsl[2]);
|
||||
var orangeHsl = goog.color.rgbToHsl(orange[0],
|
||||
orange[1],
|
||||
orange[2]);
|
||||
var orangeLightened = goog.color.lighten(orange, .91);
|
||||
var orangeLightenedHsl = goog.color.rgbToHsl(orangeLightened[0],
|
||||
orangeLightened[1],
|
||||
orangeLightened[2]);
|
||||
assertTrue('Orange that\'s lightened has more luminance than orange.',
|
||||
orangeLightenedHsl[2] >= orangeHsl[2]);
|
||||
|
||||
// Call lighten() with factors outside the expected range.
|
||||
var navyTurnedWhite = goog.color.lighten(navy, 1.01);
|
||||
assertTrue('Lightening navy by 1.01 returns white.',
|
||||
rgbColorsAreEqual(white, navyTurnedWhite));
|
||||
var brownNotLightened = goog.color.lighten(brown, -0.0000001);
|
||||
assertTrue('Lightening brown by -0.0000001 returns brown.',
|
||||
rgbColorsAreEqual(brown, brownNotLightened));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method runs unit tests against goog.color.hslDistance().
|
||||
*/
|
||||
function testHslDistance() {
|
||||
// Define some HSL colors
|
||||
var aliceBlueHsl = goog.color.rgbToHsl(240, 248, 255);
|
||||
var blackHsl = goog.color.rgbToHsl(0, 0, 0);
|
||||
var ghostWhiteHsl = goog.color.rgbToHsl(248, 248, 255);
|
||||
var navyHsl = goog.color.rgbToHsl(0, 0, 128);
|
||||
var redHsl = goog.color.rgbToHsl(255, 0, 0);
|
||||
var whiteHsl = goog.color.rgbToHsl(255, 255, 255);
|
||||
|
||||
// The distance between the same colors should be 0.
|
||||
assertTrue('There is no HSL distance between white and white.',
|
||||
goog.color.hslDistance(whiteHsl, whiteHsl) == 0);
|
||||
assertTrue('There is no HSL distance between red and red.',
|
||||
goog.color.hslDistance(redHsl, redHsl) == 0);
|
||||
|
||||
// The distance between various colors should be within certain thresholds.
|
||||
var hslDistance = goog.color.hslDistance(whiteHsl, ghostWhiteHsl);
|
||||
assertTrue('The HSL distance between white and ghost white is > 0.',
|
||||
hslDistance > 0);
|
||||
assertTrue('The HSL distance between white and ghost white is <= 0.02.',
|
||||
hslDistance <= 0.02);
|
||||
hslDistance = goog.color.hslDistance(whiteHsl, redHsl);
|
||||
assertTrue('The HSL distance betwen white and red is > 0.02.',
|
||||
hslDistance > 0.02);
|
||||
hslDistance = goog.color.hslDistance(navyHsl, aliceBlueHsl);
|
||||
assertTrue('The HSL distance between navy and alice blue is > 0.02.',
|
||||
hslDistance > 0.02);
|
||||
hslDistance = goog.color.hslDistance(blackHsl, whiteHsl);
|
||||
assertTrue('The HSL distance between white and black is 1.',
|
||||
hslDistance == 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method runs unit tests against goog.color.yiqBrightness_().
|
||||
*/
|
||||
function testYiqBrightness() {
|
||||
var white = [255, 255, 255];
|
||||
var black = [0, 0, 0];
|
||||
var coral = [255, 127, 80];
|
||||
var lightgreen = [144, 238, 144];
|
||||
|
||||
var whiteBrightness = goog.color.yiqBrightness_(white);
|
||||
var blackBrightness = goog.color.yiqBrightness_(black);
|
||||
var coralBrightness = goog.color.yiqBrightness_(coral);
|
||||
var lightgreenBrightness = goog.color.yiqBrightness_(lightgreen);
|
||||
|
||||
// brightness should be a number
|
||||
assertTrue('White brightness is a number.',
|
||||
typeof whiteBrightness == 'number');
|
||||
assertTrue('Coral brightness is a number.',
|
||||
typeof coralBrightness == 'number');
|
||||
|
||||
// brightness for known colors should match known values
|
||||
assertEquals('White brightness is 255', whiteBrightness, 255);
|
||||
assertEquals('Black brightness is 0', blackBrightness, 0);
|
||||
assertEquals('Coral brightness is 160', coralBrightness, 160);
|
||||
assertEquals('Lightgreen brightness is 199', lightgreenBrightness, 199);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method runs unit tests against goog.color.yiqBrightnessDiff_().
|
||||
*/
|
||||
function testYiqBrightnessDiff() {
|
||||
var colors = {
|
||||
'deeppink': [255, 20, 147],
|
||||
'indigo': [75, 0, 130],
|
||||
'saddlebrown': [139, 69, 19]
|
||||
};
|
||||
|
||||
var diffs = new Object();
|
||||
for (name1 in colors) {
|
||||
for (name2 in colors) {
|
||||
diffs[name1 + '-' + name2] =
|
||||
goog.color.yiqBrightnessDiff_(colors[name1], colors[name2]);
|
||||
}
|
||||
}
|
||||
|
||||
for (pair in diffs) {
|
||||
// each brightness diff should be a number
|
||||
assertTrue(pair + ' diff is a number.', typeof diffs[pair] == 'number');
|
||||
// each brightness diff should be greater than or equal to 0
|
||||
assertTrue(pair + ' diff is greater than or equal to 0.', diffs[pair] >= 0);
|
||||
}
|
||||
|
||||
// brightness diff for same-color pairs should be 0
|
||||
assertEquals('deeppink-deeppink is 0.', diffs['deeppink-deeppink'], 0);
|
||||
assertEquals('indigo-indigo is 0.', diffs['indigo-indigo'], 0);
|
||||
|
||||
// brightness diff for known pairs should match known values
|
||||
assertEquals('deeppink-indigo is 68.', diffs['deeppink-indigo'], 68);
|
||||
assertEquals('saddlebrown-deeppink is 21.',
|
||||
diffs['saddlebrown-deeppink'], 21);
|
||||
|
||||
// reversed pairs should have equal values
|
||||
assertEquals('indigo-saddlebrown is 47.', diffs['indigo-saddlebrown'], 47);
|
||||
assertEquals('saddlebrown-indigo is also 47.',
|
||||
diffs['saddlebrown-indigo'], 47);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method runs unit tests against goog.color.colorDiff_().
|
||||
*/
|
||||
function testColorDiff() {
|
||||
var colors = {
|
||||
'mediumblue': [0, 0, 205],
|
||||
'oldlace': [253, 245, 230],
|
||||
'orchid': [218, 112, 214]
|
||||
};
|
||||
|
||||
var diffs = new Object();
|
||||
for (name1 in colors) {
|
||||
for (name2 in colors) {
|
||||
diffs[name1 + '-' + name2] =
|
||||
goog.color.colorDiff_(colors[name1], colors[name2]);
|
||||
}
|
||||
}
|
||||
|
||||
for (pair in diffs) {
|
||||
// each color diff should be a number
|
||||
assertTrue(pair + ' diff is a number.', typeof diffs[pair] == 'number');
|
||||
// each color diff should be greater than or equal to 0
|
||||
assertTrue(pair + ' diff is greater than or equal to 0.', diffs[pair] >= 0);
|
||||
}
|
||||
|
||||
// color diff for same-color pairs should be 0
|
||||
assertEquals('mediumblue-mediumblue is 0.',
|
||||
diffs['mediumblue-mediumblue'], 0);
|
||||
assertEquals('oldlace-oldlace is 0.', diffs['oldlace-oldlace'], 0);
|
||||
|
||||
// color diff for known pairs should match known values
|
||||
assertEquals('mediumblue-oldlace is 523.', diffs['mediumblue-oldlace'], 523);
|
||||
assertEquals('oldlace-orchid is 184.', diffs['oldlace-orchid'], 184);
|
||||
|
||||
// reversed pairs should have equal values
|
||||
assertEquals('orchid-mediumblue is 339.', diffs['orchid-mediumblue'], 339);
|
||||
assertEquals('mediumblue-orchid is also 339.',
|
||||
diffs['mediumblue-orchid'], 339);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This method runs unit tests against goog.color.highContrast().
|
||||
*/
|
||||
function testHighContrast() {
|
||||
white = [255, 255, 255];
|
||||
black = [0, 0, 0];
|
||||
lemonchiffron = [255, 250, 205];
|
||||
sienna = [160, 82, 45];
|
||||
|
||||
var suggestion = goog.color.highContrast(
|
||||
black, [white, black, sienna, lemonchiffron]);
|
||||
|
||||
// should return an array of three numbers
|
||||
assertTrue('Return value is an array.', typeof suggestion == 'object');
|
||||
assertTrue('Return value is 3 long.', suggestion.length == 3);
|
||||
|
||||
// known color combos should return a known (i.e. human-verified) suggestion
|
||||
assertArrayEquals('White is best on sienna.',
|
||||
goog.color.highContrast(
|
||||
sienna, [white, black, sienna, lemonchiffron]), white);
|
||||
assertArrayEquals('Black is best on lemonchiffron.',
|
||||
goog.color.highContrast(
|
||||
white, [white, black, sienna, lemonchiffron]), black);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Helper function for color conversion functions between two colorspaces.
|
||||
* @param {Function} funcOne Function that converts from 1st colorspace to 2nd
|
||||
* @param {Function} funcTwo Function that converts from 2nd colorspace to 2nd
|
||||
* @param {Array<number>} color The color array passed to funcOne
|
||||
* @param {number} DELTA Margin of error for each element in color
|
||||
*/
|
||||
function colorConversionTestHelper(funcOne, funcTwo, color, DELTA) {
|
||||
|
||||
var temp = funcOne(color);
|
||||
|
||||
if (!goog.color.isValidHexColor_(temp)) {
|
||||
assertTrue('First conversion had a NaN: ' + temp, !isNaN(temp[0]));
|
||||
assertTrue('First conversion had a NaN: ' + temp, !isNaN(temp[1]));
|
||||
assertTrue('First conversion had a NaN: ' + temp, !isNaN(temp[2]));
|
||||
}
|
||||
|
||||
var back = funcTwo(temp);
|
||||
|
||||
if (!goog.color.isValidHexColor_(temp)) {
|
||||
assertTrue('Second conversion had a NaN: ' + back, !isNaN(back[0]));
|
||||
assertTrue('Second conversion had a NaN: ' + back, !isNaN(back[1]));
|
||||
assertTrue('Second conversion had a NaN: ' + back, !isNaN(back[2]));
|
||||
}
|
||||
|
||||
assertColorFuzzyEquals('Color was off', color, back, DELTA);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Checks equivalence between two colors' respective values. Accepts +- delta
|
||||
* for each pair of values
|
||||
* @param {string} Str
|
||||
* @param {Array<number>} expected
|
||||
* @param {Array<number>} actual
|
||||
* @param {number} delta Margin of error for each element in color array
|
||||
*/
|
||||
function assertColorFuzzyEquals(str, expected, actual, delta) {
|
||||
assertTrue(str + ' Expected: ' + expected + ' and got: ' + actual +
|
||||
' w/ delta: ' + delta,
|
||||
(Math.abs(expected[0] - actual[0]) <= delta) &&
|
||||
(Math.abs(expected[1] - actual[1]) <= delta) &&
|
||||
(Math.abs(expected[2] - actual[2]) <= delta));
|
||||
}
|
||||
176
vectortile/closure-library/closure/goog/color/names.js
Normal file
176
vectortile/closure-library/closure/goog/color/names.js
Normal file
@@ -0,0 +1,176 @@
|
||||
// Copyright 2006 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Names of standard colors with their associated hex values.
|
||||
*/
|
||||
|
||||
goog.provide('goog.color.names');
|
||||
|
||||
|
||||
/**
|
||||
* A map that contains a lot of colors that are recognised by various browsers.
|
||||
* This list is way larger than the minimal one dictated by W3C.
|
||||
* The keys of this map are the lowercase "readable" names of the colors, while
|
||||
* the values are the "hex" values.
|
||||
*/
|
||||
goog.color.names = {
|
||||
'aliceblue': '#f0f8ff',
|
||||
'antiquewhite': '#faebd7',
|
||||
'aqua': '#00ffff',
|
||||
'aquamarine': '#7fffd4',
|
||||
'azure': '#f0ffff',
|
||||
'beige': '#f5f5dc',
|
||||
'bisque': '#ffe4c4',
|
||||
'black': '#000000',
|
||||
'blanchedalmond': '#ffebcd',
|
||||
'blue': '#0000ff',
|
||||
'blueviolet': '#8a2be2',
|
||||
'brown': '#a52a2a',
|
||||
'burlywood': '#deb887',
|
||||
'cadetblue': '#5f9ea0',
|
||||
'chartreuse': '#7fff00',
|
||||
'chocolate': '#d2691e',
|
||||
'coral': '#ff7f50',
|
||||
'cornflowerblue': '#6495ed',
|
||||
'cornsilk': '#fff8dc',
|
||||
'crimson': '#dc143c',
|
||||
'cyan': '#00ffff',
|
||||
'darkblue': '#00008b',
|
||||
'darkcyan': '#008b8b',
|
||||
'darkgoldenrod': '#b8860b',
|
||||
'darkgray': '#a9a9a9',
|
||||
'darkgreen': '#006400',
|
||||
'darkgrey': '#a9a9a9',
|
||||
'darkkhaki': '#bdb76b',
|
||||
'darkmagenta': '#8b008b',
|
||||
'darkolivegreen': '#556b2f',
|
||||
'darkorange': '#ff8c00',
|
||||
'darkorchid': '#9932cc',
|
||||
'darkred': '#8b0000',
|
||||
'darksalmon': '#e9967a',
|
||||
'darkseagreen': '#8fbc8f',
|
||||
'darkslateblue': '#483d8b',
|
||||
'darkslategray': '#2f4f4f',
|
||||
'darkslategrey': '#2f4f4f',
|
||||
'darkturquoise': '#00ced1',
|
||||
'darkviolet': '#9400d3',
|
||||
'deeppink': '#ff1493',
|
||||
'deepskyblue': '#00bfff',
|
||||
'dimgray': '#696969',
|
||||
'dimgrey': '#696969',
|
||||
'dodgerblue': '#1e90ff',
|
||||
'firebrick': '#b22222',
|
||||
'floralwhite': '#fffaf0',
|
||||
'forestgreen': '#228b22',
|
||||
'fuchsia': '#ff00ff',
|
||||
'gainsboro': '#dcdcdc',
|
||||
'ghostwhite': '#f8f8ff',
|
||||
'gold': '#ffd700',
|
||||
'goldenrod': '#daa520',
|
||||
'gray': '#808080',
|
||||
'green': '#008000',
|
||||
'greenyellow': '#adff2f',
|
||||
'grey': '#808080',
|
||||
'honeydew': '#f0fff0',
|
||||
'hotpink': '#ff69b4',
|
||||
'indianred': '#cd5c5c',
|
||||
'indigo': '#4b0082',
|
||||
'ivory': '#fffff0',
|
||||
'khaki': '#f0e68c',
|
||||
'lavender': '#e6e6fa',
|
||||
'lavenderblush': '#fff0f5',
|
||||
'lawngreen': '#7cfc00',
|
||||
'lemonchiffon': '#fffacd',
|
||||
'lightblue': '#add8e6',
|
||||
'lightcoral': '#f08080',
|
||||
'lightcyan': '#e0ffff',
|
||||
'lightgoldenrodyellow': '#fafad2',
|
||||
'lightgray': '#d3d3d3',
|
||||
'lightgreen': '#90ee90',
|
||||
'lightgrey': '#d3d3d3',
|
||||
'lightpink': '#ffb6c1',
|
||||
'lightsalmon': '#ffa07a',
|
||||
'lightseagreen': '#20b2aa',
|
||||
'lightskyblue': '#87cefa',
|
||||
'lightslategray': '#778899',
|
||||
'lightslategrey': '#778899',
|
||||
'lightsteelblue': '#b0c4de',
|
||||
'lightyellow': '#ffffe0',
|
||||
'lime': '#00ff00',
|
||||
'limegreen': '#32cd32',
|
||||
'linen': '#faf0e6',
|
||||
'magenta': '#ff00ff',
|
||||
'maroon': '#800000',
|
||||
'mediumaquamarine': '#66cdaa',
|
||||
'mediumblue': '#0000cd',
|
||||
'mediumorchid': '#ba55d3',
|
||||
'mediumpurple': '#9370db',
|
||||
'mediumseagreen': '#3cb371',
|
||||
'mediumslateblue': '#7b68ee',
|
||||
'mediumspringgreen': '#00fa9a',
|
||||
'mediumturquoise': '#48d1cc',
|
||||
'mediumvioletred': '#c71585',
|
||||
'midnightblue': '#191970',
|
||||
'mintcream': '#f5fffa',
|
||||
'mistyrose': '#ffe4e1',
|
||||
'moccasin': '#ffe4b5',
|
||||
'navajowhite': '#ffdead',
|
||||
'navy': '#000080',
|
||||
'oldlace': '#fdf5e6',
|
||||
'olive': '#808000',
|
||||
'olivedrab': '#6b8e23',
|
||||
'orange': '#ffa500',
|
||||
'orangered': '#ff4500',
|
||||
'orchid': '#da70d6',
|
||||
'palegoldenrod': '#eee8aa',
|
||||
'palegreen': '#98fb98',
|
||||
'paleturquoise': '#afeeee',
|
||||
'palevioletred': '#db7093',
|
||||
'papayawhip': '#ffefd5',
|
||||
'peachpuff': '#ffdab9',
|
||||
'peru': '#cd853f',
|
||||
'pink': '#ffc0cb',
|
||||
'plum': '#dda0dd',
|
||||
'powderblue': '#b0e0e6',
|
||||
'purple': '#800080',
|
||||
'red': '#ff0000',
|
||||
'rosybrown': '#bc8f8f',
|
||||
'royalblue': '#4169e1',
|
||||
'saddlebrown': '#8b4513',
|
||||
'salmon': '#fa8072',
|
||||
'sandybrown': '#f4a460',
|
||||
'seagreen': '#2e8b57',
|
||||
'seashell': '#fff5ee',
|
||||
'sienna': '#a0522d',
|
||||
'silver': '#c0c0c0',
|
||||
'skyblue': '#87ceeb',
|
||||
'slateblue': '#6a5acd',
|
||||
'slategray': '#708090',
|
||||
'slategrey': '#708090',
|
||||
'snow': '#fffafa',
|
||||
'springgreen': '#00ff7f',
|
||||
'steelblue': '#4682b4',
|
||||
'tan': '#d2b48c',
|
||||
'teal': '#008080',
|
||||
'thistle': '#d8bfd8',
|
||||
'tomato': '#ff6347',
|
||||
'turquoise': '#40e0d0',
|
||||
'violet': '#ee82ee',
|
||||
'wheat': '#f5deb3',
|
||||
'white': '#ffffff',
|
||||
'whitesmoke': '#f5f5f5',
|
||||
'yellow': '#ffff00',
|
||||
'yellowgreen': '#9acd32'
|
||||
};
|
||||
1029
vectortile/closure-library/closure/goog/crypt/aes.js
Normal file
1029
vectortile/closure-library/closure/goog/crypt/aes.js
Normal file
File diff suppressed because it is too large
Load Diff
24
vectortile/closure-library/closure/goog/crypt/aes_test.html
Normal file
24
vectortile/closure-library/closure/goog/crypt/aes_test.html
Normal file
@@ -0,0 +1,24 @@
|
||||
<!doctype html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2012 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<!--
|
||||
Unit test for goog.crypt.Aes
|
||||
-->
|
||||
<head>
|
||||
<title>
|
||||
goog.crypt.Aes unit test
|
||||
</title>
|
||||
<script src="../base.js">
|
||||
</script>
|
||||
<script>
|
||||
goog.require('goog.crypt.AesTest');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
587
vectortile/closure-library/closure/goog/crypt/aes_test.js
Normal file
587
vectortile/closure-library/closure/goog/crypt/aes_test.js
Normal file
@@ -0,0 +1,587 @@
|
||||
// Copyright 2012 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.crypt.AesTest');
|
||||
goog.setTestOnly('goog.crypt.AesTest');
|
||||
|
||||
goog.require('goog.crypt');
|
||||
goog.require('goog.crypt.Aes');
|
||||
goog.require('goog.testing.jsunit');
|
||||
goog.crypt.Aes.ENABLE_TEST_MODE = true;
|
||||
|
||||
/*
|
||||
* Unit test for goog.crypt.Aes using the test vectors from the spec:
|
||||
* http://csrc.nist.gov/publications/fips/fips197/fips-197.pdf
|
||||
*/
|
||||
|
||||
var testData = null;
|
||||
|
||||
function test128() {
|
||||
doTest('000102030405060708090a0b0c0d0e0f',
|
||||
'00112233445566778899aabbccddeeff',
|
||||
v128,
|
||||
true /* encrypt */);
|
||||
}
|
||||
|
||||
function test192() {
|
||||
doTest('000102030405060708090a0b0c0d0e0f1011121314151617',
|
||||
'00112233445566778899aabbccddeeff',
|
||||
v192,
|
||||
true /* encrypt */);
|
||||
}
|
||||
|
||||
function test256() {
|
||||
doTest('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f',
|
||||
'00112233445566778899aabbccddeeff',
|
||||
v256,
|
||||
true /* encrypt */);
|
||||
}
|
||||
|
||||
function test128d() {
|
||||
doTest('000102030405060708090a0b0c0d0e0f',
|
||||
'69c4e0d86a7b0430d8cdb78070b4c55a',
|
||||
v128d,
|
||||
false /* decrypt */);
|
||||
}
|
||||
|
||||
function test192d() {
|
||||
doTest('000102030405060708090a0b0c0d0e0f1011121314151617',
|
||||
'dda97ca4864cdfe06eaf70a0ec0d7191',
|
||||
v192d,
|
||||
false /* decrypt */);
|
||||
}
|
||||
|
||||
function test256d() {
|
||||
doTest('000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f',
|
||||
'8ea2b7ca516745bfeafc49904b496089',
|
||||
v256d,
|
||||
false /* decrypt */);
|
||||
}
|
||||
|
||||
function doTest(key, input, values, dir) {
|
||||
testData = values;
|
||||
var keyArray = goog.crypt.hexToByteArray(key);
|
||||
var aes = new goog.crypt.Aes(keyArray);
|
||||
|
||||
aes.testKeySchedule_ = onTestKeySchedule;
|
||||
aes.testStartRound_ = onTestStartRound;
|
||||
aes.testAfterSubBytes_ = onTestAfterSubBytes;
|
||||
aes.testAfterShiftRows_ = onTestAfterShiftRows;
|
||||
aes.testAfterMixColumns_ = onTestAfterMixColumns;
|
||||
aes.testAfterAddRoundKey_ = onTestAfterAddRoundKey;
|
||||
|
||||
var inputArr = goog.crypt.hexToByteArray(input);
|
||||
var keyArr = goog.crypt.hexToByteArray(key);
|
||||
var outputArr = [];
|
||||
|
||||
var outputArr;
|
||||
if (dir) {
|
||||
outputArr = aes.encrypt(inputArr);
|
||||
} else {
|
||||
outputArr = aes.decrypt(inputArr);
|
||||
}
|
||||
|
||||
assertEquals('Incorrect output for test ' + testData.name,
|
||||
testData[testData.length - 1].output,
|
||||
encodeHex(outputArr));
|
||||
}
|
||||
|
||||
function onTestKeySchedule(roundNum, keySchedule, keyScheduleIndex) {
|
||||
assertNotNull(keySchedule);
|
||||
assertEquals(
|
||||
'Incorrect key for round ' + roundNum,
|
||||
testData[roundNum].k_sch, encodeKey(keySchedule, keyScheduleIndex));
|
||||
}
|
||||
|
||||
function onTestStartRound(roundNum, state) {
|
||||
assertEquals('Incorrect state for test ' + testData.name +
|
||||
' at start round ' + roundNum,
|
||||
testData[roundNum].start, encodeState(state));
|
||||
}
|
||||
|
||||
function onTestAfterSubBytes(roundNum, state) {
|
||||
assertEquals('Incorrect state for test ' + testData.name +
|
||||
' after sub bytes in round ' + roundNum,
|
||||
testData[roundNum].s_box, encodeState(state));
|
||||
}
|
||||
|
||||
function onTestAfterShiftRows(roundNum, state) {
|
||||
assertEquals('Incorrect state for test ' + testData.name +
|
||||
' after shift rows in round ' + roundNum,
|
||||
testData[roundNum].s_row, encodeState(state));
|
||||
}
|
||||
|
||||
function onTestAfterMixColumns(roundNum, state) {
|
||||
assertEquals('Incorrect state for test ' + testData.name +
|
||||
' after mix columns in round ' + roundNum,
|
||||
testData[roundNum].m_col, encodeState(state));
|
||||
}
|
||||
|
||||
function onTestAfterAddRoundKey(roundNum, state) {
|
||||
assertEquals('Incorrect state for test ' + testData.name +
|
||||
' after adding round key in round ' + roundNum,
|
||||
testData[roundNum].k_add, encodeState(state));
|
||||
}
|
||||
|
||||
function encodeHex(arr) {
|
||||
var str = [];
|
||||
|
||||
for (var i = 0; i < arr.length; i++) {
|
||||
str.push(encodeByte(arr[i]));
|
||||
}
|
||||
|
||||
return str.join('');
|
||||
}
|
||||
|
||||
function encodeState(state) {
|
||||
var s = [];
|
||||
|
||||
for (var c = 0; c < 4; c++) {
|
||||
for (var r = 0; r < 4; r++) {
|
||||
s.push(encodeByte(state[r][c]));
|
||||
}
|
||||
}
|
||||
|
||||
return s.join('');
|
||||
}
|
||||
|
||||
function encodeKey(key, round) {
|
||||
var s = [];
|
||||
|
||||
for (var r = round * 4; r < (round * 4 + 4); r++) {
|
||||
for (var c = 0; c < 4; c++) {
|
||||
s.push(encodeByte(key[r][c]));
|
||||
}
|
||||
}
|
||||
|
||||
return s.join('');
|
||||
}
|
||||
|
||||
function encodeByte(val) {
|
||||
val = Number(val).toString(16);
|
||||
|
||||
if (val.length == 1) {
|
||||
val = '0' + val;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
|
||||
var v128 = [];
|
||||
(function v128_init() {
|
||||
for (var i = 0; i <= 10; i++) v128[i] = {};
|
||||
v128.name = '128';
|
||||
v128[0].input = '00112233445566778899aabbccddeeff';
|
||||
v128[0].k_sch = '000102030405060708090a0b0c0d0e0f';
|
||||
v128[1].start = '00102030405060708090a0b0c0d0e0f0';
|
||||
v128[1].s_box = '63cab7040953d051cd60e0e7ba70e18c';
|
||||
v128[1].s_row = '6353e08c0960e104cd70b751bacad0e7';
|
||||
v128[1].m_col = '5f72641557f5bc92f7be3b291db9f91a';
|
||||
v128[1].k_sch = 'd6aa74fdd2af72fadaa678f1d6ab76fe';
|
||||
v128[2].start = '89d810e8855ace682d1843d8cb128fe4';
|
||||
v128[2].s_box = 'a761ca9b97be8b45d8ad1a611fc97369';
|
||||
v128[2].s_row = 'a7be1a6997ad739bd8c9ca451f618b61';
|
||||
v128[2].m_col = 'ff87968431d86a51645151fa773ad009';
|
||||
v128[2].k_sch = 'b692cf0b643dbdf1be9bc5006830b3fe';
|
||||
v128[3].start = '4915598f55e5d7a0daca94fa1f0a63f7';
|
||||
v128[3].s_box = '3b59cb73fcd90ee05774222dc067fb68';
|
||||
v128[3].s_row = '3bd92268fc74fb735767cbe0c0590e2d';
|
||||
v128[3].m_col = '4c9c1e66f771f0762c3f868e534df256';
|
||||
v128[3].k_sch = 'b6ff744ed2c2c9bf6c590cbf0469bf41';
|
||||
v128[4].start = 'fa636a2825b339c940668a3157244d17';
|
||||
v128[4].s_box = '2dfb02343f6d12dd09337ec75b36e3f0';
|
||||
v128[4].s_row = '2d6d7ef03f33e334093602dd5bfb12c7';
|
||||
v128[4].m_col = '6385b79ffc538df997be478e7547d691';
|
||||
v128[4].k_sch = '47f7f7bc95353e03f96c32bcfd058dfd';
|
||||
v128[5].start = '247240236966b3fa6ed2753288425b6c';
|
||||
v128[5].s_box = '36400926f9336d2d9fb59d23c42c3950';
|
||||
v128[5].s_row = '36339d50f9b539269f2c092dc4406d23';
|
||||
v128[5].m_col = 'f4bcd45432e554d075f1d6c51dd03b3c';
|
||||
v128[5].k_sch = '3caaa3e8a99f9deb50f3af57adf622aa';
|
||||
v128[6].start = 'c81677bc9b7ac93b25027992b0261996';
|
||||
v128[6].s_box = 'e847f56514dadde23f77b64fe7f7d490';
|
||||
v128[6].s_row = 'e8dab6901477d4653ff7f5e2e747dd4f';
|
||||
v128[6].m_col = '9816ee7400f87f556b2c049c8e5ad036';
|
||||
v128[6].k_sch = '5e390f7df7a69296a7553dc10aa31f6b';
|
||||
v128[7].start = 'c62fe109f75eedc3cc79395d84f9cf5d';
|
||||
v128[7].s_box = 'b415f8016858552e4bb6124c5f998a4c';
|
||||
v128[7].s_row = 'b458124c68b68a014b99f82e5f15554c';
|
||||
v128[7].m_col = 'c57e1c159a9bd286f05f4be098c63439';
|
||||
v128[7].k_sch = '14f9701ae35fe28c440adf4d4ea9c026';
|
||||
v128[8].start = 'd1876c0f79c4300ab45594add66ff41f';
|
||||
v128[8].s_box = '3e175076b61c04678dfc2295f6a8bfc0';
|
||||
v128[8].s_row = '3e1c22c0b6fcbf768da85067f6170495';
|
||||
v128[8].m_col = 'baa03de7a1f9b56ed5512cba5f414d23';
|
||||
v128[8].k_sch = '47438735a41c65b9e016baf4aebf7ad2';
|
||||
v128[9].start = 'fde3bad205e5d0d73547964ef1fe37f1';
|
||||
v128[9].s_box = '5411f4b56bd9700e96a0902fa1bb9aa1';
|
||||
v128[9].s_row = '54d990a16ba09ab596bbf40ea111702f';
|
||||
v128[9].m_col = 'e9f74eec023020f61bf2ccf2353c21c7';
|
||||
v128[9].k_sch = '549932d1f08557681093ed9cbe2c974e';
|
||||
v128[10].start = 'bd6e7c3df2b5779e0b61216e8b10b689';
|
||||
v128[10].s_box = '7a9f102789d5f50b2beffd9f3dca4ea7';
|
||||
v128[10].s_row = '7ad5fda789ef4e272bca100b3d9ff59f';
|
||||
v128[10].k_sch = '13111d7fe3944a17f307a78b4d2b30c5';
|
||||
v128[10].output = '69c4e0d86a7b0430d8cdb78070b4c55a';
|
||||
})();
|
||||
|
||||
var v128d = [];
|
||||
(function v128d_init() {
|
||||
for (var i = 0; i <= 10; i++) v128d[i] = {};
|
||||
v128d.name = '128d';
|
||||
v128d[0].input = '69c4e0d86a7b0430d8cdb78070b4c55a';
|
||||
v128d[0].k_sch = '13111d7fe3944a17f307a78b4d2b30c5';
|
||||
v128d[1].start = '7ad5fda789ef4e272bca100b3d9ff59f';
|
||||
v128d[1].s_row = '7a9f102789d5f50b2beffd9f3dca4ea7';
|
||||
v128d[1].s_box = 'bd6e7c3df2b5779e0b61216e8b10b689';
|
||||
v128d[1].k_sch = '549932d1f08557681093ed9cbe2c974e';
|
||||
v128d[1].k_add = 'e9f74eec023020f61bf2ccf2353c21c7';
|
||||
v128d[2].start = '54d990a16ba09ab596bbf40ea111702f';
|
||||
v128d[2].s_row = '5411f4b56bd9700e96a0902fa1bb9aa1';
|
||||
v128d[2].s_box = 'fde3bad205e5d0d73547964ef1fe37f1';
|
||||
v128d[2].k_sch = '47438735a41c65b9e016baf4aebf7ad2';
|
||||
v128d[2].k_add = 'baa03de7a1f9b56ed5512cba5f414d23';
|
||||
v128d[3].start = '3e1c22c0b6fcbf768da85067f6170495';
|
||||
v128d[3].s_row = '3e175076b61c04678dfc2295f6a8bfc0';
|
||||
v128d[3].s_box = 'd1876c0f79c4300ab45594add66ff41f';
|
||||
v128d[3].k_sch = '14f9701ae35fe28c440adf4d4ea9c026';
|
||||
v128d[3].k_add = 'c57e1c159a9bd286f05f4be098c63439';
|
||||
v128d[4].start = 'b458124c68b68a014b99f82e5f15554c';
|
||||
v128d[4].s_row = 'b415f8016858552e4bb6124c5f998a4c';
|
||||
v128d[4].s_box = 'c62fe109f75eedc3cc79395d84f9cf5d';
|
||||
v128d[4].k_sch = '5e390f7df7a69296a7553dc10aa31f6b';
|
||||
v128d[4].k_add = '9816ee7400f87f556b2c049c8e5ad036';
|
||||
v128d[5].start = 'e8dab6901477d4653ff7f5e2e747dd4f';
|
||||
v128d[5].s_row = 'e847f56514dadde23f77b64fe7f7d490';
|
||||
v128d[5].s_box = 'c81677bc9b7ac93b25027992b0261996';
|
||||
v128d[5].k_sch = '3caaa3e8a99f9deb50f3af57adf622aa';
|
||||
v128d[5].k_add = 'f4bcd45432e554d075f1d6c51dd03b3c';
|
||||
v128d[6].start = '36339d50f9b539269f2c092dc4406d23';
|
||||
v128d[6].s_row = '36400926f9336d2d9fb59d23c42c3950';
|
||||
v128d[6].s_box = '247240236966b3fa6ed2753288425b6c';
|
||||
v128d[6].k_sch = '47f7f7bc95353e03f96c32bcfd058dfd';
|
||||
v128d[6].k_add = '6385b79ffc538df997be478e7547d691';
|
||||
v128d[7].start = '2d6d7ef03f33e334093602dd5bfb12c7';
|
||||
v128d[7].s_row = '2dfb02343f6d12dd09337ec75b36e3f0';
|
||||
v128d[7].s_box = 'fa636a2825b339c940668a3157244d17';
|
||||
v128d[7].k_sch = 'b6ff744ed2c2c9bf6c590cbf0469bf41';
|
||||
v128d[7].k_add = '4c9c1e66f771f0762c3f868e534df256';
|
||||
v128d[8].start = '3bd92268fc74fb735767cbe0c0590e2d';
|
||||
v128d[8].s_row = '3b59cb73fcd90ee05774222dc067fb68';
|
||||
v128d[8].s_box = '4915598f55e5d7a0daca94fa1f0a63f7';
|
||||
v128d[8].k_sch = 'b692cf0b643dbdf1be9bc5006830b3fe';
|
||||
v128d[8].k_add = 'ff87968431d86a51645151fa773ad009';
|
||||
v128d[9].start = 'a7be1a6997ad739bd8c9ca451f618b61';
|
||||
v128d[9].s_row = 'a761ca9b97be8b45d8ad1a611fc97369';
|
||||
v128d[9].s_box = '89d810e8855ace682d1843d8cb128fe4';
|
||||
v128d[9].k_sch = 'd6aa74fdd2af72fadaa678f1d6ab76fe';
|
||||
v128d[9].k_add = '5f72641557f5bc92f7be3b291db9f91a';
|
||||
v128d[10].start = '6353e08c0960e104cd70b751bacad0e7';
|
||||
v128d[10].s_row = '63cab7040953d051cd60e0e7ba70e18c';
|
||||
v128d[10].s_box = '00102030405060708090a0b0c0d0e0f0';
|
||||
v128d[10].k_sch = '000102030405060708090a0b0c0d0e0f';
|
||||
v128d[10].output = '00112233445566778899aabbccddeeff';
|
||||
})();
|
||||
|
||||
var v192 = [];
|
||||
(function v192_init() {
|
||||
for (var i = 0; i <= 12; i++) v192[i] = {};
|
||||
v192.name = '192';
|
||||
v192[0].input = '00112233445566778899aabbccddeeff';
|
||||
v192[0].k_sch = '000102030405060708090a0b0c0d0e0f';
|
||||
v192[1].start = '00102030405060708090a0b0c0d0e0f0';
|
||||
v192[1].s_box = '63cab7040953d051cd60e0e7ba70e18c';
|
||||
v192[1].s_row = '6353e08c0960e104cd70b751bacad0e7';
|
||||
v192[1].m_col = '5f72641557f5bc92f7be3b291db9f91a';
|
||||
v192[1].k_sch = '10111213141516175846f2f95c43f4fe';
|
||||
v192[2].start = '4f63760643e0aa85aff8c9d041fa0de4';
|
||||
v192[2].s_box = '84fb386f1ae1ac977941dd70832dd769';
|
||||
v192[2].s_row = '84e1dd691a41d76f792d389783fbac70';
|
||||
v192[2].m_col = '9f487f794f955f662afc86abd7f1ab29';
|
||||
v192[2].k_sch = '544afef55847f0fa4856e2e95c43f4fe';
|
||||
v192[3].start = 'cb02818c17d2af9c62aa64428bb25fd7';
|
||||
v192[3].s_box = '1f770c64f0b579deaaac432c3d37cf0e';
|
||||
v192[3].s_row = '1fb5430ef0accf64aa370cde3d77792c';
|
||||
v192[3].m_col = 'b7a53ecbbf9d75a0c40efc79b674cc11';
|
||||
v192[3].k_sch = '40f949b31cbabd4d48f043b810b7b342';
|
||||
v192[4].start = 'f75c7778a327c8ed8cfebfc1a6c37f53';
|
||||
v192[4].s_box = '684af5bc0acce85564bb0878242ed2ed';
|
||||
v192[4].s_row = '68cc08ed0abbd2bc642ef555244ae878';
|
||||
v192[4].m_col = '7a1e98bdacb6d1141a6944dd06eb2d3e';
|
||||
v192[4].k_sch = '58e151ab04a2a5557effb5416245080c';
|
||||
v192[5].start = '22ffc916a81474416496f19c64ae2532';
|
||||
v192[5].s_box = '9316dd47c2fa92834390a1de43e43f23';
|
||||
v192[5].s_row = '93faa123c2903f4743e4dd83431692de';
|
||||
v192[5].m_col = 'aaa755b34cffe57cef6f98e1f01c13e6';
|
||||
v192[5].k_sch = '2ab54bb43a02f8f662e3a95d66410c08';
|
||||
v192[6].start = '80121e0776fd1d8a8d8c31bc965d1fee';
|
||||
v192[6].s_box = 'cdc972c53854a47e5d64c765904cc028';
|
||||
v192[6].s_row = 'cd54c7283864c0c55d4c727e90c9a465';
|
||||
v192[6].m_col = '921f748fd96e937d622d7725ba8ba50c';
|
||||
v192[6].k_sch = 'f501857297448d7ebdf1c6ca87f33e3c';
|
||||
v192[7].start = '671ef1fd4e2a1e03dfdcb1ef3d789b30';
|
||||
v192[7].s_box = '8572a1542fe5727b9e86c8df27bc1404';
|
||||
v192[7].s_row = '85e5c8042f8614549ebca17b277272df';
|
||||
v192[7].m_col = 'e913e7b18f507d4b227ef652758acbcc';
|
||||
v192[7].k_sch = 'e510976183519b6934157c9ea351f1e0';
|
||||
v192[8].start = '0c0370d00c01e622166b8accd6db3a2c';
|
||||
v192[8].s_box = 'fe7b5170fe7c8e93477f7e4bf6b98071';
|
||||
v192[8].s_row = 'fe7c7e71fe7f807047b95193f67b8e4b';
|
||||
v192[8].m_col = '6cf5edf996eb0a069c4ef21cbfc25762';
|
||||
v192[8].k_sch = '1ea0372a995309167c439e77ff12051e';
|
||||
v192[9].start = '7255dad30fb80310e00d6c6b40d0527c';
|
||||
v192[9].s_box = '40fc5766766c7bcae1d7507f09700010';
|
||||
v192[9].s_row = '406c501076d70066e17057ca09fc7b7f';
|
||||
v192[9].m_col = '7478bcdce8a50b81d4327a9009188262';
|
||||
v192[9].k_sch = 'dd7e0e887e2fff68608fc842f9dcc154';
|
||||
v192[10].start = 'a906b254968af4e9b4bdb2d2f0c44336';
|
||||
v192[10].s_box = 'd36f3720907ebf1e8d7a37b58c1c1a05';
|
||||
v192[10].s_row = 'd37e3705907a1a208d1c371e8c6fbfb5';
|
||||
v192[10].m_col = '0d73cc2d8f6abe8b0cf2dd9bb83d422e';
|
||||
v192[10].k_sch = '859f5f237a8d5a3dc0c02952beefd63a';
|
||||
v192[11].start = '88ec930ef5e7e4b6cc32f4c906d29414';
|
||||
v192[11].s_box = 'c4cedcabe694694e4b23bfdd6fb522fa';
|
||||
v192[11].s_row = 'c494bffae62322ab4bb5dc4e6fce69dd';
|
||||
v192[11].m_col = '71d720933b6d677dc00b8f28238e0fb7';
|
||||
v192[11].k_sch = 'de601e7827bcdf2ca223800fd8aeda32';
|
||||
v192[12].start = 'afb73eeb1cd1b85162280f27fb20d585';
|
||||
v192[12].s_box = '79a9b2e99c3e6cd1aa3476cc0fb70397';
|
||||
v192[12].s_row = '793e76979c3403e9aab7b2d10fa96ccc';
|
||||
v192[12].k_sch = 'a4970a331a78dc09c418c271e3a41d5d';
|
||||
v192[12].output = 'dda97ca4864cdfe06eaf70a0ec0d7191';
|
||||
})();
|
||||
|
||||
var v192d = [];
|
||||
(function v192d_init() {
|
||||
for (var i = 0; i <= 12; i++) v192d[i] = {};
|
||||
v192d.name = '192d';
|
||||
v192d[0].input = 'dda97ca4864cdfe06eaf70a0ec0d7191';
|
||||
v192d[0].k_sch = 'a4970a331a78dc09c418c271e3a41d5d';
|
||||
v192d[1].start = '793e76979c3403e9aab7b2d10fa96ccc';
|
||||
v192d[1].s_row = '79a9b2e99c3e6cd1aa3476cc0fb70397';
|
||||
v192d[1].s_box = 'afb73eeb1cd1b85162280f27fb20d585';
|
||||
v192d[1].k_sch = 'de601e7827bcdf2ca223800fd8aeda32';
|
||||
v192d[1].k_add = '71d720933b6d677dc00b8f28238e0fb7';
|
||||
v192d[2].start = 'c494bffae62322ab4bb5dc4e6fce69dd';
|
||||
v192d[2].s_row = 'c4cedcabe694694e4b23bfdd6fb522fa';
|
||||
v192d[2].s_box = '88ec930ef5e7e4b6cc32f4c906d29414';
|
||||
v192d[2].k_sch = '859f5f237a8d5a3dc0c02952beefd63a';
|
||||
v192d[2].k_add = '0d73cc2d8f6abe8b0cf2dd9bb83d422e';
|
||||
v192d[3].start = 'd37e3705907a1a208d1c371e8c6fbfb5';
|
||||
v192d[3].s_row = 'd36f3720907ebf1e8d7a37b58c1c1a05';
|
||||
v192d[3].s_box = 'a906b254968af4e9b4bdb2d2f0c44336';
|
||||
v192d[3].k_sch = 'dd7e0e887e2fff68608fc842f9dcc154';
|
||||
v192d[3].k_add = '7478bcdce8a50b81d4327a9009188262';
|
||||
v192d[4].start = '406c501076d70066e17057ca09fc7b7f';
|
||||
v192d[4].s_row = '40fc5766766c7bcae1d7507f09700010';
|
||||
v192d[4].s_box = '7255dad30fb80310e00d6c6b40d0527c';
|
||||
v192d[4].k_sch = '1ea0372a995309167c439e77ff12051e';
|
||||
v192d[4].k_add = '6cf5edf996eb0a069c4ef21cbfc25762';
|
||||
v192d[5].start = 'fe7c7e71fe7f807047b95193f67b8e4b';
|
||||
v192d[5].s_row = 'fe7b5170fe7c8e93477f7e4bf6b98071';
|
||||
v192d[5].s_box = '0c0370d00c01e622166b8accd6db3a2c';
|
||||
v192d[5].k_sch = 'e510976183519b6934157c9ea351f1e0';
|
||||
v192d[5].k_add = 'e913e7b18f507d4b227ef652758acbcc';
|
||||
v192d[6].start = '85e5c8042f8614549ebca17b277272df';
|
||||
v192d[6].s_row = '8572a1542fe5727b9e86c8df27bc1404';
|
||||
v192d[6].s_box = '671ef1fd4e2a1e03dfdcb1ef3d789b30';
|
||||
v192d[6].k_sch = 'f501857297448d7ebdf1c6ca87f33e3c';
|
||||
v192d[6].k_add = '921f748fd96e937d622d7725ba8ba50c';
|
||||
v192d[7].start = 'cd54c7283864c0c55d4c727e90c9a465';
|
||||
v192d[7].s_row = 'cdc972c53854a47e5d64c765904cc028';
|
||||
v192d[7].s_box = '80121e0776fd1d8a8d8c31bc965d1fee';
|
||||
v192d[7].k_sch = '2ab54bb43a02f8f662e3a95d66410c08';
|
||||
v192d[7].k_add = 'aaa755b34cffe57cef6f98e1f01c13e6';
|
||||
v192d[8].start = '93faa123c2903f4743e4dd83431692de';
|
||||
v192d[8].s_row = '9316dd47c2fa92834390a1de43e43f23';
|
||||
v192d[8].s_box = '22ffc916a81474416496f19c64ae2532';
|
||||
v192d[8].k_sch = '58e151ab04a2a5557effb5416245080c';
|
||||
v192d[8].k_add = '7a1e98bdacb6d1141a6944dd06eb2d3e';
|
||||
v192d[9].start = '68cc08ed0abbd2bc642ef555244ae878';
|
||||
v192d[9].s_row = '684af5bc0acce85564bb0878242ed2ed';
|
||||
v192d[9].s_box = 'f75c7778a327c8ed8cfebfc1a6c37f53';
|
||||
v192d[9].k_sch = '40f949b31cbabd4d48f043b810b7b342';
|
||||
v192d[9].k_add = 'b7a53ecbbf9d75a0c40efc79b674cc11';
|
||||
v192d[10].start = '1fb5430ef0accf64aa370cde3d77792c';
|
||||
v192d[10].s_row = '1f770c64f0b579deaaac432c3d37cf0e';
|
||||
v192d[10].s_box = 'cb02818c17d2af9c62aa64428bb25fd7';
|
||||
v192d[10].k_sch = '544afef55847f0fa4856e2e95c43f4fe';
|
||||
v192d[10].k_add = '9f487f794f955f662afc86abd7f1ab29';
|
||||
v192d[11].start = '84e1dd691a41d76f792d389783fbac70';
|
||||
v192d[11].s_row = '84fb386f1ae1ac977941dd70832dd769';
|
||||
v192d[11].s_box = '4f63760643e0aa85aff8c9d041fa0de4';
|
||||
v192d[11].k_sch = '10111213141516175846f2f95c43f4fe';
|
||||
v192d[11].k_add = '5f72641557f5bc92f7be3b291db9f91a';
|
||||
v192d[12].start = '6353e08c0960e104cd70b751bacad0e7';
|
||||
v192d[12].s_row = '63cab7040953d051cd60e0e7ba70e18c';
|
||||
v192d[12].s_box = '00102030405060708090a0b0c0d0e0f0';
|
||||
v192d[12].k_sch = '000102030405060708090a0b0c0d0e0f';
|
||||
v192d[12].output = '00112233445566778899aabbccddeeff';
|
||||
})();
|
||||
|
||||
var v256 = [];
|
||||
(function v256_init() {
|
||||
for (var i = 0; i <= 14; i++) v256[i] = {};
|
||||
v256.name = '256';
|
||||
v256[0].input = '00112233445566778899aabbccddeeff';
|
||||
v256[0].k_sch = '000102030405060708090a0b0c0d0e0f';
|
||||
v256[1].start = '00102030405060708090a0b0c0d0e0f0';
|
||||
v256[1].s_box = '63cab7040953d051cd60e0e7ba70e18c';
|
||||
v256[1].s_row = '6353e08c0960e104cd70b751bacad0e7';
|
||||
v256[1].m_col = '5f72641557f5bc92f7be3b291db9f91a';
|
||||
v256[1].k_sch = '101112131415161718191a1b1c1d1e1f';
|
||||
v256[2].start = '4f63760643e0aa85efa7213201a4e705';
|
||||
v256[2].s_box = '84fb386f1ae1ac97df5cfd237c49946b';
|
||||
v256[2].s_row = '84e1fd6b1a5c946fdf4938977cfbac23';
|
||||
v256[2].m_col = 'bd2a395d2b6ac438d192443e615da195';
|
||||
v256[2].k_sch = 'a573c29fa176c498a97fce93a572c09c';
|
||||
v256[3].start = '1859fbc28a1c00a078ed8aadc42f6109';
|
||||
v256[3].s_box = 'adcb0f257e9c63e0bc557e951c15ef01';
|
||||
v256[3].s_row = 'ad9c7e017e55ef25bc150fe01ccb6395';
|
||||
v256[3].m_col = '810dce0cc9db8172b3678c1e88a1b5bd';
|
||||
v256[3].k_sch = '1651a8cd0244beda1a5da4c10640bade';
|
||||
v256[4].start = '975c66c1cb9f3fa8a93a28df8ee10f63';
|
||||
v256[4].s_box = '884a33781fdb75c2d380349e19f876fb';
|
||||
v256[4].s_row = '88db34fb1f807678d3f833c2194a759e';
|
||||
v256[4].m_col = 'b2822d81abe6fb275faf103a078c0033';
|
||||
v256[4].k_sch = 'ae87dff00ff11b68a68ed5fb03fc1567';
|
||||
v256[5].start = '1c05f271a417e04ff921c5c104701554';
|
||||
v256[5].s_box = '9c6b89a349f0e18499fda678f2515920';
|
||||
v256[5].s_row = '9cf0a62049fd59a399518984f26be178';
|
||||
v256[5].m_col = 'aeb65ba974e0f822d73f567bdb64c877';
|
||||
v256[5].k_sch = '6de1f1486fa54f9275f8eb5373b8518d';
|
||||
v256[6].start = 'c357aae11b45b7b0a2c7bd28a8dc99fa';
|
||||
v256[6].s_box = '2e5bacf8af6ea9e73ac67a34c286ee2d';
|
||||
v256[6].s_row = '2e6e7a2dafc6eef83a86ace7c25ba934';
|
||||
v256[6].m_col = 'b951c33c02e9bd29ae25cdb1efa08cc7';
|
||||
v256[6].k_sch = 'c656827fc9a799176f294cec6cd5598b';
|
||||
v256[7].start = '7f074143cb4e243ec10c815d8375d54c';
|
||||
v256[7].s_box = 'd2c5831a1f2f36b278fe0c4cec9d0329';
|
||||
v256[7].s_row = 'd22f0c291ffe031a789d83b2ecc5364c';
|
||||
v256[7].m_col = 'ebb19e1c3ee7c9e87d7535e9ed6b9144';
|
||||
v256[7].k_sch = '3de23a75524775e727bf9eb45407cf39';
|
||||
v256[8].start = 'd653a4696ca0bc0f5acaab5db96c5e7d';
|
||||
v256[8].s_box = 'f6ed49f950e06576be74624c565058ff';
|
||||
v256[8].s_row = 'f6e062ff507458f9be50497656ed654c';
|
||||
v256[8].m_col = '5174c8669da98435a8b3e62ca974a5ea';
|
||||
v256[8].k_sch = '0bdc905fc27b0948ad5245a4c1871c2f';
|
||||
v256[9].start = '5aa858395fd28d7d05e1a38868f3b9c5';
|
||||
v256[9].s_box = 'bec26a12cfb55dff6bf80ac4450d56a6';
|
||||
v256[9].s_row = 'beb50aa6cff856126b0d6aff45c25dc4';
|
||||
v256[9].m_col = '0f77ee31d2ccadc05430a83f4ef96ac3';
|
||||
v256[9].k_sch = '45f5a66017b2d387300d4d33640a820a';
|
||||
v256[10].start = '4a824851c57e7e47643de50c2af3e8c9';
|
||||
v256[10].s_box = 'd61352d1a6f3f3a04327d9fee50d9bdd';
|
||||
v256[10].s_row = 'd6f3d9dda6279bd1430d52a0e513f3fe';
|
||||
v256[10].m_col = 'bd86f0ea748fc4f4630f11c1e9331233';
|
||||
v256[10].k_sch = '7ccff71cbeb4fe5413e6bbf0d261a7df';
|
||||
v256[11].start = 'c14907f6ca3b3aa070e9aa313b52b5ec';
|
||||
v256[11].s_box = '783bc54274e280e0511eacc7e200d5ce';
|
||||
v256[11].s_row = '78e2acce741ed5425100c5e0e23b80c7';
|
||||
v256[11].m_col = 'af8690415d6e1dd387e5fbedd5c89013';
|
||||
v256[11].k_sch = 'f01afafee7a82979d7a5644ab3afe640';
|
||||
v256[12].start = '5f9c6abfbac634aa50409fa766677653';
|
||||
v256[12].s_box = 'cfde0208f4b418ac5309db5c338538ed';
|
||||
v256[12].s_row = 'cfb4dbedf4093808538502ac33de185c';
|
||||
v256[12].m_col = '7427fae4d8a695269ce83d315be0392b';
|
||||
v256[12].k_sch = '2541fe719bf500258813bbd55a721c0a';
|
||||
v256[13].start = '516604954353950314fb86e401922521';
|
||||
v256[13].s_box = 'd133f22a1aed2a7bfa0f44697c4f3ffd';
|
||||
v256[13].s_row = 'd1ed44fd1a0f3f2afa4ff27b7c332a69';
|
||||
v256[13].m_col = '2c21a820306f154ab712c75eee0da04f';
|
||||
v256[13].k_sch = '4e5a6699a9f24fe07e572baacdf8cdea';
|
||||
v256[14].start = '627bceb9999d5aaac945ecf423f56da5';
|
||||
v256[14].s_box = 'aa218b56ee5ebeacdd6ecebf26e63c06';
|
||||
v256[14].s_row = 'aa5ece06ee6e3c56dde68bac2621bebf';
|
||||
v256[14].k_sch = '24fc79ccbf0979e9371ac23c6d68de36';
|
||||
v256[14].output = '8ea2b7ca516745bfeafc49904b496089';
|
||||
})();
|
||||
|
||||
var v256d = [];
|
||||
(function v256d_init() {
|
||||
for (var i = 0; i <= 14; i++) v256d[i] = {};
|
||||
v256d.name = '256d';
|
||||
v256d[0].input = '8ea2b7ca516745bfeafc49904b496089';
|
||||
v256d[0].k_sch = '24fc79ccbf0979e9371ac23c6d68de36';
|
||||
v256d[1].start = 'aa5ece06ee6e3c56dde68bac2621bebf';
|
||||
v256d[1].s_row = 'aa218b56ee5ebeacdd6ecebf26e63c06';
|
||||
v256d[1].s_box = '627bceb9999d5aaac945ecf423f56da5';
|
||||
v256d[1].k_sch = '4e5a6699a9f24fe07e572baacdf8cdea';
|
||||
v256d[1].k_add = '2c21a820306f154ab712c75eee0da04f';
|
||||
v256d[2].start = 'd1ed44fd1a0f3f2afa4ff27b7c332a69';
|
||||
v256d[2].s_row = 'd133f22a1aed2a7bfa0f44697c4f3ffd';
|
||||
v256d[2].s_box = '516604954353950314fb86e401922521';
|
||||
v256d[2].k_sch = '2541fe719bf500258813bbd55a721c0a';
|
||||
v256d[2].k_add = '7427fae4d8a695269ce83d315be0392b';
|
||||
v256d[3].start = 'cfb4dbedf4093808538502ac33de185c';
|
||||
v256d[3].s_row = 'cfde0208f4b418ac5309db5c338538ed';
|
||||
v256d[3].s_box = '5f9c6abfbac634aa50409fa766677653';
|
||||
v256d[3].k_sch = 'f01afafee7a82979d7a5644ab3afe640';
|
||||
v256d[3].k_add = 'af8690415d6e1dd387e5fbedd5c89013';
|
||||
v256d[4].start = '78e2acce741ed5425100c5e0e23b80c7';
|
||||
v256d[4].s_row = '783bc54274e280e0511eacc7e200d5ce';
|
||||
v256d[4].s_box = 'c14907f6ca3b3aa070e9aa313b52b5ec';
|
||||
v256d[4].k_sch = '7ccff71cbeb4fe5413e6bbf0d261a7df';
|
||||
v256d[4].k_add = 'bd86f0ea748fc4f4630f11c1e9331233';
|
||||
v256d[5].start = 'd6f3d9dda6279bd1430d52a0e513f3fe';
|
||||
v256d[5].s_row = 'd61352d1a6f3f3a04327d9fee50d9bdd';
|
||||
v256d[5].s_box = '4a824851c57e7e47643de50c2af3e8c9';
|
||||
v256d[5].k_sch = '45f5a66017b2d387300d4d33640a820a';
|
||||
v256d[5].k_add = '0f77ee31d2ccadc05430a83f4ef96ac3';
|
||||
v256d[6].start = 'beb50aa6cff856126b0d6aff45c25dc4';
|
||||
v256d[6].s_row = 'bec26a12cfb55dff6bf80ac4450d56a6';
|
||||
v256d[6].s_box = '5aa858395fd28d7d05e1a38868f3b9c5';
|
||||
v256d[6].k_sch = '0bdc905fc27b0948ad5245a4c1871c2f';
|
||||
v256d[6].k_add = '5174c8669da98435a8b3e62ca974a5ea';
|
||||
v256d[7].start = 'f6e062ff507458f9be50497656ed654c';
|
||||
v256d[7].s_row = 'f6ed49f950e06576be74624c565058ff';
|
||||
v256d[7].s_box = 'd653a4696ca0bc0f5acaab5db96c5e7d';
|
||||
v256d[7].k_sch = '3de23a75524775e727bf9eb45407cf39';
|
||||
v256d[7].k_add = 'ebb19e1c3ee7c9e87d7535e9ed6b9144';
|
||||
v256d[8].start = 'd22f0c291ffe031a789d83b2ecc5364c';
|
||||
v256d[8].s_row = 'd2c5831a1f2f36b278fe0c4cec9d0329';
|
||||
v256d[8].s_box = '7f074143cb4e243ec10c815d8375d54c';
|
||||
v256d[8].k_sch = 'c656827fc9a799176f294cec6cd5598b';
|
||||
v256d[8].k_add = 'b951c33c02e9bd29ae25cdb1efa08cc7';
|
||||
v256d[9].start = '2e6e7a2dafc6eef83a86ace7c25ba934';
|
||||
v256d[9].s_row = '2e5bacf8af6ea9e73ac67a34c286ee2d';
|
||||
v256d[9].s_box = 'c357aae11b45b7b0a2c7bd28a8dc99fa';
|
||||
v256d[9].k_sch = '6de1f1486fa54f9275f8eb5373b8518d';
|
||||
v256d[9].k_add = 'aeb65ba974e0f822d73f567bdb64c877';
|
||||
v256d[10].start = '9cf0a62049fd59a399518984f26be178';
|
||||
v256d[10].s_row = '9c6b89a349f0e18499fda678f2515920';
|
||||
v256d[10].s_box = '1c05f271a417e04ff921c5c104701554';
|
||||
v256d[10].k_sch = 'ae87dff00ff11b68a68ed5fb03fc1567';
|
||||
v256d[10].k_add = 'b2822d81abe6fb275faf103a078c0033';
|
||||
v256d[11].start = '88db34fb1f807678d3f833c2194a759e';
|
||||
v256d[11].s_row = '884a33781fdb75c2d380349e19f876fb';
|
||||
v256d[11].s_box = '975c66c1cb9f3fa8a93a28df8ee10f63';
|
||||
v256d[11].k_sch = '1651a8cd0244beda1a5da4c10640bade';
|
||||
v256d[11].k_add = '810dce0cc9db8172b3678c1e88a1b5bd';
|
||||
v256d[12].start = 'ad9c7e017e55ef25bc150fe01ccb6395';
|
||||
v256d[12].s_row = 'adcb0f257e9c63e0bc557e951c15ef01';
|
||||
v256d[12].s_box = '1859fbc28a1c00a078ed8aadc42f6109';
|
||||
v256d[12].k_sch = 'a573c29fa176c498a97fce93a572c09c';
|
||||
v256d[12].k_add = 'bd2a395d2b6ac438d192443e615da195';
|
||||
v256d[13].start = '84e1fd6b1a5c946fdf4938977cfbac23';
|
||||
v256d[13].s_row = '84fb386f1ae1ac97df5cfd237c49946b';
|
||||
v256d[13].s_box = '4f63760643e0aa85efa7213201a4e705';
|
||||
v256d[13].k_sch = '101112131415161718191a1b1c1d1e1f';
|
||||
v256d[13].k_add = '5f72641557f5bc92f7be3b291db9f91a';
|
||||
v256d[14].start = '6353e08c0960e104cd70b751bacad0e7';
|
||||
v256d[14].s_row = '63cab7040953d051cd60e0e7ba70e18c';
|
||||
v256d[14].s_box = '00102030405060708090a0b0c0d0e0f0';
|
||||
v256d[14].k_sch = '000102030405060708090a0b0c0d0e0f';
|
||||
v256d[14].output = '00112233445566778899aabbccddeeff';
|
||||
})();
|
||||
164
vectortile/closure-library/closure/goog/crypt/arc4.js
Normal file
164
vectortile/closure-library/closure/goog/crypt/arc4.js
Normal file
@@ -0,0 +1,164 @@
|
||||
// Copyright 2005 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview ARC4 streamcipher implementation. A description of the
|
||||
* algorithm can be found at:
|
||||
* http://www.mozilla.org/projects/security/pki/nss/draft-kaukonen-cipher-arcfour-03.txt.
|
||||
*
|
||||
* Usage:
|
||||
* <code>
|
||||
* var arc4 = new goog.crypt.Arc4();
|
||||
* arc4.setKey(key);
|
||||
* arc4.discard(1536);
|
||||
* arc4.crypt(bytes);
|
||||
* </code>
|
||||
*
|
||||
* Note: For converting between strings and byte arrays, goog.crypt.base64 may
|
||||
* be useful.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.crypt.Arc4');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* ARC4 streamcipher implementation.
|
||||
* @constructor
|
||||
* @final
|
||||
* @struct
|
||||
*/
|
||||
goog.crypt.Arc4 = function() {
|
||||
/**
|
||||
* A permutation of all 256 possible bytes.
|
||||
* @type {Array<number>}
|
||||
* @private
|
||||
*/
|
||||
this.state_ = [];
|
||||
|
||||
/**
|
||||
* 8 bit index pointer into this.state_.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.index1_ = 0;
|
||||
|
||||
/**
|
||||
* 8 bit index pointer into this.state_.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.index2_ = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Initialize the cipher for use with new key.
|
||||
* @param {Array<number>} key A byte array containing the key.
|
||||
* @param {number=} opt_length Indicates # of bytes to take from the key.
|
||||
*/
|
||||
goog.crypt.Arc4.prototype.setKey = function(key, opt_length) {
|
||||
goog.asserts.assertArray(key, 'Key parameter must be a byte array');
|
||||
|
||||
if (!opt_length) {
|
||||
opt_length = key.length;
|
||||
}
|
||||
|
||||
var state = this.state_;
|
||||
|
||||
for (var i = 0; i < 256; ++i) {
|
||||
state[i] = i;
|
||||
}
|
||||
|
||||
var j = 0;
|
||||
for (var i = 0; i < 256; ++i) {
|
||||
j = (j + state[i] + key[i % opt_length]) & 255;
|
||||
|
||||
var tmp = state[i];
|
||||
state[i] = state[j];
|
||||
state[j] = tmp;
|
||||
}
|
||||
|
||||
this.index1_ = 0;
|
||||
this.index2_ = 0;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Discards n bytes of the keystream.
|
||||
* These days 1536 is considered a decent amount to drop to get the key state
|
||||
* warmed-up enough for secure usage. This is not done in the constructor to
|
||||
* preserve efficiency for use cases that do not need this.
|
||||
* NOTE: Discard is identical to crypt without actually xoring any data. It's
|
||||
* unfortunate to have this code duplicated, but this was done for performance
|
||||
* reasons. Alternatives which were attempted:
|
||||
* 1. Create a temp array of the correct length and pass it to crypt. This
|
||||
* works but needlessly allocates an array. But more importantly this
|
||||
* requires choosing an array type (Array or Uint8Array) in discard, and
|
||||
* choosing a different type than will be passed to crypt by the client
|
||||
* code hurts the javascript engines ability to optimize crypt (7x hit in
|
||||
* v8).
|
||||
* 2. Make data option in crypt so discard can pass null, this has a huge
|
||||
* perf hit for crypt.
|
||||
* @param {number} length Number of bytes to disregard from the stream.
|
||||
*/
|
||||
goog.crypt.Arc4.prototype.discard = function(length) {
|
||||
var i = this.index1_;
|
||||
var j = this.index2_;
|
||||
var state = this.state_;
|
||||
|
||||
for (var n = 0; n < length; ++n) {
|
||||
i = (i + 1) & 255;
|
||||
j = (j + state[i]) & 255;
|
||||
|
||||
var tmp = state[i];
|
||||
state[i] = state[j];
|
||||
state[j] = tmp;
|
||||
}
|
||||
|
||||
this.index1_ = i;
|
||||
this.index2_ = j;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* En- or decrypt (same operation for streamciphers like ARC4)
|
||||
* @param {Array<number>|Uint8Array} data The data to be xor-ed in place.
|
||||
* @param {number=} opt_length The number of bytes to crypt.
|
||||
*/
|
||||
goog.crypt.Arc4.prototype.crypt = function(data, opt_length) {
|
||||
if (!opt_length) {
|
||||
opt_length = data.length;
|
||||
}
|
||||
var i = this.index1_;
|
||||
var j = this.index2_;
|
||||
var state = this.state_;
|
||||
|
||||
for (var n = 0; n < opt_length; ++n) {
|
||||
i = (i + 1) & 255;
|
||||
j = (j + state[i]) & 255;
|
||||
|
||||
var tmp = state[i];
|
||||
state[i] = state[j];
|
||||
state[j] = tmp;
|
||||
|
||||
data[n] ^= state[(state[i] + state[j]) & 255];
|
||||
}
|
||||
|
||||
this.index1_ = i;
|
||||
this.index2_ = j;
|
||||
};
|
||||
22
vectortile/closure-library/closure/goog/crypt/arc4_test.html
Normal file
22
vectortile/closure-library/closure/goog/crypt/arc4_test.html
Normal file
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2010 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>
|
||||
Closure Unit Tests - goog.crypt.arc4
|
||||
</title>
|
||||
<script src="../base.js">
|
||||
</script>
|
||||
<script>
|
||||
goog.require('goog.crypt.Arc4Test');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
59
vectortile/closure-library/closure/goog/crypt/arc4_test.js
Normal file
59
vectortile/closure-library/closure/goog/crypt/arc4_test.js
Normal file
@@ -0,0 +1,59 @@
|
||||
// Copyright 2010 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.crypt.Arc4Test');
|
||||
goog.setTestOnly('goog.crypt.Arc4Test');
|
||||
|
||||
goog.require('goog.array');
|
||||
goog.require('goog.crypt.Arc4');
|
||||
goog.require('goog.testing.jsunit');
|
||||
|
||||
function testEncryptionDecryption() {
|
||||
var key = [0x25, 0x26, 0x27, 0x28];
|
||||
var startArray = [0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67];
|
||||
var byteArray = [0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67];
|
||||
|
||||
var arc4 = new goog.crypt.Arc4();
|
||||
arc4.setKey(key);
|
||||
arc4.crypt(byteArray);
|
||||
|
||||
assertArrayEquals(byteArray, [0x51, 0xBB, 0xDD, 0x95, 0x9B, 0x42, 0x34]);
|
||||
|
||||
// The same key and crypt call should unencrypt the data back to its original
|
||||
// state
|
||||
arc4 = new goog.crypt.Arc4();
|
||||
arc4.setKey(key);
|
||||
arc4.crypt(byteArray);
|
||||
assertArrayEquals(byteArray, startArray);
|
||||
}
|
||||
|
||||
function testDiscard() {
|
||||
var key = [0x25, 0x26, 0x27, 0x28];
|
||||
var data = [0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67];
|
||||
|
||||
var arc4 = new goog.crypt.Arc4();
|
||||
arc4.setKey(key);
|
||||
arc4.discard(256);
|
||||
var withDiscard = goog.array.clone(data);
|
||||
arc4.crypt(withDiscard);
|
||||
|
||||
// First encrypting a dummy array should give the same result as
|
||||
// discarding.
|
||||
arc4 = new goog.crypt.Arc4();
|
||||
arc4.setKey(key);
|
||||
var withCrypt = goog.array.clone(data);
|
||||
arc4.crypt(new Array(256));
|
||||
arc4.crypt(withCrypt);
|
||||
assertArrayEquals(withDiscard, withCrypt);
|
||||
}
|
||||
286
vectortile/closure-library/closure/goog/crypt/base64.js
Normal file
286
vectortile/closure-library/closure/goog/crypt/base64.js
Normal file
@@ -0,0 +1,286 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Base64 en/decoding. Not much to say here except that we
|
||||
* work with decoded values in arrays of bytes. By "byte" I mean a number
|
||||
* in [0, 255].
|
||||
*
|
||||
* @author doughtie@google.com (Gavin Doughtie)
|
||||
*/
|
||||
|
||||
goog.provide('goog.crypt.base64');
|
||||
goog.require('goog.crypt');
|
||||
goog.require('goog.userAgent');
|
||||
|
||||
// Static lookup maps, lazily populated by init_()
|
||||
|
||||
|
||||
/**
|
||||
* Maps bytes to characters.
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
goog.crypt.base64.byteToCharMap_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Maps characters to bytes.
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
goog.crypt.base64.charToByteMap_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Maps bytes to websafe characters.
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
goog.crypt.base64.byteToCharMapWebSafe_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Maps websafe characters to bytes.
|
||||
* @type {Object}
|
||||
* @private
|
||||
*/
|
||||
goog.crypt.base64.charToByteMapWebSafe_ = null;
|
||||
|
||||
|
||||
/**
|
||||
* Our default alphabet, shared between
|
||||
* ENCODED_VALS and ENCODED_VALS_WEBSAFE
|
||||
* @type {string}
|
||||
*/
|
||||
goog.crypt.base64.ENCODED_VALS_BASE =
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
|
||||
'abcdefghijklmnopqrstuvwxyz' +
|
||||
'0123456789';
|
||||
|
||||
|
||||
/**
|
||||
* Our default alphabet. Value 64 (=) is special; it means "nothing."
|
||||
* @type {string}
|
||||
*/
|
||||
goog.crypt.base64.ENCODED_VALS =
|
||||
goog.crypt.base64.ENCODED_VALS_BASE + '+/=';
|
||||
|
||||
|
||||
/**
|
||||
* Our websafe alphabet.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.crypt.base64.ENCODED_VALS_WEBSAFE =
|
||||
goog.crypt.base64.ENCODED_VALS_BASE + '-_.';
|
||||
|
||||
|
||||
/**
|
||||
* Whether this browser supports the atob and btoa functions. This extension
|
||||
* started at Mozilla but is now implemented by many browsers. We use the
|
||||
* ASSUME_* variables to avoid pulling in the full useragent detection library
|
||||
* but still allowing the standard per-browser compilations.
|
||||
*
|
||||
* @type {boolean}
|
||||
*/
|
||||
goog.crypt.base64.HAS_NATIVE_SUPPORT = goog.userAgent.GECKO ||
|
||||
goog.userAgent.WEBKIT ||
|
||||
goog.userAgent.OPERA ||
|
||||
typeof(goog.global.atob) == 'function';
|
||||
|
||||
|
||||
/**
|
||||
* Base64-encode an array of bytes.
|
||||
*
|
||||
* @param {Array<number>|Uint8Array} input An array of bytes (numbers with
|
||||
* value in [0, 255]) to encode.
|
||||
* @param {boolean=} opt_webSafe Boolean indicating we should use the
|
||||
* alternative alphabet.
|
||||
* @return {string} The base64 encoded string.
|
||||
*/
|
||||
goog.crypt.base64.encodeByteArray = function(input, opt_webSafe) {
|
||||
if (!goog.isArrayLike(input)) {
|
||||
throw Error('encodeByteArray takes an array as a parameter');
|
||||
}
|
||||
|
||||
goog.crypt.base64.init_();
|
||||
|
||||
var byteToCharMap = opt_webSafe ?
|
||||
goog.crypt.base64.byteToCharMapWebSafe_ :
|
||||
goog.crypt.base64.byteToCharMap_;
|
||||
|
||||
var output = [];
|
||||
|
||||
for (var i = 0; i < input.length; i += 3) {
|
||||
var byte1 = input[i];
|
||||
var haveByte2 = i + 1 < input.length;
|
||||
var byte2 = haveByte2 ? input[i + 1] : 0;
|
||||
var haveByte3 = i + 2 < input.length;
|
||||
var byte3 = haveByte3 ? input[i + 2] : 0;
|
||||
|
||||
var outByte1 = byte1 >> 2;
|
||||
var outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4);
|
||||
var outByte3 = ((byte2 & 0x0F) << 2) | (byte3 >> 6);
|
||||
var outByte4 = byte3 & 0x3F;
|
||||
|
||||
if (!haveByte3) {
|
||||
outByte4 = 64;
|
||||
|
||||
if (!haveByte2) {
|
||||
outByte3 = 64;
|
||||
}
|
||||
}
|
||||
|
||||
output.push(byteToCharMap[outByte1],
|
||||
byteToCharMap[outByte2],
|
||||
byteToCharMap[outByte3],
|
||||
byteToCharMap[outByte4]);
|
||||
}
|
||||
|
||||
return output.join('');
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Base64-encode a string.
|
||||
*
|
||||
* @param {string} input A string to encode.
|
||||
* @param {boolean=} opt_webSafe If true, we should use the
|
||||
* alternative alphabet.
|
||||
* @return {string} The base64 encoded string.
|
||||
*/
|
||||
goog.crypt.base64.encodeString = function(input, opt_webSafe) {
|
||||
// Shortcut for Mozilla browsers that implement
|
||||
// a native base64 encoder in the form of "btoa/atob"
|
||||
if (goog.crypt.base64.HAS_NATIVE_SUPPORT && !opt_webSafe) {
|
||||
return goog.global.btoa(input);
|
||||
}
|
||||
return goog.crypt.base64.encodeByteArray(
|
||||
goog.crypt.stringToByteArray(input), opt_webSafe);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Base64-decode a string.
|
||||
*
|
||||
* @param {string} input to decode.
|
||||
* @param {boolean=} opt_webSafe True if we should use the
|
||||
* alternative alphabet.
|
||||
* @return {string} string representing the decoded value.
|
||||
*/
|
||||
goog.crypt.base64.decodeString = function(input, opt_webSafe) {
|
||||
// Shortcut for Mozilla browsers that implement
|
||||
// a native base64 encoder in the form of "btoa/atob"
|
||||
if (goog.crypt.base64.HAS_NATIVE_SUPPORT && !opt_webSafe) {
|
||||
return goog.global.atob(input);
|
||||
}
|
||||
return goog.crypt.byteArrayToString(
|
||||
goog.crypt.base64.decodeStringToByteArray(input, opt_webSafe));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Base64-decode a string.
|
||||
*
|
||||
* In base-64 decoding, groups of four characters are converted into three
|
||||
* bytes. If the encoder did not apply padding, the input length may not
|
||||
* be a multiple of 4.
|
||||
*
|
||||
* In this case, the last group will have fewer than 4 characters, and
|
||||
* padding will be inferred. If the group has one or two characters, it decodes
|
||||
* to one byte. If the group has three characters, it decodes to two bytes.
|
||||
*
|
||||
* @param {string} input Input to decode.
|
||||
* @param {boolean=} opt_webSafe True if we should use the web-safe alphabet.
|
||||
* @return {!Array<number>} bytes representing the decoded value.
|
||||
*/
|
||||
goog.crypt.base64.decodeStringToByteArray = function(input, opt_webSafe) {
|
||||
goog.crypt.base64.init_();
|
||||
|
||||
var charToByteMap = opt_webSafe ?
|
||||
goog.crypt.base64.charToByteMapWebSafe_ :
|
||||
goog.crypt.base64.charToByteMap_;
|
||||
|
||||
var output = [];
|
||||
|
||||
for (var i = 0; i < input.length; ) {
|
||||
var byte1 = charToByteMap[input.charAt(i++)];
|
||||
|
||||
var haveByte2 = i < input.length;
|
||||
var byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0;
|
||||
++i;
|
||||
|
||||
var haveByte3 = i < input.length;
|
||||
var byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64;
|
||||
++i;
|
||||
|
||||
var haveByte4 = i < input.length;
|
||||
var byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64;
|
||||
++i;
|
||||
|
||||
if (byte1 == null || byte2 == null ||
|
||||
byte3 == null || byte4 == null) {
|
||||
throw Error();
|
||||
}
|
||||
|
||||
var outByte1 = (byte1 << 2) | (byte2 >> 4);
|
||||
output.push(outByte1);
|
||||
|
||||
if (byte3 != 64) {
|
||||
var outByte2 = ((byte2 << 4) & 0xF0) | (byte3 >> 2);
|
||||
output.push(outByte2);
|
||||
|
||||
if (byte4 != 64) {
|
||||
var outByte3 = ((byte3 << 6) & 0xC0) | byte4;
|
||||
output.push(outByte3);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Lazy static initialization function. Called before
|
||||
* accessing any of the static map variables.
|
||||
* @private
|
||||
*/
|
||||
goog.crypt.base64.init_ = function() {
|
||||
if (!goog.crypt.base64.byteToCharMap_) {
|
||||
goog.crypt.base64.byteToCharMap_ = {};
|
||||
goog.crypt.base64.charToByteMap_ = {};
|
||||
goog.crypt.base64.byteToCharMapWebSafe_ = {};
|
||||
goog.crypt.base64.charToByteMapWebSafe_ = {};
|
||||
|
||||
// We want quick mappings back and forth, so we precompute two maps.
|
||||
for (var i = 0; i < goog.crypt.base64.ENCODED_VALS.length; i++) {
|
||||
goog.crypt.base64.byteToCharMap_[i] =
|
||||
goog.crypt.base64.ENCODED_VALS.charAt(i);
|
||||
goog.crypt.base64.charToByteMap_[goog.crypt.base64.byteToCharMap_[i]] = i;
|
||||
goog.crypt.base64.byteToCharMapWebSafe_[i] =
|
||||
goog.crypt.base64.ENCODED_VALS_WEBSAFE.charAt(i);
|
||||
goog.crypt.base64.charToByteMapWebSafe_[
|
||||
goog.crypt.base64.byteToCharMapWebSafe_[i]] = i;
|
||||
|
||||
// Be forgiving when decoding and correctly decode both encodings.
|
||||
if (i >= goog.crypt.base64.ENCODED_VALS_BASE.length) {
|
||||
goog.crypt.base64.charToByteMap_[
|
||||
goog.crypt.base64.ENCODED_VALS_WEBSAFE.charAt(i)] = i;
|
||||
goog.crypt.base64.charToByteMapWebSafe_[
|
||||
goog.crypt.base64.ENCODED_VALS.charAt(i)] = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>
|
||||
Closure Unit Tests - goog.crypt.base64
|
||||
</title>
|
||||
<script src="../base.js">
|
||||
</script>
|
||||
<script>
|
||||
goog.require('goog.crypt.base64Test');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
156
vectortile/closure-library/closure/goog/crypt/base64_test.js
Normal file
156
vectortile/closure-library/closure/goog/crypt/base64_test.js
Normal file
@@ -0,0 +1,156 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.crypt.base64Test');
|
||||
goog.setTestOnly('goog.crypt.base64Test');
|
||||
|
||||
goog.require('goog.crypt');
|
||||
goog.require('goog.crypt.base64');
|
||||
goog.require('goog.testing.jsunit');
|
||||
|
||||
// Static test data
|
||||
var tests = [
|
||||
'', '',
|
||||
'f', 'Zg==',
|
||||
'fo', 'Zm8=',
|
||||
'foo', 'Zm9v',
|
||||
'foob', 'Zm9vYg==',
|
||||
'fooba', 'Zm9vYmE=',
|
||||
'foobar', 'Zm9vYmFy',
|
||||
|
||||
// Testing non-ascii characters (1-10 in chinese)
|
||||
'\xe4\xb8\x80\xe4\xba\x8c\xe4\xb8\x89\xe5\x9b\x9b\xe4\xba\x94\xe5' +
|
||||
'\x85\xad\xe4\xb8\x83\xe5\x85\xab\xe4\xb9\x9d\xe5\x8d\x81',
|
||||
'5LiA5LqM5LiJ5Zub5LqU5YWt5LiD5YWr5Lmd5Y2B'];
|
||||
|
||||
function testByteArrayEncoding() {
|
||||
// Let's see if it's sane by feeding it some well-known values. Index i
|
||||
// has the input and index i+1 has the expected value.
|
||||
for (var i = 0; i < tests.length; i += 2) {
|
||||
var enc = goog.crypt.base64.encodeByteArray(
|
||||
goog.crypt.stringToByteArray(tests[i]));
|
||||
assertEquals(tests[i + 1], enc);
|
||||
var dec = goog.crypt.byteArrayToString(
|
||||
goog.crypt.base64.decodeStringToByteArray(enc));
|
||||
assertEquals(tests[i], dec);
|
||||
|
||||
// Check that websafe decoding accepts non-websafe codes.
|
||||
dec = goog.crypt.byteArrayToString(
|
||||
goog.crypt.base64.decodeStringToByteArray(enc, true /* websafe */));
|
||||
assertEquals(tests[i], dec);
|
||||
|
||||
// Re-encode as websafe.
|
||||
enc = goog.crypt.base64.encodeByteArray(
|
||||
goog.crypt.stringToByteArray(tests[i], true /* websafe */));
|
||||
|
||||
// Check that non-websafe decoding accepts websafe codes.
|
||||
dec = goog.crypt.byteArrayToString(
|
||||
goog.crypt.base64.decodeStringToByteArray(enc));
|
||||
assertEquals(tests[i], dec);
|
||||
|
||||
// Check that websafe decoding accepts websafe codes.
|
||||
dec = goog.crypt.byteArrayToString(
|
||||
goog.crypt.base64.decodeStringToByteArray(enc, true /* websafe */));
|
||||
assertEquals(tests[i], dec);
|
||||
}
|
||||
}
|
||||
|
||||
function testOddLengthByteArrayEncoding() {
|
||||
var buffer = [0, 0, 0];
|
||||
var encodedBuffer = goog.crypt.base64.encodeByteArray(buffer);
|
||||
assertEquals('AAAA', encodedBuffer);
|
||||
|
||||
var decodedBuffer = goog.crypt.base64.decodeStringToByteArray(encodedBuffer);
|
||||
assertEquals(decodedBuffer.length, buffer.length);
|
||||
for (i = 0; i < buffer.length; i++) {
|
||||
assertEquals(buffer[i], decodedBuffer[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// Tests that decoding a string where the length is not a multiple of 4 does
|
||||
// not produce spurious trailing zeroes. This is a regression test for
|
||||
// cl/65120705, which fixes a bug that was introduced when support for
|
||||
// non-padded base64 encoding was added in cl/20209336.
|
||||
function testOddLengthByteArrayDecoding() {
|
||||
// The base-64 encoding of the bytes [97, 98, 99, 100], with no padding.
|
||||
// The padded version would be "YWJjZA==" (length 8), or "YWJjZA.." if
|
||||
// web-safe.
|
||||
var encodedBuffer = 'YWJjZA';
|
||||
var decodedBuffer1 = goog.crypt.base64.decodeStringToByteArray(encodedBuffer);
|
||||
assertEquals(4, decodedBuffer1.length);
|
||||
// Note that byteArrayToString ignores any trailing zeroes because
|
||||
// String.fromCharCode(0) is ''.
|
||||
assertEquals('abcd', goog.crypt.byteArrayToString(decodedBuffer1));
|
||||
|
||||
// Repeat the test in web-safe decoding mode.
|
||||
var decodedBuffer2 = goog.crypt.base64.decodeStringToByteArray(encodedBuffer,
|
||||
true /* web-safe */);
|
||||
assertEquals(4, decodedBuffer2.length);
|
||||
assertEquals('abcd', goog.crypt.byteArrayToString(decodedBuffer2));
|
||||
}
|
||||
|
||||
function testShortcutPathEncoding() {
|
||||
// Test the higher-level API (tests the btoa/atob shortcut path)
|
||||
for (var i = 0; i < tests.length; i += 2) {
|
||||
var enc = goog.crypt.base64.encodeString(tests[i]);
|
||||
assertEquals(tests[i + 1], enc);
|
||||
var dec = goog.crypt.base64.decodeString(enc);
|
||||
assertEquals(tests[i], dec);
|
||||
}
|
||||
}
|
||||
|
||||
function testMultipleIterations() {
|
||||
// Now run it through its paces
|
||||
|
||||
var numIterations = 100;
|
||||
for (var i = 0; i < numIterations; i++) {
|
||||
|
||||
var input = [];
|
||||
for (var j = 0; j < i; j++)
|
||||
input[j] = j % 256;
|
||||
|
||||
var encoded = goog.crypt.base64.encodeByteArray(input);
|
||||
var decoded = goog.crypt.base64.decodeStringToByteArray(encoded);
|
||||
assertEquals('Decoded length not equal to input length?',
|
||||
input.length, decoded.length);
|
||||
|
||||
for (var j = 0; j < i; j++)
|
||||
assertEquals('Values differ at position ' + j, input[j], decoded[j]);
|
||||
}
|
||||
}
|
||||
|
||||
function testWebSafeEncoding() {
|
||||
// Test non-websafe / websafe difference
|
||||
var test = '>>>???>>>???=/+';
|
||||
var enc = goog.crypt.base64.encodeByteArray(
|
||||
goog.crypt.stringToByteArray(test));
|
||||
assertEquals('Non-websafe broken?', 'Pj4+Pz8/Pj4+Pz8/PS8r', enc);
|
||||
enc = goog.crypt.base64.encodeString(test);
|
||||
assertEquals('Non-websafe broken?', 'Pj4+Pz8/Pj4+Pz8/PS8r', enc);
|
||||
enc = goog.crypt.base64.encodeByteArray(
|
||||
goog.crypt.stringToByteArray(test), true /* websafe */);
|
||||
assertEquals('Websafe encoding broken', 'Pj4-Pz8_Pj4-Pz8_PS8r', enc);
|
||||
enc = goog.crypt.base64.encodeString(test, true);
|
||||
assertEquals('Non-websafe broken?', 'Pj4-Pz8_Pj4-Pz8_PS8r', enc);
|
||||
var dec = goog.crypt.byteArrayToString(
|
||||
goog.crypt.base64.decodeStringToByteArray(enc, true /* websafe */));
|
||||
assertEquals('Websafe decoding broken', test, dec);
|
||||
dec = goog.crypt.base64.decodeString(enc, true /* websafe */);
|
||||
assertEquals('Websafe decoding broken', test, dec);
|
||||
|
||||
// Test parsing malformed characters
|
||||
assertThrows('Didn\'t throw on malformed input', function() {
|
||||
goog.crypt.base64.decodeStringToByteArray('foooooo)oooo', true /*websafe*/);
|
||||
});
|
||||
}
|
||||
242
vectortile/closure-library/closure/goog/crypt/basen.js
Normal file
242
vectortile/closure-library/closure/goog/crypt/basen.js
Normal file
@@ -0,0 +1,242 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Numeric base conversion library. Works for arbitrary bases and
|
||||
* arbitrary length numbers.
|
||||
*
|
||||
* For base-64 conversion use base64.js because it is optimized for the specific
|
||||
* conversion to base-64 while this module is generic. Base-64 is defined here
|
||||
* mostly for demonstration purpose.
|
||||
*
|
||||
* TODO: Make base64 and baseN classes that have common interface. (Perhaps...)
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.crypt.baseN');
|
||||
|
||||
|
||||
/**
|
||||
* Base-2, i.e. '01'.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.crypt.baseN.BASE_BINARY = '01';
|
||||
|
||||
|
||||
/**
|
||||
* Base-8, i.e. '01234567'.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.crypt.baseN.BASE_OCTAL = '01234567';
|
||||
|
||||
|
||||
/**
|
||||
* Base-10, i.e. '0123456789'.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.crypt.baseN.BASE_DECIMAL = '0123456789';
|
||||
|
||||
|
||||
/**
|
||||
* Base-16 using lower case, i.e. '0123456789abcdef'.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.crypt.baseN.BASE_LOWERCASE_HEXADECIMAL = '0123456789abcdef';
|
||||
|
||||
|
||||
/**
|
||||
* Base-16 using upper case, i.e. '0123456789ABCDEF'.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.crypt.baseN.BASE_UPPERCASE_HEXADECIMAL = '0123456789ABCDEF';
|
||||
|
||||
|
||||
/**
|
||||
* The more-known version of the BASE-64 encoding. Uses + and / characters.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.crypt.baseN.BASE_64 =
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
|
||||
|
||||
|
||||
/**
|
||||
* URL-safe version of the BASE-64 encoding.
|
||||
* @type {string}
|
||||
*/
|
||||
goog.crypt.baseN.BASE_64_URL_SAFE =
|
||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_';
|
||||
|
||||
|
||||
/**
|
||||
* Converts a number from one numeric base to another.
|
||||
*
|
||||
* The bases are represented as strings, which list allowed digits. Each digit
|
||||
* should be unique. The bases can either be user defined, or any of
|
||||
* goog.crypt.baseN.BASE_xxx.
|
||||
*
|
||||
* The number is in human-readable format, most significant digit first, and is
|
||||
* a non-negative integer. Base designators such as $, 0x, d, b or h (at end)
|
||||
* will be interpreted as digits, so avoid them. Leading zeros will be trimmed.
|
||||
*
|
||||
* Note: for huge bases the result may be inaccurate because of overflowing
|
||||
* 64-bit doubles used by JavaScript for integer calculus. This may happen
|
||||
* if the product of the number of digits in the input and output bases comes
|
||||
* close to 10^16, which is VERY unlikely (100M digits in each base), but
|
||||
* may be possible in the future unicode world. (Unicode 3.2 has less than 100K
|
||||
* characters. However, it reserves some more, close to 1M.)
|
||||
*
|
||||
* @param {string} number The number to convert.
|
||||
* @param {string} inputBase The numeric base the number is in (all digits).
|
||||
* @param {string} outputBase Requested numeric base.
|
||||
* @return {string} The converted number.
|
||||
*/
|
||||
goog.crypt.baseN.recodeString = function(number, inputBase, outputBase) {
|
||||
if (outputBase == '') {
|
||||
throw Error('Empty output base');
|
||||
}
|
||||
|
||||
// Check if number is 0 (special case when we don't want to return '').
|
||||
var isZero = true;
|
||||
for (var i = 0, n = number.length; i < n; i++) {
|
||||
if (number.charAt(i) != inputBase.charAt(0)) {
|
||||
isZero = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isZero) {
|
||||
return outputBase.charAt(0);
|
||||
}
|
||||
|
||||
var numberDigits = goog.crypt.baseN.stringToArray_(number, inputBase);
|
||||
|
||||
var inputBaseSize = inputBase.length;
|
||||
var outputBaseSize = outputBase.length;
|
||||
|
||||
// result = 0.
|
||||
var result = [];
|
||||
|
||||
// For all digits of number, starting with the most significant ...
|
||||
for (var i = numberDigits.length - 1; i >= 0; i--) {
|
||||
|
||||
// result *= number.base.
|
||||
var carry = 0;
|
||||
for (var j = 0, n = result.length; j < n; j++) {
|
||||
var digit = result[j];
|
||||
// This may overflow for huge bases. See function comment.
|
||||
digit = digit * inputBaseSize + carry;
|
||||
if (digit >= outputBaseSize) {
|
||||
var remainder = digit % outputBaseSize;
|
||||
carry = (digit - remainder) / outputBaseSize;
|
||||
digit = remainder;
|
||||
} else {
|
||||
carry = 0;
|
||||
}
|
||||
result[j] = digit;
|
||||
}
|
||||
while (carry) {
|
||||
var remainder = carry % outputBaseSize;
|
||||
result.push(remainder);
|
||||
carry = (carry - remainder) / outputBaseSize;
|
||||
}
|
||||
|
||||
// result += number[i].
|
||||
carry = numberDigits[i];
|
||||
var j = 0;
|
||||
while (carry) {
|
||||
if (j >= result.length) {
|
||||
// Extend result with a leading zero which will be overwritten below.
|
||||
result.push(0);
|
||||
}
|
||||
var digit = result[j];
|
||||
digit += carry;
|
||||
if (digit >= outputBaseSize) {
|
||||
var remainder = digit % outputBaseSize;
|
||||
carry = (digit - remainder) / outputBaseSize;
|
||||
digit = remainder;
|
||||
} else {
|
||||
carry = 0;
|
||||
}
|
||||
result[j] = digit;
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
return goog.crypt.baseN.arrayToString_(result, outputBase);
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts a string representation of a number to an array of digit values.
|
||||
*
|
||||
* More precisely, the digit values are indices into the number base, which
|
||||
* is represented as a string, which can either be user defined or one of the
|
||||
* BASE_xxx constants.
|
||||
*
|
||||
* Throws an Error if the number contains a digit not found in the base.
|
||||
*
|
||||
* @param {string} number The string to convert, most significant digit first.
|
||||
* @param {string} base Digits in the base.
|
||||
* @return {!Array<number>} Array of digit values, least significant digit
|
||||
* first.
|
||||
* @private
|
||||
*/
|
||||
goog.crypt.baseN.stringToArray_ = function(number, base) {
|
||||
var index = {};
|
||||
for (var i = 0, n = base.length; i < n; i++) {
|
||||
index[base.charAt(i)] = i;
|
||||
}
|
||||
var result = [];
|
||||
for (var i = number.length - 1; i >= 0; i--) {
|
||||
var character = number.charAt(i);
|
||||
var digit = index[character];
|
||||
if (typeof digit == 'undefined') {
|
||||
throw Error('Number ' + number +
|
||||
' contains a character not found in base ' +
|
||||
base + ', which is ' + character);
|
||||
}
|
||||
result.push(digit);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Converts an array representation of a number to a string.
|
||||
*
|
||||
* More precisely, the elements of the input array are indices into the base,
|
||||
* which is represented as a string, which can either be user defined or one of
|
||||
* the BASE_xxx constants.
|
||||
*
|
||||
* Throws an Error if the number contains a digit which is outside the range
|
||||
* 0 ... base.length - 1.
|
||||
*
|
||||
* @param {Array<number>} number Array of digit values, least significant
|
||||
* first.
|
||||
* @param {string} base Digits in the base.
|
||||
* @return {string} Number as a string, most significant digit first.
|
||||
* @private
|
||||
*/
|
||||
goog.crypt.baseN.arrayToString_ = function(number, base) {
|
||||
var n = number.length;
|
||||
var chars = [];
|
||||
var baseSize = base.length;
|
||||
for (var i = n - 1; i >= 0; i--) {
|
||||
var digit = number[i];
|
||||
if (digit >= baseSize || digit < 0) {
|
||||
throw Error('Number ' + number + ' contains an invalid digit: ' + digit);
|
||||
}
|
||||
chars.push(base.charAt(digit));
|
||||
}
|
||||
return chars.join('');
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>
|
||||
Closure Unit Tests - goog.crypt.baseN
|
||||
</title>
|
||||
<script src="../base.js">
|
||||
</script>
|
||||
<script>
|
||||
goog.require('goog.crypt.baseNTest');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
165
vectortile/closure-library/closure/goog/crypt/basen_test.js
Normal file
165
vectortile/closure-library/closure/goog/crypt/basen_test.js
Normal file
@@ -0,0 +1,165 @@
|
||||
// Copyright 2007 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Tests for arbitrary base conversion library baseconversion.js.
|
||||
*/
|
||||
|
||||
goog.provide('goog.crypt.baseNTest');
|
||||
goog.setTestOnly('goog.crypt.baseNTest');
|
||||
|
||||
goog.require('goog.crypt.baseN');
|
||||
goog.require('goog.testing.jsunit');
|
||||
|
||||
function testDecToHex() {
|
||||
verifyConversion(goog.crypt.baseN.BASE_DECIMAL, '0',
|
||||
goog.crypt.baseN.BASE_LOWERCASE_HEXADECIMAL, '0');
|
||||
verifyConversion(goog.crypt.baseN.BASE_DECIMAL, '9',
|
||||
goog.crypt.baseN.BASE_UPPERCASE_HEXADECIMAL, '9');
|
||||
verifyConversion(goog.crypt.baseN.BASE_DECIMAL, '13',
|
||||
goog.crypt.baseN.BASE_LOWERCASE_HEXADECIMAL, 'd');
|
||||
verifyConversion(goog.crypt.baseN.BASE_DECIMAL, '255',
|
||||
goog.crypt.baseN.BASE_UPPERCASE_HEXADECIMAL, 'FF');
|
||||
verifyConversion(goog.crypt.baseN.BASE_DECIMAL,
|
||||
'53425987345897',
|
||||
goog.crypt.baseN.BASE_LOWERCASE_HEXADECIMAL,
|
||||
'309734ff5de9');
|
||||
verifyConversion(goog.crypt.baseN.BASE_DECIMAL,
|
||||
'987080888',
|
||||
goog.crypt.baseN.BASE_UPPERCASE_HEXADECIMAL,
|
||||
'3AD5A8B8');
|
||||
verifyConversion(goog.crypt.baseN.BASE_DECIMAL,
|
||||
'009341587237',
|
||||
goog.crypt.baseN.BASE_LOWERCASE_HEXADECIMAL,
|
||||
'22ccd4f25');
|
||||
}
|
||||
|
||||
function testBinToDec() {
|
||||
verifyConversion(
|
||||
goog.crypt.baseN.BASE_BINARY,
|
||||
'11101010101000100010010000010010010000111101000100110111000000100001' +
|
||||
'01100100111110110010000010110100111101000010010100001011111011111100' +
|
||||
'00000010000010000101010101000000000101100000000100011111011101111001' +
|
||||
'10000001000000000100101110001001001101101001101111010101111100010001' +
|
||||
'11011100000110111000000100111011100100010010011001111011001111001011' +
|
||||
'10001000101111001010011101101100110110011110010000011100101011110010' +
|
||||
'11010001001111110011000000001001011011111011010000110011010000010111' +
|
||||
'10111100000001100010111100000100000000110001011101011110100000011010' +
|
||||
'0110000100011111',
|
||||
goog.crypt.baseN.BASE_DECIMAL,
|
||||
'34589745906769047354795784390596748934723904739085568907689045723489' +
|
||||
'05745789789078907890789023447892365623589745678902348976234598723459' +
|
||||
'087523496723486089723459078349087');
|
||||
}
|
||||
|
||||
function testDecToBin() {
|
||||
verifyConversion(
|
||||
goog.crypt.baseN.BASE_DECIMAL,
|
||||
'00342589674590347859734908573490568347534805468907960579056785605496' +
|
||||
'83475873465859072390486756098742380573908572390463805745656623475234' +
|
||||
'82345670247851902784123897349486238502378940637925807378946358964328' +
|
||||
'57906148572346857346409823758034763928401296023947234784623765456367' +
|
||||
'764623627623574',
|
||||
goog.crypt.baseN.BASE_BINARY,
|
||||
'10010011011100101010001111100111001100110000110111111110010110101000' +
|
||||
'01010110110010000111000001100110100101010000101001100001011000101111' +
|
||||
'01011101111100101101010010000111011110011110010101111001110010100100' +
|
||||
'10111110000101111011010000000111111011110010011110101011100101000001' +
|
||||
'00011000101010011001101000011101001010001101011110101001011011100101' +
|
||||
'11100000101000010010101001011001100100101110111101010000011010001010' +
|
||||
'01011100100111110001100111100100011001001001100011011100100111011111' +
|
||||
'01000100101001000100110001011010010000011010111101111111111111110100' +
|
||||
'01100101001111001111100110101000001100100000111111100101110010111011' +
|
||||
'10110110001100100011101010110110100001001000101011001001100011010110' +
|
||||
'10110100000110000110010111110100000100110110010010010101111001001111' +
|
||||
'11100100000010101111110100011010011101011010001101110011100110111111' +
|
||||
'11000100001111010000000101011011000010010000000100111111010110111100' +
|
||||
'00101111010011011010011010010001000101100001111001110010010110');
|
||||
}
|
||||
|
||||
function test7To9() {
|
||||
verifyConversion(
|
||||
'0123456', // Base 7.
|
||||
'60625646056660665666066534602566346056634560665606666656465634265434' +
|
||||
'66563465664566346406366534664656650660665623456663456654360665',
|
||||
'012345678', // Base 9.
|
||||
'11451222686557606458341381287142358175337801548087003804852781764284' +
|
||||
'273762357630423116743334671762638240652740158536');
|
||||
}
|
||||
|
||||
function testZeros() {
|
||||
verifyConversion(goog.crypt.baseN.BASE_DECIMAL, '0',
|
||||
goog.crypt.baseN.BASE_LOWERCASE_HEXADECIMAL, '0');
|
||||
verifyConversion(goog.crypt.baseN.BASE_DECIMAL, '000',
|
||||
goog.crypt.baseN.BASE_LOWERCASE_HEXADECIMAL, '0');
|
||||
verifyConversion(goog.crypt.baseN.BASE_DECIMAL, '0000007',
|
||||
goog.crypt.baseN.BASE_LOWERCASE_HEXADECIMAL, '7');
|
||||
}
|
||||
|
||||
function testArbitraryBases() {
|
||||
verifyConversion('X9(', // Base 3.
|
||||
'9(XX((9X(XX9(9X9(X9(',
|
||||
'a:*o9', // Base 5.
|
||||
':oa**:9o9**9oo');
|
||||
}
|
||||
|
||||
function testEmptyBases() {
|
||||
var e = assertThrows(function() {
|
||||
goog.crypt.baseN.recodeString('1230', '', '0123');
|
||||
});
|
||||
assertEquals('Exception message', 'Number 1230 contains a character ' +
|
||||
'not found in base , which is 0', e.message);
|
||||
|
||||
e = assertThrows(function() {
|
||||
goog.crypt.baseN.recodeString('1230', '0123', '');
|
||||
});
|
||||
assertEquals('Exception message', 'Empty output base', e.message);
|
||||
}
|
||||
|
||||
function testInvalidDigits() {
|
||||
var e = assertThrows(function() {
|
||||
goog.crypt.baseN.recodeString('123x456', '01234567', '01234567');
|
||||
});
|
||||
assertEquals('Exception message', 'Number 123x456 contains a character ' +
|
||||
'not found in base 01234567, which is x', e.message);
|
||||
}
|
||||
|
||||
function makeHugeBase() {
|
||||
// Number of digits in the base.
|
||||
// Tests break if this is set to 200'000. The reason for that is
|
||||
// String.fromCharCode(196609) == String.fromCharCode(1).
|
||||
var baseSize = 20000;
|
||||
var tab = [];
|
||||
for (var i = 0; i < baseSize; i++) {
|
||||
tab.push(String.fromCharCode(i));
|
||||
}
|
||||
return tab.join('');
|
||||
}
|
||||
|
||||
function testHugeInputBase() {
|
||||
verifyConversion(makeHugeBase(), String.fromCharCode(12345),
|
||||
goog.crypt.baseN.BASE_DECIMAL, '12345');
|
||||
}
|
||||
|
||||
function testHugeOutputBase() {
|
||||
verifyConversion(goog.crypt.baseN.BASE_DECIMAL, '12345',
|
||||
makeHugeBase(), String.fromCharCode(12345));
|
||||
}
|
||||
|
||||
function verifyConversion(inputBase, inputNumber, outputBase, outputNumber) {
|
||||
assertEquals(outputNumber,
|
||||
goog.crypt.baseN.recodeString(inputNumber,
|
||||
inputBase,
|
||||
outputBase));
|
||||
}
|
||||
285
vectortile/closure-library/closure/goog/crypt/blobhasher.js
Normal file
285
vectortile/closure-library/closure/goog/crypt/blobhasher.js
Normal file
@@ -0,0 +1,285 @@
|
||||
// Copyright 2011 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Asynchronous hash computer for the Blob interface.
|
||||
*
|
||||
* The Blob interface, part of the HTML5 File API, is supported on Chrome 7+,
|
||||
* Firefox 4.0 and Opera 11. No Blob interface implementation is expected on
|
||||
* Internet Explorer 10. Chrome 11, Firefox 5.0 and the subsequent release of
|
||||
* Opera are supposed to use vendor prefixes due to evolving API, see
|
||||
* http://dev.w3.org/2006/webapi/FileAPI/ for details.
|
||||
*
|
||||
* This implementation currently uses upcoming Chrome and Firefox prefixes,
|
||||
* plus the original Blob.slice specification, as implemented on Chrome 10
|
||||
* and Firefox 4.0.
|
||||
*
|
||||
*/
|
||||
|
||||
goog.provide('goog.crypt.BlobHasher');
|
||||
goog.provide('goog.crypt.BlobHasher.EventType');
|
||||
|
||||
goog.require('goog.asserts');
|
||||
goog.require('goog.events.EventTarget');
|
||||
goog.require('goog.fs');
|
||||
goog.require('goog.log');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Construct the hash computer.
|
||||
*
|
||||
* @param {!goog.crypt.Hash} hashFn The hash function to use.
|
||||
* @param {number=} opt_blockSize Processing block size.
|
||||
* @constructor
|
||||
* @struct
|
||||
* @suppress {checkStructDictInheritance}
|
||||
* @extends {goog.events.EventTarget}
|
||||
* @final
|
||||
*/
|
||||
goog.crypt.BlobHasher = function(hashFn, opt_blockSize) {
|
||||
goog.crypt.BlobHasher.base(this, 'constructor');
|
||||
|
||||
/**
|
||||
* The actual hash function.
|
||||
* @type {!goog.crypt.Hash}
|
||||
* @private
|
||||
*/
|
||||
this.hashFn_ = hashFn;
|
||||
|
||||
/**
|
||||
* The blob being processed or null if no blob is being processed.
|
||||
* @type {Blob}
|
||||
* @private
|
||||
*/
|
||||
this.blob_ = null;
|
||||
|
||||
/**
|
||||
* Computed hash value.
|
||||
* @type {Array<number>}
|
||||
* @private
|
||||
*/
|
||||
this.hashVal_ = null;
|
||||
|
||||
/**
|
||||
* Number of bytes already processed.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.bytesProcessed_ = 0;
|
||||
|
||||
/**
|
||||
* The number of bytes to hash or Infinity for no limit.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.hashingLimit_ = Infinity;
|
||||
|
||||
/**
|
||||
* Processing block size.
|
||||
* @type {number}
|
||||
* @private
|
||||
*/
|
||||
this.blockSize_ = opt_blockSize || 5000000;
|
||||
|
||||
/**
|
||||
* File reader object. Will be null if no chunk is currently being read.
|
||||
* @type {FileReader}
|
||||
* @private
|
||||
*/
|
||||
this.fileReader_ = null;
|
||||
|
||||
/**
|
||||
* The logger used by this object.
|
||||
* @type {goog.log.Logger}
|
||||
* @private
|
||||
*/
|
||||
this.logger_ = goog.log.getLogger('goog.crypt.BlobHasher');
|
||||
};
|
||||
goog.inherits(goog.crypt.BlobHasher, goog.events.EventTarget);
|
||||
|
||||
|
||||
/**
|
||||
* Event names for hash computation events
|
||||
* @enum {string}
|
||||
*/
|
||||
goog.crypt.BlobHasher.EventType = {
|
||||
STARTED: 'started',
|
||||
PROGRESS: 'progress',
|
||||
THROTTLED: 'throttled',
|
||||
COMPLETE: 'complete',
|
||||
ABORT: 'abort',
|
||||
ERROR: 'error'
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Start the hash computation.
|
||||
* @param {!Blob} blob The blob of data to compute the hash for.
|
||||
*/
|
||||
goog.crypt.BlobHasher.prototype.hash = function(blob) {
|
||||
this.abort();
|
||||
this.hashFn_.reset();
|
||||
this.blob_ = blob;
|
||||
this.hashVal_ = null;
|
||||
this.bytesProcessed_ = 0;
|
||||
this.dispatchEvent(goog.crypt.BlobHasher.EventType.STARTED);
|
||||
|
||||
this.processNextBlock_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Sets the maximum number of bytes to hash or Infinity for no limit. Can be
|
||||
* called before hash() to throttle the hash computation. The hash computation
|
||||
* can then be continued by repeatedly calling setHashingLimit() with greater
|
||||
* byte offsets. This is useful if you don't need the hash until some time in
|
||||
* the future, for example when uploading a file and you don't need the hash
|
||||
* until the transfer is complete.
|
||||
* @param {number} byteOffset The byte offset to compute the hash up to.
|
||||
* Should be a non-negative integer or Infinity for no limit. Negative
|
||||
* values are not allowed.
|
||||
*/
|
||||
goog.crypt.BlobHasher.prototype.setHashingLimit = function(byteOffset) {
|
||||
goog.asserts.assert(byteOffset >= 0, 'Hashing limit must be non-negative.');
|
||||
this.hashingLimit_ = byteOffset;
|
||||
|
||||
// Resume processing if a blob is currently being hashed, but no block read
|
||||
// is currently in progress.
|
||||
if (this.blob_ && !this.fileReader_) {
|
||||
this.processNextBlock_();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Abort hash computation.
|
||||
*/
|
||||
goog.crypt.BlobHasher.prototype.abort = function() {
|
||||
if (this.fileReader_) {
|
||||
this.fileReader_.abort();
|
||||
this.fileReader_ = null;
|
||||
}
|
||||
|
||||
if (this.blob_) {
|
||||
this.blob_ = null;
|
||||
this.dispatchEvent(goog.crypt.BlobHasher.EventType.ABORT);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {number} Number of bytes processed so far.
|
||||
*/
|
||||
goog.crypt.BlobHasher.prototype.getBytesProcessed = function() {
|
||||
return this.bytesProcessed_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @return {Array<number>} The computed hash value or null if not ready.
|
||||
*/
|
||||
goog.crypt.BlobHasher.prototype.getHash = function() {
|
||||
return this.hashVal_;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Helper function setting up the processing for the next block, or finalizing
|
||||
* the computation if all blocks were processed.
|
||||
* @private
|
||||
*/
|
||||
goog.crypt.BlobHasher.prototype.processNextBlock_ = function() {
|
||||
goog.asserts.assert(this.blob_, 'A hash computation must be in progress.');
|
||||
|
||||
if (this.bytesProcessed_ < this.blob_.size) {
|
||||
|
||||
if (this.hashingLimit_ <= this.bytesProcessed_) {
|
||||
// Throttle limit reached. Wait until we are allowed to hash more bytes.
|
||||
this.dispatchEvent(goog.crypt.BlobHasher.EventType.THROTTLED);
|
||||
return;
|
||||
}
|
||||
|
||||
// We have to reset the FileReader every time, otherwise it fails on
|
||||
// Chrome, including the latest Chrome 12 beta.
|
||||
// http://code.google.com/p/chromium/issues/detail?id=82346
|
||||
this.fileReader_ = new FileReader();
|
||||
this.fileReader_.onload = goog.bind(this.onLoad_, this);
|
||||
this.fileReader_.onerror = goog.bind(this.onError_, this);
|
||||
|
||||
var endOffset = Math.min(this.hashingLimit_, this.blob_.size);
|
||||
var size = Math.min(endOffset - this.bytesProcessed_, this.blockSize_);
|
||||
var chunk = goog.fs.sliceBlob(this.blob_, this.bytesProcessed_,
|
||||
this.bytesProcessed_ + size);
|
||||
if (!chunk || chunk.size != size) {
|
||||
goog.log.error(this.logger_, 'Failed slicing the blob');
|
||||
this.onError_();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.fileReader_.readAsArrayBuffer) {
|
||||
this.fileReader_.readAsArrayBuffer(chunk);
|
||||
} else if (this.fileReader_.readAsBinaryString) {
|
||||
this.fileReader_.readAsBinaryString(chunk);
|
||||
} else {
|
||||
goog.log.error(this.logger_, 'Failed calling the chunk reader');
|
||||
this.onError_();
|
||||
}
|
||||
} else {
|
||||
this.hashVal_ = this.hashFn_.digest();
|
||||
this.blob_ = null;
|
||||
this.dispatchEvent(goog.crypt.BlobHasher.EventType.COMPLETE);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handle processing block loaded.
|
||||
* @private
|
||||
*/
|
||||
goog.crypt.BlobHasher.prototype.onLoad_ = function() {
|
||||
goog.log.info(this.logger_, 'Successfully loaded a chunk');
|
||||
|
||||
var array = null;
|
||||
if (this.fileReader_.result instanceof Array ||
|
||||
goog.isString(this.fileReader_.result)) {
|
||||
array = this.fileReader_.result;
|
||||
} else if (goog.global['ArrayBuffer'] && goog.global['Uint8Array'] &&
|
||||
this.fileReader_.result instanceof ArrayBuffer) {
|
||||
array = new Uint8Array(this.fileReader_.result);
|
||||
}
|
||||
if (!array) {
|
||||
goog.log.error(this.logger_, 'Failed reading the chunk');
|
||||
this.onError_();
|
||||
return;
|
||||
}
|
||||
|
||||
this.hashFn_.update(array);
|
||||
this.bytesProcessed_ += array.length;
|
||||
this.fileReader_ = null;
|
||||
this.dispatchEvent(goog.crypt.BlobHasher.EventType.PROGRESS);
|
||||
|
||||
this.processNextBlock_();
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Handles error.
|
||||
* @private
|
||||
*/
|
||||
goog.crypt.BlobHasher.prototype.onError_ = function() {
|
||||
this.fileReader_ = null;
|
||||
this.blob_ = null;
|
||||
this.dispatchEvent(goog.crypt.BlobHasher.EventType.ERROR);
|
||||
};
|
||||
@@ -0,0 +1,23 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2011 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
|
||||
<title>
|
||||
Closure Unit Tests - goog.crypt.BlobHasher
|
||||
</title>
|
||||
<script src="../base.js">
|
||||
</script>
|
||||
<script>
|
||||
goog.require('goog.crypt.BlobHasherTest');
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
382
vectortile/closure-library/closure/goog/crypt/blobhasher_test.js
Normal file
382
vectortile/closure-library/closure/goog/crypt/blobhasher_test.js
Normal file
@@ -0,0 +1,382 @@
|
||||
// Copyright 2011 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
goog.provide('goog.crypt.BlobHasherTest');
|
||||
goog.setTestOnly('goog.crypt.BlobHasherTest');
|
||||
|
||||
goog.require('goog.crypt');
|
||||
goog.require('goog.crypt.BlobHasher');
|
||||
goog.require('goog.crypt.Md5');
|
||||
goog.require('goog.events');
|
||||
goog.require('goog.testing.PropertyReplacer');
|
||||
goog.require('goog.testing.jsunit');
|
||||
|
||||
// A browser-independent mock of goog.fs.sliceBlob. The actual implementation
|
||||
// calls the underlying slice method differently based on browser version.
|
||||
// This mock does not support negative opt_end.
|
||||
var fsSliceBlobMock = function(blob, start, opt_end) {
|
||||
if (!goog.isNumber(opt_end)) {
|
||||
opt_end = blob.size;
|
||||
}
|
||||
return blob.slice(start, opt_end);
|
||||
};
|
||||
|
||||
// Mock out the Blob using a string.
|
||||
BlobMock = function(string) {
|
||||
this.data = string;
|
||||
this.size = this.data.length;
|
||||
};
|
||||
|
||||
BlobMock.prototype.slice = function(start, end) {
|
||||
return new BlobMock(this.data.substr(start, end - start));
|
||||
};
|
||||
|
||||
|
||||
// Mock out the FileReader to have control over the flow.
|
||||
FileReaderMock = function() {
|
||||
this.array_ = [];
|
||||
this.result = null;
|
||||
this.readyState = this.EMPTY;
|
||||
|
||||
this.onload = null;
|
||||
this.onabort = null;
|
||||
this.onerror = null;
|
||||
};
|
||||
|
||||
FileReaderMock.prototype.EMPTY = 0;
|
||||
FileReaderMock.prototype.LOADING = 1;
|
||||
FileReaderMock.prototype.DONE = 2;
|
||||
|
||||
FileReaderMock.prototype.mockLoad = function() {
|
||||
this.readyState = this.DONE;
|
||||
this.result = this.array_;
|
||||
if (this.onload) {
|
||||
this.onload.call();
|
||||
}
|
||||
};
|
||||
|
||||
FileReaderMock.prototype.abort = function() {
|
||||
this.readyState = this.DONE;
|
||||
if (this.onabort) {
|
||||
this.onabort.call();
|
||||
}
|
||||
};
|
||||
|
||||
FileReaderMock.prototype.mockError = function() {
|
||||
this.readyState = this.DONE;
|
||||
if (this.onerror) {
|
||||
this.onerror.call();
|
||||
}
|
||||
};
|
||||
|
||||
FileReaderMock.prototype.readAsArrayBuffer = function(blobMock) {
|
||||
this.readyState = this.LOADING;
|
||||
this.array_ = [];
|
||||
for (var i = 0; i < blobMock.size; ++i) {
|
||||
this.array_[i] = blobMock.data.charCodeAt(i);
|
||||
}
|
||||
};
|
||||
|
||||
FileReaderMock.prototype.isLoading = function() {
|
||||
return this.readyState == this.LOADING;
|
||||
};
|
||||
|
||||
var stubs = new goog.testing.PropertyReplacer();
|
||||
function setUp() {
|
||||
stubs.set(goog.global, 'FileReader', FileReaderMock);
|
||||
stubs.set(goog.fs, 'sliceBlob', fsSliceBlobMock);
|
||||
}
|
||||
|
||||
function tearDown() {
|
||||
stubs.reset();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Makes the blobHasher read chunks from the blob and hash it. The number of
|
||||
* reads shall not exceed a pre-determined number (typically blob size / chunk
|
||||
* size) for computing hash. This function fails fast (after maxReads is
|
||||
* reached), assuming that the hasher failed to generate hashes. This prevents
|
||||
* the test suite from going into infinite loop.
|
||||
* @param {!goog.crypt.BlobHasher} blobHasher Hasher in action.
|
||||
* @param {number} maxReads Max number of read attempts.
|
||||
*/
|
||||
function readFromBlob(blobHasher, maxReads) {
|
||||
var counter = 0;
|
||||
while (blobHasher.fileReader_ && blobHasher.fileReader_.isLoading() &&
|
||||
counter <= maxReads) {
|
||||
blobHasher.fileReader_.mockLoad();
|
||||
counter++;
|
||||
}
|
||||
assertTrue(counter <= maxReads);
|
||||
return counter;
|
||||
}
|
||||
|
||||
function testBasicOperations() {
|
||||
if (!window.Blob) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Test hashing with one chunk.
|
||||
var hashFn = new goog.crypt.Md5();
|
||||
var blobHasher = new goog.crypt.BlobHasher(hashFn);
|
||||
var blob = new BlobMock('The quick brown fox jumps over the lazy dog');
|
||||
blobHasher.hash(blob);
|
||||
readFromBlob(blobHasher, 1);
|
||||
assertEquals('9e107d9d372bb6826bd81d3542a419d6',
|
||||
goog.crypt.byteArrayToHex(blobHasher.getHash()));
|
||||
|
||||
// Test hashing with multiple chunks.
|
||||
blobHasher = new goog.crypt.BlobHasher(hashFn, 7);
|
||||
blobHasher.hash(blob);
|
||||
readFromBlob(blobHasher, Math.ceil(blob.size / 7));
|
||||
assertEquals('9e107d9d372bb6826bd81d3542a419d6',
|
||||
goog.crypt.byteArrayToHex(blobHasher.getHash()));
|
||||
|
||||
// Test hashing with no chunks.
|
||||
blob = new BlobMock('');
|
||||
blobHasher.hash(blob);
|
||||
readFromBlob(blobHasher, 1);
|
||||
assertEquals('d41d8cd98f00b204e9800998ecf8427e',
|
||||
goog.crypt.byteArrayToHex(blobHasher.getHash()));
|
||||
|
||||
}
|
||||
|
||||
function testNormalFlow() {
|
||||
if (!window.Blob) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Test the flow with one chunk.
|
||||
var hashFn = new goog.crypt.Md5();
|
||||
var blobHasher = new goog.crypt.BlobHasher(hashFn, 13);
|
||||
var blob = new BlobMock('short');
|
||||
var startedEvents = 0;
|
||||
var progressEvents = 0;
|
||||
var completeEvents = 0;
|
||||
goog.events.listen(blobHasher, goog.crypt.BlobHasher.EventType.STARTED,
|
||||
function() { ++startedEvents; });
|
||||
goog.events.listen(blobHasher, goog.crypt.BlobHasher.EventType.PROGRESS,
|
||||
function() { ++progressEvents; });
|
||||
goog.events.listen(blobHasher, goog.crypt.BlobHasher.EventType.COMPLETE,
|
||||
function() { ++completeEvents; });
|
||||
blobHasher.hash(blob);
|
||||
assertEquals(1, startedEvents);
|
||||
assertEquals(0, progressEvents);
|
||||
assertEquals(0, completeEvents);
|
||||
readFromBlob(blobHasher, 1);
|
||||
assertEquals(1, startedEvents);
|
||||
assertEquals(1, progressEvents);
|
||||
assertEquals(1, completeEvents);
|
||||
|
||||
// Test the flow with multiple chunks.
|
||||
blob = new BlobMock('The quick brown fox jumps over the lazy dog');
|
||||
startedEvents = 0;
|
||||
progressEvents = 0;
|
||||
completeEvents = 0;
|
||||
var progressLoops = 0;
|
||||
blobHasher.hash(blob);
|
||||
assertEquals(1, startedEvents);
|
||||
assertEquals(0, progressEvents);
|
||||
assertEquals(0, completeEvents);
|
||||
progressLoops = readFromBlob(blobHasher, Math.ceil(blob.size / 13));
|
||||
assertEquals(1, startedEvents);
|
||||
assertEquals(progressLoops, progressEvents);
|
||||
assertEquals(1, completeEvents);
|
||||
}
|
||||
|
||||
function testAbortsAndErrors() {
|
||||
if (!window.Blob) {
|
||||
return;
|
||||
}
|
||||
|
||||
var hashFn = new goog.crypt.Md5();
|
||||
var blobHasher = new goog.crypt.BlobHasher(hashFn, 13);
|
||||
var blob = new BlobMock('The quick brown fox jumps over the lazy dog');
|
||||
var abortEvents = 0;
|
||||
var errorEvents = 0;
|
||||
var completeEvents = 0;
|
||||
goog.events.listen(blobHasher, goog.crypt.BlobHasher.EventType.ABORT,
|
||||
function() { ++abortEvents; });
|
||||
goog.events.listen(blobHasher, goog.crypt.BlobHasher.EventType.ERROR,
|
||||
function() { ++errorEvents; });
|
||||
goog.events.listen(blobHasher, goog.crypt.BlobHasher.EventType.COMPLETE,
|
||||
function() { ++completeEvents; });
|
||||
|
||||
// Immediate abort.
|
||||
blobHasher.hash(blob);
|
||||
assertEquals(0, abortEvents);
|
||||
assertEquals(0, errorEvents);
|
||||
assertEquals(0, completeEvents);
|
||||
blobHasher.abort();
|
||||
blobHasher.abort();
|
||||
assertEquals(1, abortEvents);
|
||||
assertEquals(0, errorEvents);
|
||||
assertEquals(0, completeEvents);
|
||||
abortEvents = 0;
|
||||
|
||||
// Delayed abort.
|
||||
blobHasher.hash(blob);
|
||||
blobHasher.fileReader_.mockLoad();
|
||||
assertEquals(0, abortEvents);
|
||||
assertEquals(0, errorEvents);
|
||||
assertEquals(0, completeEvents);
|
||||
blobHasher.abort();
|
||||
blobHasher.abort();
|
||||
assertEquals(1, abortEvents);
|
||||
assertEquals(0, errorEvents);
|
||||
assertEquals(0, completeEvents);
|
||||
abortEvents = 0;
|
||||
|
||||
// Immediate error.
|
||||
blobHasher.hash(blob);
|
||||
blobHasher.fileReader_.mockError();
|
||||
assertEquals(0, abortEvents);
|
||||
assertEquals(1, errorEvents);
|
||||
assertEquals(0, completeEvents);
|
||||
errorEvents = 0;
|
||||
|
||||
// Delayed error.
|
||||
blobHasher.hash(blob);
|
||||
blobHasher.fileReader_.mockLoad();
|
||||
blobHasher.fileReader_.mockError();
|
||||
assertEquals(0, abortEvents);
|
||||
assertEquals(1, errorEvents);
|
||||
assertEquals(0, completeEvents);
|
||||
abortEvents = 0;
|
||||
|
||||
}
|
||||
|
||||
function testBasicThrottling() {
|
||||
if (!window.Blob) {
|
||||
return;
|
||||
}
|
||||
|
||||
var hashFn = new goog.crypt.Md5();
|
||||
var blobHasher = new goog.crypt.BlobHasher(hashFn, 5);
|
||||
var blob = new BlobMock('The quick brown fox jumps over the lazy dog');
|
||||
var throttledEvents = 0;
|
||||
var completeEvents = 0;
|
||||
goog.events.listen(blobHasher, goog.crypt.BlobHasher.EventType.THROTTLED,
|
||||
function() { ++throttledEvents; });
|
||||
goog.events.listen(blobHasher, goog.crypt.BlobHasher.EventType.COMPLETE,
|
||||
function() { ++completeEvents; });
|
||||
|
||||
// Start a throttled hash. No chunks should be processed yet.
|
||||
blobHasher.setHashingLimit(0);
|
||||
assertEquals(0, throttledEvents);
|
||||
blobHasher.hash(blob);
|
||||
assertEquals(1, throttledEvents);
|
||||
assertEquals(0, blobHasher.getBytesProcessed());
|
||||
assertNull(blobHasher.fileReader_);
|
||||
|
||||
// One chunk should be processed.
|
||||
blobHasher.setHashingLimit(4);
|
||||
assertEquals(1, throttledEvents);
|
||||
assertEquals(1, readFromBlob(blobHasher, 1));
|
||||
assertEquals(2, throttledEvents);
|
||||
assertEquals(4, blobHasher.getBytesProcessed());
|
||||
|
||||
// One more chunk should be processed.
|
||||
blobHasher.setHashingLimit(5);
|
||||
assertEquals(2, throttledEvents);
|
||||
assertEquals(1, readFromBlob(blobHasher, 1));
|
||||
assertEquals(3, throttledEvents);
|
||||
assertEquals(5, blobHasher.getBytesProcessed());
|
||||
|
||||
// Two more chunks should be processed.
|
||||
blobHasher.setHashingLimit(15);
|
||||
assertEquals(3, throttledEvents);
|
||||
assertEquals(2, readFromBlob(blobHasher, 2));
|
||||
assertEquals(4, throttledEvents);
|
||||
assertEquals(15, blobHasher.getBytesProcessed());
|
||||
|
||||
// The entire blob should be processed.
|
||||
blobHasher.setHashingLimit(Infinity);
|
||||
var expectedChunks = Math.ceil(blob.size / 5) - 3;
|
||||
assertEquals(expectedChunks, readFromBlob(blobHasher, expectedChunks));
|
||||
assertEquals(4, throttledEvents);
|
||||
assertEquals(1, completeEvents);
|
||||
assertEquals('9e107d9d372bb6826bd81d3542a419d6',
|
||||
goog.crypt.byteArrayToHex(blobHasher.getHash()));
|
||||
}
|
||||
|
||||
function testLengthZeroThrottling() {
|
||||
if (!window.Blob) {
|
||||
return;
|
||||
}
|
||||
|
||||
var hashFn = new goog.crypt.Md5();
|
||||
var blobHasher = new goog.crypt.BlobHasher(hashFn);
|
||||
var throttledEvents = 0;
|
||||
var completeEvents = 0;
|
||||
goog.events.listen(blobHasher, goog.crypt.BlobHasher.EventType.THROTTLED,
|
||||
function() { ++throttledEvents; });
|
||||
goog.events.listen(blobHasher, goog.crypt.BlobHasher.EventType.COMPLETE,
|
||||
function() { ++completeEvents; });
|
||||
|
||||
// Test throttling with length 0 blob.
|
||||
var blob = new BlobMock('');
|
||||
blobHasher.setHashingLimit(0);
|
||||
blobHasher.hash(blob);
|
||||
assertEquals(0, throttledEvents);
|
||||
assertEquals(1, completeEvents);
|
||||
assertEquals('d41d8cd98f00b204e9800998ecf8427e',
|
||||
goog.crypt.byteArrayToHex(blobHasher.getHash()));
|
||||
}
|
||||
|
||||
function testAbortsAndErrorsWhileThrottling() {
|
||||
if (!window.Blob) {
|
||||
return;
|
||||
}
|
||||
|
||||
var hashFn = new goog.crypt.Md5();
|
||||
var blobHasher = new goog.crypt.BlobHasher(hashFn, 5);
|
||||
var blob = new BlobMock('The quick brown fox jumps over the lazy dog');
|
||||
var abortEvents = 0;
|
||||
var errorEvents = 0;
|
||||
var throttledEvents = 0;
|
||||
var completeEvents = 0;
|
||||
goog.events.listen(blobHasher, goog.crypt.BlobHasher.EventType.ABORT,
|
||||
function() { ++abortEvents; });
|
||||
goog.events.listen(blobHasher, goog.crypt.BlobHasher.EventType.ERROR,
|
||||
function() { ++errorEvents; });
|
||||
goog.events.listen(blobHasher, goog.crypt.BlobHasher.EventType.THROTTLED,
|
||||
function() { ++throttledEvents; });
|
||||
goog.events.listen(blobHasher, goog.crypt.BlobHasher.EventType.COMPLETE,
|
||||
function() { ++completeEvents; });
|
||||
|
||||
// Test that processing cannot be continued after abort.
|
||||
blobHasher.setHashingLimit(0);
|
||||
blobHasher.hash(blob);
|
||||
assertEquals(1, throttledEvents);
|
||||
blobHasher.abort();
|
||||
assertEquals(1, abortEvents);
|
||||
blobHasher.setHashingLimit(10);
|
||||
assertNull(blobHasher.fileReader_);
|
||||
assertEquals(1, throttledEvents);
|
||||
assertEquals(0, completeEvents);
|
||||
assertNull(blobHasher.getHash());
|
||||
|
||||
// Test that processing cannot be continued after error.
|
||||
blobHasher.hash(blob);
|
||||
assertEquals(1, throttledEvents);
|
||||
blobHasher.fileReader_.mockError();
|
||||
assertEquals(1, errorEvents);
|
||||
blobHasher.setHashingLimit(100);
|
||||
assertNull(blobHasher.fileReader_);
|
||||
assertEquals(1, throttledEvents);
|
||||
assertEquals(0, completeEvents);
|
||||
assertNull(blobHasher.getHash());
|
||||
}
|
||||
52
vectortile/closure-library/closure/goog/crypt/blockcipher.js
Normal file
52
vectortile/closure-library/closure/goog/crypt/blockcipher.js
Normal file
@@ -0,0 +1,52 @@
|
||||
// Copyright 2012 The Closure Library Authors. All Rights Reserved.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS-IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
/**
|
||||
* @fileoverview Interface definition of a block cipher. A block cipher is a
|
||||
* pair of algorithms that implement encryption and decryption of input bytes.
|
||||
*
|
||||
* @see http://en.wikipedia.org/wiki/Block_cipher
|
||||
*
|
||||
* @author nnaze@google.com (Nathan Naze)
|
||||
*/
|
||||
|
||||
goog.provide('goog.crypt.BlockCipher');
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Interface definition for a block cipher.
|
||||
* @interface
|
||||
*/
|
||||
goog.crypt.BlockCipher = function() {};
|
||||
|
||||
|
||||
/**
|
||||
* Encrypt a plaintext block. The implementation may expect (and assert)
|
||||
* a particular block length.
|
||||
* @param {!Array<number>} input Plaintext array of input bytes.
|
||||
* @return {!Array<number>} Encrypted ciphertext array of bytes. Should be the
|
||||
* same length as input.
|
||||
*/
|
||||
goog.crypt.BlockCipher.prototype.encrypt;
|
||||
|
||||
|
||||
/**
|
||||
* Decrypt a plaintext block. The implementation may expect (and assert)
|
||||
* a particular block length.
|
||||
* @param {!Array<number>} input Ciphertext. Array of input bytes.
|
||||
* @return {!Array<number>} Decrypted plaintext array of bytes. Should be the
|
||||
* same length as input.
|
||||
*/
|
||||
goog.crypt.BlockCipher.prototype.decrypt;
|
||||
@@ -0,0 +1,25 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<!--
|
||||
Copyright 2014 The Closure Library Authors. All Rights Reserved.
|
||||
|
||||
Use of this source code is governed by the Apache License, Version 2.0.
|
||||
See the COPYING file for details.
|
||||
-->
|
||||
<head>
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<title>Closure Performance Tests - byteArrayToString</title>
|
||||
<link rel="stylesheet" type="text/css"
|
||||
href="../testing/performancetable.css"/>
|
||||
<script src="../base.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<h1>Closure Performance Tests - byteArrayToString</h1>
|
||||
<div id="perfTable"></div>
|
||||
<hr>
|
||||
<script>
|
||||
goog.require('goog.crypt.byteArrayToStringPerf');
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user