first commit

This commit is contained in:
s.golasch
2023-08-01 13:49:46 +02:00
commit 1fc239fd54
20238 changed files with 3112246 additions and 0 deletions

19
build/node_modules/vulcanize/.editorconfig generated vendored Normal file
View File

@@ -0,0 +1,19 @@
# Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
# This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
# The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
# The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
# Code distributed by Google as part of the polymer project is also
# subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
# Polymer EditorConfig
root = true
[*]
charset = utf-8
indent_size = 2
indent_style = space
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false

1
build/node_modules/vulcanize/.eslintignore generated vendored Normal file
View File

@@ -0,0 +1 @@
test/html/*

6
build/node_modules/vulcanize/.eslintrc.json generated vendored Normal file
View File

@@ -0,0 +1,6 @@
{
"extends": "eslint:recommended",
"env": {
"node": true
}
}

1
build/node_modules/vulcanize/.gitattributes generated vendored Normal file
View File

@@ -0,0 +1 @@
* text=auto

View File

@@ -0,0 +1,16 @@
<!--
Thanks for the PR!
If this change has a user visible change (including
bug fixes, new features, etc) please describe the change in
CHANGELOG.md.
If the change is an entirely package-internal reshuffling/refactoring
should the change not be described in the CHANGELOG.
Consider also updating the README.
More info: http://keepachangelog.com/en/0.3.0/
-->
- [ ] CHANGELOG.md has been updated

8
build/node_modules/vulcanize/.npmignore generated vendored Normal file
View File

@@ -0,0 +1,8 @@
node_modules
# npmignore
example
CHANGELOG.md
README.md
util
test

6
build/node_modules/vulcanize/.travis.yml generated vendored Normal file
View File

@@ -0,0 +1,6 @@
language: node_js
node_js:
- "4"
- "6"
- "node"
sudo: false

553
build/node_modules/vulcanize/CHANGELOG.md generated vendored Normal file
View File

@@ -0,0 +1,553 @@
# Change Log
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## Unreleased
## 1.16.0 - 2017-07-14
- Fix erroneously reverse-order inlining of style imports `<link rel="import" type="css">`.
- Added `--polymer2` flag that changes some of the rewriting behaviors to support the fact that Polymer 2.x honors the `assetpath` of `<dom-module>` when interpreting style urls:
- Disables rewriting urls in inlined html imports containing `<style>` tags inside `<dom-module>` containers.
- Include consideration of container `<dom-module>` `assetpath` property when rewriting urls inside inlined style imports.
## 1.15.5 - 2017-06-01
- Add --out-request-list to bin/vulcanize help message
## 1.15.4 - 2017-03-21
- `excludes` option now honors JavaScript asset references:
- Won't attempt to load the JS (which caused errors when local file not present.)
- Won't inline excluded JS files.
- Added --out-request-list option, which writes a list of request URLs required
to vulcanize <html file> to a given file on success.
## 1.15.3 - 2017-01-17
- Fix for how paths are rewritten in nested import scenarios where paths to same
directory were ignored instead of treated as "." for relative path.
## 1.15.2 - 2016-12-16
- Fix for how assetpath is set when in the same directory, where assetpath attribute
for components in same directly were incorrectly set to "/".
## 1.15.1 - 2016-12-16
- Amended README and minor text fixes to CHANGELOG post release.
## 1.15.0 - 2016-12-16
- Fixed: Preserve style ordering when moving imports and links out of head tag.
- Don't actually move anything out of head until an html import is encountered.
## 1.14.12 - 2016-11-16
- Removed update-notifier dependency and functionality
- Fixed: Stopped moving links with certain rels out of the head tag to avoid breaking
favicons, manifests, and other such features.
- Speed enhancements
## 1.14.11 - 2016-04-11
- Radically simpler inlining design. Move all imports and scripts into document
body, replace imports inline.
- Add tests for more complicated inlining scenarios
## 1.14.10 - 2016-04-07
- Must use path resolution when moving `<head>` nodes
## 1.14.9 - 2016-04-05
- Try harder to preserve script ordering, move nodes from `<head>` of current
document into import inlining fragment
## 1.14.8 - 2016-03-24
- Undo hydrolysis inlining scripts
## 1.14.7 - 2016-03-01
- Fix inlining for firebase and other scripts that use `\\x3c/script` syntax
when making more scripts
## 1.14.6 - 2016-02-23
- Make sure `@license` comments always are maintained
## 1.14.5 - 2016-01-21
- Fix dom5 dependency to 1.3+
## 1.14.4 - 2016-01-21
- Make sure `<link rel="import type="css">` inlining is placed into a
`<dom-module>`'s `<template>`
## 1.14.3 - 2016-01-19
- Fix for trailing slash in `<base>` tag
## 1.14.2 - 2016-01-19
- Fix paths when preserving execution order moves scripts to body
## 1.14.1 - 2016-01-14
- Escape inline scripts
- Strip Excludes fixed to have higher precedence than Excludes
- Fix script execution order with imports, once and for all!
## 1.14.0 - 2015-10-20
- Add `output` option to write file from CLI
## 1.13.1
- Strip Excludes should be fuzzy
## 1.13.0
- Support custom hydrolysis file loaders
## 1.12.3
- Make sure `excludes` works with `redirects`
## 1.12.2
- Fix CLI spelling of `redirects`
## 1.12.1
- Fix misspelling of `redirects` in library options
## 1.12.0
- New `--redirect` flag and `redirect` argument to set up custom path mappings
## 1.11.0
- New `-add-import` flag and `addedImports` argument to add additional imports
to the target file.
- Copy `@media` queries on external CSS files into inlined styles.
- Fix excluding css files from computing dependencies.
## 1.10.5
- Fix a dumb unix path assumption for --inline-scripts and --inline-css +
absolute paths on windows.
## 1.10.4
- Fix excludes for js files and folders
## 1.10.3
- Fix regression in --strip-comments from 1.9.0
## 1.10.2
- Use URLs internally until calling hydrolysis
- Fixes a bunch of inline issues for Windows
## 1.10.1
- Typecheck inputs in library usage
- Fix README to say that `stripExcludes` is an Array not a Boolean
## 1.10.0
- Add `inputUrl` option to work around grunt and gulp plugins providing
filepaths that cannot be used as URLs to `vulcanize.process()`
## 1.9.3
- Fix abspath bug on windows machines
## 1.9.2
- Use new class API in binary
- Update dependencies
## 1.9.1
- Fix `implicitStrip` in new Class based API
## 1.9.0
- New class based API:
```js
var Vulcanize = require('vulcanize');
var vulcan = new Vulcanize(options);
vulcan.process(...);
```
- `vulcanize.setOptions` and `vulcanize.process` are deprecated
## 1.8.1
- Bump hydrolysis to 1.12.0 with proper ordering
## 1.8.0
- Make stripComments work more reliably
## 1.7.1
- Don't try to inline styles from external sources
## 1.7.0
- Inline link[rel="stylesheet"] css as well as polymer import stylesheets
## 1.6.0
- Update usage of private API of hydrolysis
- Correctly set 'implicit strip' option when used programatically
## 1.5.1
- Ignore external (http and https) resources from inlining
## 1.5.0
- Error on the use of old Polymer elements. Vulcanize 0.7.x is the last version
that will handle &lt; Polymer 0.8.
- Rewrite urls for inlined styles
## 1.4.4
- Make sure excluded js files are totally removed (they inserted blank script
tags)
## 1.4.3
- Update dependencies and docs
- Dependency update fixes cyclic dependencies
## 1.4.2
- Fix URL rewriting from parts of imports that end up in `<body>`
## 1.4.1
- `--implicit-strip` is default
- Remove "comment normalization" when stripping, it was not self-stable
## 1.4.0
- Add `--strip-comments` to remove unnecessary comments
## 1.3.0
- Add `--inline-css` option to inline external stylesheets
## 1.2.1
- Update dependencies
## 1.2.0
- Change `--strip-exclude` to be an array of excludes to strip
- `--implicit-strip` is the old `--strip-excludes` behavior
## 1.1.0
- Add `--inline-scripts` option to inline external scripts
## 1.0.0
- Rewrite on top of [hydrolysis](https://github.com/PolymerLabs/hydrolysis) and
[dom5](https://github.com/PolymerLabs/dom5)
- Factor out `--csp` flag into [crisper](https://github.com/PolymerLabs/crisper)
- Remove html and javascript minification
## 0.7.10
- Collapse whitespace instead of removing it
- Keep unique license comments
## 0.7.9
- Honor `<base>` urls in inline styles
## 0.7.8
- Update to whacko 0.17.3
## 0.7.7
- Honor `<base>` tag
- Make all schemas "absolute" urls
## 0.7.6
- Don't rewrite urls starting with '#'
## 0.7.5
- Remove cssom, just use regexes
## 0.7.4
- Workaround for cssom not liking '{{ }}' bindings in `<style>` tags (unsupported, use `<core-style>` instead)
## 0.7.3
- Replace clean-css with cssom, which does less "optimizations"
## 0.7.2
- Disable css number rounding for crazy-sad flexbox hacks in IE 10
- Add charset=utf-8 to all scripts
- Better comment removal codepath
## 0.7.1
- Support for mobile URL Schemes "tel:" and "sms:"
- Better reporting of javascript error messages with `--strip`
- Handle buffers as input with `inputSrc`
- Rename `outputSrc` to `outputHandler`
## 0.7.0
- Upgrade to whacko 0.17.2 with template support
- add utils.searchAll to make a query that walks into `<template>` elements
## 0.6.2
- stick to whacko 0.17.1 until `<template>` support is complete
## 0.6.1
- fix bug with removing absolute imports
## 0.6.0
- Strip excluded imports by default (old behavior accessible with --no-strip-excludes flag)
## 0.5.0
- finally switch to new-world polymer license
- Add a bunch of tests for lib/vulcan
- Refactor test suites
- tests for utils and optparser modules
- Merge pull request #83 from jongeho1/undefined-element
- undefined element fix
- remove unnecessary require statement
- Handle indirect prototype references in Polymer invocation
- plumb abspath to all url rewriting
- shields!
- add travis config
- add tests!
- Add option for printing version and nag to update
- move test folder to example
- Merge branch 'master' of github.com:rush340/vulcanize into rush340-master
- Merge pull request #75 from ragingwind/remove-importerjs
- Merge pull request #77 from Polymer/use-whacko
- Keep consistent ordering of import document heads and bodies
- Don't create a whole document for inlining styles
- Switch to whacko/parse5
- fix flipped conditional
- Merge pull request #76 from ragingwind/buffer
- Support buffer in/out
- Remove importer.js
- more explicit checking of whether abspath is set
- cleaned up regex matching of root
- renamed webAbsPath to abspath
- fixed cheerio options to perform the same parsing while reading and writing
- if webAbsPath is passed in, use absolute paths everywhere
- resolve webAbsPath if relative path provided
- added recognition of double-slash paths as a remote absolute URL
- applied webAbsPath option for handling absolute paths (based on jongeho1's pull request: https://github.com/Polymer/vulcanize/pull/36)
## 0.4.3
- Release 0.4.3
- Mailto: is an absolute path
- Merge pull request #70 from rush340/htmlentities
- added missing use of CHEERIO_OPTIONS
- fixed cheerio options to perform the same parsing while reading and writing
- Merge pull request #59 from mozilla-appmaker/cheerio-write-fix
- Merge pull request #65 from tbuckley/patch-1
- Add quotes around filenames in CSS
- audit license headers
- fixed cheerio options to perform the same parsing while reading and writing
- Never decode entities
## 0.4.2
- Fix inline svgs
- Update README with --strip functionality
## 0.4.1
- Bump version to 0.4.1
- Strip comments and whitespace from all nodes
## 0.4.0
- Bump to version 0.4.0
- Replace noscript with explicit Polymer invocation, to ensure correct element registration order when CSP'ed.
## 0.3.1
- remove extraneous async module
- Fixes #34
## 0.3.0
- Hide import content from view in the main document
## 0.2.7
- always add name to polymer invocation
## 0.2.6
- bump version
- add small usage block to help
- Make --strip work with --csp
- Clean up use of get/setTextContent
- Inline stylesheet happens after import path fixup, so outputPath of rewriteURL should be the overall outputPath
## 0.2.5
- update to 0.2.5
- .text() was decoding HTML entities, read raw script node content for CSP
- Support Polymer invocation without tag name
- Fix slightly broken merge conflict
- Enable `--inline --csp` mode to smash everything into one JS file
- Upstream cheerio changed loop semantics to return "dom" nodes instead of sugared cheerio objects
- Fix #29
- Print help dialog if called without arguments
- update dependencies
## 0.2.4
- Treat config file as "defaults", commandline flags override
- Do path resolution before import processing and style inlining
## 0.2.3
- A few bug fixes
## 0.2.2
- Don't recalculate assetpath for handled elements
- Bump to 0.2.1
## 0.2.1
- unbreak assetpath generation
## 0.2.0
- Prepare vulcanize 0.2.0
- Merge pull request #25 from lborgav/patch-1
- Fixing missing letters
- Don't move external scripts around with CSP mode
- Use uglify inline_script
- Use cleancss only for stripping comments
- Merge pull request #21 from azakus/modular
- went a little too quick with the regex
- Remove byte order mark
- Make sure not to lose assetpath fix
- First draft at a split out Importer
- Inplace inline *all* imports
- Copy setTextNode since it's so tiny
- move all the option validation into optparser
- Update npm dependencies
- Split out path resolution
- Break out option parser
- Break out constants
- Add the hooks for style and script excludes
- Add changelog generation script
- Merge pull request #16 from tbuckley/master
- Include excluded script instead of its contents
- Only put a trailing slash into assetpath attribute if there is a path
- bump version
- clone all styles (minus href and rel) from `<link>` to `<style>`
- update to 0.1.13
- Skip non-JS scripts and non-CSS styles
- bump version
- Make sure to CSPify main document first, load platform.js first in the output js file.
- add test config for excluding polymer.html
- Refactor handling of inlined and excluded import insertion
- bump version
- Fix subtle path bug in stylesheets
- use uglify and clean-css to strip comments from js and css when using --strip
- Clean up
- bump version
- --csp will now operate on the input html file as well
- Fix script inlining to ignore parsing html comments
- cheerio 0.13 seems to work just fine
- inline stylesheets in the main page when using --inline
- README: add ga beacon
## 0.1.9
- Reset excludes on each run
## 0.1.8
- Bump version
- add "strip comments" functionality
- fix minor typo in helep text: s/defualts/defaults
## 0.1.7
- bump version
- add sub-import test to the top level import
- Add --config option to specify user defined excludes
- Add user-defined excludes from inling.
## 0.1.6
- bump version
- test with absolute urls
- remove console.log
- Deduplicate absolute url imports
- fix missing absolute imports
## 0.1.5
- bump to 0.1.5
- Revert "polymer-scope is no longer supported"
## 0.1.4
- reset shared buffers on each handleMainDocument call
## 0.1.3
- bump version
- move option checking to setOptions, not the bin
- Add npm installation instructions
- polymer-scope is no longer supported
## 0.1.2
## 0.1.15
- Only put a trailing slash into assetpath attribute if there is a path
## 0.1.14
- bump version
- clone all styles (minus href and rel) from `<link>` to `<style>`
## 0.1.13
- update to 0.1.13
- Skip non-JS scripts and non-CSS styles
## 0.1.12
- bump version
- Make sure to CSPify main document first, load platform.js first in the output js file.
- add test config for excluding polymer.html
- Refactor handling of inlined and excluded import insertion
## 0.1.11
- bump version
- Fix subtle path bug in stylesheets
- use uglify and clean-css to strip comments from js and css when using --strip
- Clean up
## 0.1.10
- bump version
- --csp will now operate on the input html file as well
- Fix script inlining to ignore parsing html comments
- cheerio 0.13 seems to work just fine
- inline stylesheets in the main page when using --inline
- README: add ga beacon
- Reset excludes on each run
- Bump version
- add "strip comments" functionality
- fix minor typo in helep text: s/defualts/defaults
- bump version
- add sub-import test to the top level import
- Add --config option to specify user defined excludes
- Add user-defined excludes from inling.
- bump version
- test with absolute urls
- remove console.log
- Deduplicate absolute url imports
- fix missing absolute imports
- bump to 0.1.5
- Revert "polymer-scope is no longer supported"
- reset shared buffers on each handleMainDocument call
- bump version
- move option checking to setOptions, not the bin
- Add npm installation instructions
- polymer-scope is no longer supported
- bump version
- update README to be more approachable
- add a help dialog, fix "main" in package.json
## 0.1.1
- Bump version to 0.1.1
- Fix paths from main html file if input or output directories are not current working directory
- Add style url rewriting back
- add other directories to testing
- Merge pull request #3 from akhileshgupta/inline_styles_fix
- Merge pull request #2 from akhileshgupta/concat_scripts_bugfix
- variable rename and removing the unrequired check
- fixing the use of .html(cssText) to update the styles content.
- resolving script path from outputDir during concatenation
- Merge pull request #1 from addyosmani/patch-1
- Adds npm install snippet, minor formatting changes.
## 0.1.0
- semver recommends starting at 0.1.0
- add repo info to package.json
## 0.0.1
- Update README.md
- add license top
- remove unrelated viz file
- add license files
- reference new executable path
- reference bin/vulcanize for global npm install
- split vulcan.js into vulcanize bin and lib/vulcan.js
- reorder constant variables, add missing SCRIPT_SRC
- inlineScripts now uses html text and regex, not cheerio api
- Use html() to inline scripts, text() makes HTML Entities
- Add --inline option to inline all scripts into main document (opposite of --csp)
- Update README to reflect all-in-one html files
- Try to insert inlined import exactly where the link was
- make everything from imports inlined
- update README with index-vulcanized output
- Inlined stylesheets must have URL paths rewritten, move to import processing
- inline css stylesheets into style tags in polymer elements
- assetpath is handled by polymer now
- Update README.md
- Update README.md
- Remove unused function
- fix import location finding and windows path munging
- Fix output directory for CSP js file
- find better spots for vulcanized imports and scripts
- Update to newer cheerio with fixed htmlparser
- reflect new functionality in README, fix up newline issues, refactor constants
- vulcanizer will now take in a single main document and produce a built version of that main document.
- add a semicolon to all scripts to prevent weird insertion conditions
- update README for CSP mode
- For CSP, allow an option to separate scripts into a separate file
- Process imports as whole files, no element extraction
- breaking down doc tool for analysis
- Update README for polymer-element
- update for polymer-element
- Much more useful README
- use assetpath attribute on `<element>` to fix resolvePath usage in Polymer elements

27
build/node_modules/vulcanize/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,27 @@
// Copyright (c) 2014 The Polymer Authors. All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

172
build/node_modules/vulcanize/README.md generated vendored Normal file
View File

@@ -0,0 +1,172 @@
[![NPM version](http://img.shields.io/npm/v/vulcanize.svg)](https://npmjs.org/package/vulcanize)
[![Build Status](http://img.shields.io/travis/Polymer/vulcanize.svg)](https://travis-ci.org/Polymer/vulcanize)
# Vulcanize
### Reduce an HTML file and its dependent HTML Imports into one file
>Named for the [Vulcanization](http://en.wikipedia.org/wiki/Vulcanization) process that turns polymers into more durable
materials.
Web pages that use multiple [HTML Imports](http://www.html5rocks.com/en/tutorials/webcomponents/imports/) to load dependencies may end up making lots of network round-trips. In many cases, this can lead to long initial load times and unnecessary bandwidth usage. The Vulcanize tool follows HTML Imports and `<script>` tags to inline these external assets into a single page, to be used in production.
In the future, technologies such as [HTTP/2](http://en.wikipedia.org/wiki/HTTP/2) and [Server Push](https://http2.github.io/faq/#whats-the-benefit-of-server-push) will likely obsolete the need for a tool like vulcanize for production uses.
## Installation
`vulcanize` is available on npm. For maximium utility, `vulcanize` should be installed globally.
npm install -g vulcanize
This will install `vulcanize` to `/usr/local/bin/vulcanize` (you may need `sudo`
for this step).
## Options
- `-h`|`--help`: print this message
- `-v`|`--version`: print version number
- `-p <arg>`|`--abspath <arg>`: use <arg> as the "webserver root", make all adjusted urls absolute
- `--exclude <path>`: exclude a subpath from root. Use multiple times to exclude multiple paths. Tags (imports/scripts/etc) that reference an excluded path are left in-place, meaning the resources are not inlined. ex: `--exclude=elements/x-foo.html --exclude=elements/x-bar.html`
- `--strip-exclude`: Exclude a subpath and remove any links referencing it.
- `--inline-scripts`: Inline external scripts.
- `--inline-css`: Inline external stylesheets.
- `--add-import <path>`: Add this import to the target HTML before vulcanizing. Can be used multiple times.
- `--redirect <uri>|<path>`: Takes an argument in the form of URI|PATH where url is a URI composed of a protocol, hostname, and path and PATH is a local filesystem path to replace the matched URI part with. Multiple redirects may be specified; the earliest ones have the highest priority.
- `--strip-comments`: Strips all HTML comments not containing an @license from the document.
- `--no-implicit-strip`: *DANGEROUS*! Avoid stripping imports of the transitive dependencies of imports specified with `--exclude`. May result in duplicate javascript inlining.
- `--out-html <path>`: If specified, output will be written to <path> instead of stdout.
- `--out-request-list <path>`: Writes a list of request URLs required to vulcanize <html file> to <path> on success.
## Usage
The command
vulcanize target.html
will inline the HTML Imports of `target.html` and print the resulting HTML to
standard output.
The command
vulcanize target.html > build.html
will inline the HTML Imports of `target.html` and print the result to
`build.html`.
The command
vulcanize -p "path/to/target/" /target.html
will inline the HTML Imports of `target.html`, treat `path/to/target/` as the
webroot of target.html, and make all urls absolute to the provided webroot.
The command
vulcanize --exclude "path/to/target/subpath/" --exclude "path/to/target/subpath2/" target.html
will inline the HTML Imports of `target.html` that are not in the directory
`path/to/target/subpath` nor `path/to/target/subpath2`.
If the `--strip-exclude` flag is used, the HTML Import `<link>` tags that
point to resources in `path/totarget/subpath` and `path/to/target/subpath2/`
will also be removed.
The command
vulcanize --inline-scripts target.html
will inline scripts in `target.html` as well as HTML Imports. Exclude flags will apply to both Imports and Scripts.
The command
vulcanize --inline-css target.html
will inline Polymerized stylesheets, `<link rel="import" type="css">`
The command
vulcanize --strip-comments target.html
will remove HTML comments, except for those that begin with `@license`.
License comments will be deduplicated.
## Using vulcanize programmatically
Vulcanize as a library has two exported function.
`vulcanize` constructor takes an object of options similar to the command line
options.
- `abspath`: A folder to treat as "webroot".
- When specified, use an absolute path to `target`.
- `excludes`: An array of strings with regular expressions to exclude paths from being inlined.
- `stripExcludes`: Similar to `excludes`, but strips the imports from the output entirely.
- If `stripExcludes` is empty, it will be set the value of `excludes` by default.
- `inlineScripts`: Inline external scripts.
- `inlineCss`: Inline external stylesheets.
- `addedImports`: Additional HTML imports to inline, added to the end of the
target file
- `redirects`: An array of strings with the format `URI|PATH` where url is a URI composed of a protocol, hostname, and path and PATH is a local filesystem path to replace the matched URI part with. Multiple redirects may be specified; the earliest ones have the highest priority.
- `stripComments`: Remove non-license HTML comments.
- `inputUrl`: A URL string that will override the `target` argument to
`vulcanize.process()`.
By design, gulp and grunt plugins expect to work on the given file path.
`vulcanize` has its own file loader, and expects to be given URLs. In
instances where the filename cannot be used as a URL `inputUrl` will
override the filename.
- `loader`: A [hydrolysis](https://www.npmjs.com/package/hydrolysis) loader.
This loader is generated with the `target` argument to `vulcan.process` and
the `exclude` paths. A custom loader can be given if more advanced setups
are necesssary.
`vulcanize.process` takes a `target` path to `target.html` and a callback.
Example:
```js
var Vulcanize = require('vulcanize');
var hydrolysis = require('hydrolysis');
/* a Hydrolysis loader object (optional) */
var loader = new hydrolysis.loader(...)
var vulcan = new Vulcanize({
abspath: '',
excludes: [
'\\.css$'
],
stripExcludes: [
],
inlineScripts: false,
inlineCss: false,
addedImports: [
],
redirects: [
],
implicitStrip: true,
stripComments: false
// optional
loader: loader,
inputUrl: ''
});
vulcan.process(target, function(err, inlinedHtml) {
});
```
## Caveats
Because HTML Imports changes the order of execution scripts can have, Vulcanize
has to make a few compromises to achieve that same script execution order.
1. Contents of all HTML Import documents will be moved to `<body>`
1. Any scripts or styles, inline or linked, which occur after a `<link rel="import">` node in `<head>` will be moved to `<body>` after the contents of the HTML Import.
## What happened to [feature] from 0.X?
- `--csp` mode has been moved into [crisper](https://github.com/PolymerLabs/crisper)
- `--strip` mode was removed, use something like [html-minifier](https://github.com/kangax/html-minifier) or [minimize](https://github.com/Moveo/minimize)
- Use these at your own risk, they may not understand all of Polymer's uses of HTML or CSS (https://github.com/kangax/html-minifier/issues/377)
## What about build tools
- [grunt-vulcanize](https://www.npmjs.com/package/grunt-vulcanize)
- [gulp-vulcanize](https://www.npmjs.com/package/gulp-vulcanize)
- [broccoli-vulcanize](https://www.npmjs.com/package/broccoli-vulcanize)
[![Analytics](https://ga-beacon.appspot.com/UA-39334307-2/Polymer/vulcanize/README)](https://github.com/igrigorik/ga-beacon)

5
build/node_modules/vulcanize/bin/.eslintrc.json generated vendored Normal file
View File

@@ -0,0 +1,5 @@
{
"rules": {
"no-console": "off"
}
}

154
build/node_modules/vulcanize/bin/vulcanize generated vendored Executable file
View File

@@ -0,0 +1,154 @@
#!/usr/bin/env node
/**
* @license
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
// jshint node: true
'use strict';
var nopt = require('nopt');
var fs = require('fs');
var vulcan = require('../lib/vulcan');
var help = [
'vulcanize: Reduce an HTML file and its dependent HTML Imports into one file',
'',
'Usage:',
' vulcanize <html file>',
'',
'Options:',
' -h|--help: print this message',
' -v|--version: print version number',
' -p <arg>|--abspath <arg>: use <arg> as the "webserver root", make all adjusted urls absolute',
' --inline-scripts: Inline external scripts',
' --inline-css: Inline external stylesheets',
' --add-import <path>: Add this import to the target HTML before vulcanizing. Can be used multiple times.',
' --exclude <path>: exclude a subpath from root. Use multiple times to exclude multiple paths. Tags to excluded paths are kept.',
' --strip-exclude: Exclude a subpath and strip the link that includes it.',
' --strip-comments: Strips all HTML comments not containing an @license from the document',
' --redirect <uri>|<path>: Takes an argument in the form of URI|PATH where url is a URI composed of a protocol, hostname, and path and PATH is a local filesystem path to replace the matched URI part with. Multiple redirects may be specified; the earliest ones have the highest priority.',
' --no-implicit-strip: DANGEROUS! Avoid stripping imports of the transitive dependencies of imports specified with `--exclude`. May result in duplicate javascript inlining.',
' --out-html <path>: If specified, output will be written to <path> instead of stdout.',
' --out-request-list <path>: Writes a list of request URLs required to vulcanize <html file> to <path> on success.',
' --polymer2: Rewrites urls in accordance with Polymer 2.x expectations, which applies the assetpath property of <dom-module> tags to the url() values in their style elements at runtime. ',
'',
'Examples:',
' The command',
'',
' vulcanize target.html',
'',
' will inline the HTML Imports of `target.html` and print the resulting HTML to standard output.',
'',
' The command',
'',
' vulcanize target.html > build.html',
'',
' will inline the HTML Imports of `target.html` and print the result to build.html.',
'',
' The command',
'',
' vulcanize -p "path/to/target/" /target.html',
'',
' will inline the HTML Imports of `target.html`, treat `path/to/target/` as the webroot of target.html, and make all urls absolute to the provided webroot.',
'',
' The command',
'',
' vulcanize --exclude "path/to/target/subpath/" --exclude "path/to/target/subpath2/" target.html',
'',
' will inline the HTML Imports of `target.html` that are not in the directory `path/to/target/subpath` nor `path/to/target/subpath2`.',
'',
' If the `--strip-excludes` flag is used, the HTML Import `<link>` tags that point to resources in `path/totarget/subpath` and `path/to/target/subpath2/` will also be removed.',
'',
' The command',
'',
' vulcanize --inline-scripts target.html',
'',
' will inline scripts in `target.html` as well as HTML Imports. Exclude flags will apply to both Imports and Scripts.'
].join('\n');
var args = nopt(
{
help: Boolean,
version: Boolean,
abspath: String,
exclude: [String, Array],
polymer2: Boolean,
redirect: [String, Array],
'add-import': [String, Array],
'strip-exclude': [String, Array],
'strip-comments': Boolean,
'no-implicit-strip': Boolean,
'inline-scripts': Boolean,
'inline-css': Boolean,
'out-html': String,
'out-request-list': String
},
{
'h': ['--help'],
'v': ['--version'],
'p': ['--abspath']
}
);
var target = args.argv.remain[0];
function printHelp() {
console.log(help);
}
var pkg = require('../package.json');
function printVersion() {
console.log('vulcanize:', pkg.version);
}
if (args.version) {
printVersion();
process.exit(0);
}
if (args.help || !target) {
printHelp();
process.exit(0);
}
// escape a regex string and return a new RegExp
function stringToRegExp(str) {
return new RegExp(str.replace(/[-\/\\*+?.()|[\]{}]/g, '\\$&'));
}
args.addedImports = args['add-import'] || [];
args.excludes = args.exclude || [];
args.redirects = args.redirect || [];
args.stripExcludes = args['strip-exclude'] || [];
args.stripComments = args['strip-comments'];
args.implicitStrip = !args['no-implicit-strip'];
args.inlineScripts = args['inline-scripts'];
args.inlineCss = args['inline-css'];
args.polymer2 = args['polymer2'];
var vulcanize = new vulcan(args);
vulcanize.process(target, function(err, content) {
if (err) {
process.stderr.write(require('util').inspect(err));
process.exit(1);
}
if (args['out-request-list']) {
var urls = Object.keys(vulcanize.loader.requests).filter(function(url) {
return !vulcanize.isExcludedHref(url);
});
fs.writeFileSync(args['out-request-list'], urls.join('\n') + '\n');
}
if (args['out-html']) {
fs.writeFileSync(args['out-html'], content + '\n');
} else {
process.stdout.write(content);
}
});

26
build/node_modules/vulcanize/lib/comment-map.js generated vendored Normal file
View File

@@ -0,0 +1,26 @@
/**
* @license
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
function CommentMap() {
this.commentMap = Object.create(null);
}
CommentMap.prototype = {
get: function(comment) {
return this.commentMap[comment];
},
set: function(comment, value) {
this.commentMap[comment] = value;
},
keys: function() {
return Object.keys(this.commentMap);
}
};
module.exports = CommentMap;

18
build/node_modules/vulcanize/lib/constants.js generated vendored Normal file
View File

@@ -0,0 +1,18 @@
/**
* @license
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
module.exports = {
EXTERNAL_URL: /^(?:https?:)?\/\//,
ABS_URL: /(^\/)|(^#)|(^[\w-\d]*:)/,
URL: /url\([^)]*\)/g,
URL_ATTR: ['href', 'src', 'action', 'style', 'assetpath'],
URL_TEMPLATE: '{{.*}}|\\[\\[.*\\]\\]',
OLD_POLYMER: 'This version of vulcanize is not compatible with Polymer < 0.8. Please use vulcanize 0.7.x.'
};

100
build/node_modules/vulcanize/lib/matchers.js generated vendored Normal file
View File

@@ -0,0 +1,100 @@
/**
* @license
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
// jshint node: true
'use strict';
var constants = require('./constants');
var dom5 = require('dom5');
var p = dom5.predicates;
var urlAttrMatchers = constants.URL_ATTR.map(function(attr) {
return p.hasAttr(attr);
});
var urlAttrs = p.OR.apply(null, urlAttrMatchers);
var jsMatcher = p.AND(
p.hasTagName('script'),
p.OR(
p.NOT(
p.hasAttr('type')
),
p.hasAttrValue('type', 'text/javascript'),
p.hasAttrValue('type', 'application/javascript')
)
);
var externalStyle = p.AND(
p.hasTagName('link'),
p.hasAttrValue('rel', 'stylesheet')
);
// polymer specific external stylesheet
var polymerExternalStyle = p.AND(
p.hasTagName('link'),
p.hasAttrValue('rel', 'import'),
p.hasAttrValue('type', 'css')
);
var htmlImport = p.AND(
p.hasTagName('link'),
p.hasAttrValue('rel', 'import'),
p.OR(
p.NOT(p.hasAttr('type')),
p.hasAttrValue('type', 'text/html')
)
);
var styleMatcher = p.AND(
p.hasTagName('style'),
p.OR(
p.NOT(
p.hasAttr('type')
),
p.hasAttrValue('type', 'text/css')
)
);
var targetMatcher = p.AND(
p.OR(
p.hasTagName('a'),
p.hasTagName('form')
),
p.NOT(p.hasAttr('target'))
);
module.exports = {
head: p.hasTagName('head'),
body: p.hasTagName('body'),
base: p.hasTagName('base'),
domModule: p.AND(
p.hasTagName('dom-module'),
p.hasAttr('id'),
p.NOT(
p.hasAttr('assetpath')
)
),
meta: p.AND(
p.hasTagName('meta'),
p.hasAttr('charset')
),
polymerElement: p.hasTagName('polymer-element'),
urlAttrs: urlAttrs,
targetMatcher: targetMatcher,
polymerExternalStyle: polymerExternalStyle,
htmlImport: htmlImport,
JS: jsMatcher,
CSS: styleMatcher,
CSS_LINK: externalStyle,
POLY_CSS_LINK: polymerExternalStyle,
ALL_CSS_LINK: p.OR(externalStyle, polymerExternalStyle),
JS_SRC: p.AND(p.hasAttr('src'), jsMatcher),
JS_INLINE: p.AND(p.NOT(p.hasAttr('src')), jsMatcher)
};

165
build/node_modules/vulcanize/lib/pathresolver.js generated vendored Normal file
View File

@@ -0,0 +1,165 @@
/**
* @license
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
// jshint node:true
'use strict';
var path = require('path');
// use path.posix on Node > 0.12+, path-posix on 0.10
var pathPosix = path.posix || require('path-posix');
var url = require('url');
var dom5 = require('dom5');
var matchers = require('./matchers');
var constants = require('./constants');
var PathResolver = function PathResolver(abspath) {
if (abspath) {
this.abspath = abspath;
}
};
PathResolver.prototype = {
isTemplatedUrl: function isTemplatedUrl(href) {
return href.search(constants.URL_TEMPLATE) >= 0;
},
resolvePaths: function resolvePaths(importDoc, importUrl, mainDocUrl, polymer2) {
// rewrite URLs in element attributes
var nodes = dom5.queryAll(importDoc, matchers.urlAttrs);
var attrValue;
for (var i = 0, node; i < nodes.length; i++) {
node = nodes[i];
for (var j = 0, attr; j < constants.URL_ATTR.length; j++) {
attr = constants.URL_ATTR[j];
attrValue = dom5.getAttribute(node, attr);
// When the path is an empty string value the intent is to represent
// in URL-speak "the same path that the current document is at".
// We'll set it to '.' which better represents this intent to the
// rewrite methods.
if (attrValue === '') {
attrValue = '.';
}
if (attrValue && !this.isTemplatedUrl(attrValue)) {
var relUrl;
if (attr === 'style') {
relUrl = this.rewriteURL(importUrl, mainDocUrl, attrValue);
} else {
relUrl = this.rewriteRelPath(importUrl, mainDocUrl, attrValue);
if (attr === 'assetpath' && relUrl.length > 0 && relUrl.slice(-1) !== '/') {
relUrl += '/';
}
}
dom5.setAttribute(node, attr, relUrl);
}
}
}
// rewrite URLs in stylesheets unless they're inside a <dom-module>
var styleNodes = polymer2 ?
dom5.queryAll(importDoc,
dom5.predicates.AND(
dom5.predicates.NOT(
dom5.predicates.parentMatches(
dom5.predicates.hasTagName('dom-module'))),
matchers.CSS)) :
dom5.queryAll(importDoc, matchers.CSS);
for (i = 0, node; i < styleNodes.length; i++) {
node = styleNodes[i];
var styleText = dom5.getTextContent(node);
styleText = this.rewriteURL(importUrl, mainDocUrl, styleText);
dom5.setTextContent(node, styleText);
}
// add assetpath to dom-modules in importDoc
var domModules = dom5.queryAll(importDoc, matchers.domModule);
for (i = 0, node; i < domModules.length; i++) {
node = domModules[i];
var assetPathUrl = this.rewriteRelPath(importUrl, mainDocUrl, '');
assetPathUrl = pathPosix.dirname(assetPathUrl) + '/';
dom5.setAttribute(node, 'assetpath', assetPathUrl);
}
},
isAbsoluteUrl: function isAbsoluteUrl(href) {
return constants.ABS_URL.test(href);
},
rewriteRelPath: function rewriteRelPath(importUrl, mainDocUrl, relUrl) {
if (this.isAbsoluteUrl(relUrl)) {
return relUrl;
}
var absUrl = url.resolve(importUrl, relUrl);
if (this.abspath) {
return url.resolve('/', absUrl);
}
var parsedFrom = url.parse(mainDocUrl);
var parsedTo = url.parse(absUrl);
if (parsedFrom.protocol === parsedTo.protocol && parsedFrom.host === parsedTo.host) {
var pathname = pathPosix.relative(pathPosix.dirname(parsedFrom.pathname), parsedTo.pathname);
return url.format({
pathname: pathname,
search: parsedTo.search,
hash: parsedTo.hash
});
}
return absUrl;
},
rewriteURL: function rewriteURL(importUrl, mainDocUrl, cssText) {
return cssText.replace(constants.URL, function(match) {
var path = match.replace(/["']/g, "").slice(4, -1);
path = this.rewriteRelPath(importUrl, mainDocUrl, path);
return 'url("' + path + '")';
}.bind(this));
},
// remove effects of <base>
acid: function acid(doc, docUrl, polymer2) {
var base = dom5.query(doc, matchers.base);
if (base) {
var baseUrl = dom5.getAttribute(base, 'href');
var baseTarget = dom5.getAttribute(base, 'target');
dom5.remove(base);
if (baseUrl) {
if (baseUrl.slice(-1) === '/') {
baseUrl = baseUrl.slice(0, -1);
}
var docBaseUrl = url.resolve(docUrl, baseUrl + '/.index.html');
this.resolvePaths(doc, docBaseUrl, docUrl, polymer2);
}
if (baseTarget) {
var elementsNeedTarget = dom5.queryAll(doc, matchers.targetMatcher);
elementsNeedTarget.forEach(function(el) {
dom5.setAttribute(el, 'target', baseTarget);
});
}
}
},
pathToUrl: function pathToUrl(filePath) {
var absolutePath = path.resolve(filePath);
if (process.platform === 'win32') {
// encode C:\foo\ as C:/foo/
return absolutePath.split('\\').join('/');
} else {
return absolutePath;
}
},
urlToPath: function urlToPath(uri) {
var parsed = url.parse(uri);
if (process.platform === 'win32') {
return parsed.protocol + parsed.pathname.split('/').join('\\');
} else {
return (parsed.protocol || '') + parsed.pathname;
}
}
};
module.exports = PathResolver;

565
build/node_modules/vulcanize/lib/vulcan.js generated vendored Normal file
View File

@@ -0,0 +1,565 @@
/**
* @license
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
// jshint node: true
'use strict';
var path = require('path');
var url = require('url');
var pathPosix = path.posix || require('path-posix');
var hyd = require('hydrolysis');
var dom5 = require('dom5');
var CommentMap = require('./comment-map');
var constants = require('./constants');
var matchers = require('./matchers');
var PathResolver = require('./pathresolver');
var encodeString = require('../third_party/UglifyJS2/output');
var Promise = global.Promise || require('es6-promise').Promise;
/**
* This is the copy of vulcanize we keep to simulate the setOptions api.
*
* TODO(garlicnation): deprecate and remove setOptions API in favor of constructor.
*/
var singleton;
function buildLoader(config) {
var abspath = config.abspath;
var excludes = config.excludes;
var fsResolver = config.fsResolver;
var redirects = config.redirects;
var loader = new hyd.Loader();
if (fsResolver) {
loader.addResolver(fsResolver);
} else {
var fsOptions = {};
if (abspath) {
fsOptions.root = path.resolve(abspath);
fsOptions.basePath = '/';
}
loader.addResolver(new hyd.FSResolver(fsOptions));
}
// build null HTTPS? resolver to skip external scripts
loader.addResolver(new hyd.NoopResolver(constants.EXTERNAL_URL));
var redirectOptions = {};
if (abspath) {
redirectOptions.root = path.resolve(abspath);
redirectOptions.basePath = '/';
}
var redirectConfigs = [];
for (var i = 0; i < redirects.length; i++) {
var split = redirects[i].split('|');
var uri = url.parse(split[0]);
var replacement = split[1];
if (!uri || !replacement) {
throw new Error("Invalid redirect config: " + redirects[i]);
}
var redirectConfig = new hyd.RedirectResolver.ProtocolRedirect({
protocol: uri.protocol,
hostname: uri.hostname,
path: uri.pathname,
redirectPath: replacement
});
redirectConfigs.push(redirectConfig);
}
if (redirectConfigs.length > 0) {
redirectOptions.redirects = redirectConfigs;
loader.addResolver(new hyd.RedirectResolver(redirectOptions));
}
if (excludes) {
excludes.forEach(function(r) {
loader.addResolver(new hyd.NoopResolver(r));
});
}
return loader;
}
function nextSibling(node) {
var parentNode = node.parentNode;
if (!parentNode) {
return null;
}
var idx = parentNode.childNodes.indexOf(node);
return parentNode.childNodes[idx + 1] || null;
}
var Vulcan = function Vulcan(opts) {
// implicitStrip should be true by default
this.implicitStrip = opts.implicitStrip === undefined ? true : Boolean(opts.implicitStrip);
this.abspath = (String(opts.abspath) === opts.abspath && String(opts.abspath).trim() !== '') ? path.resolve(opts.abspath) : null;
this.pathResolver = new PathResolver(this.abspath);
this.addedImports = Array.isArray(opts.addedImports) ? opts.addedImports : [];
this.excludes = Array.isArray(opts.excludes) ? opts.excludes : [];
this.stripExcludes = Array.isArray(opts.stripExcludes) ? opts.stripExcludes : [];
this.stripComments = Boolean(opts.stripComments);
this.enableCssInlining = Boolean(opts.inlineCss);
this.enableScriptInlining = Boolean(opts.inlineScripts);
this.inputUrl = String(opts.inputUrl) === opts.inputUrl ? opts.inputUrl : '';
this.fsResolver = opts.fsResolver;
this.redirects = Array.isArray(opts.redirects) ? opts.redirects : [];
this.polymer2 = opts.polymer2;
if (opts.loader) {
this.loader = opts.loader;
} else {
this.loader = buildLoader({
abspath: this.abspath,
fsResolver: this.fsResolver,
excludes: this.excludes,
redirects: this.redirects
});
}
};
Vulcan.prototype = {
isDuplicateImport: function isDuplicateImport(importMeta) {
return !importMeta.href;
},
reparent: function reparent(newParent) {
return function(node) {
node.parentNode = newParent;
};
},
isExcludedImport: function isExcludedImport(importMeta) {
return this.isExcludedHref(importMeta.href);
},
isExcludedHref: function isExcludedHref(href) {
if (constants.EXTERNAL_URL.test(href)) {
return true;
}
if (!this.excludes) {
return false;
}
return this.excludes.some(function(r) {
return href.search(r) >= 0;
});
},
isStrippedImport: function isStrippedImport(importMeta) {
if (!this.stripExcludes.length) {
return false;
}
var href = importMeta.href;
return this.stripExcludes.some(function(r) {
return href.search(r) >= 0;
});
},
isBlankTextNode: function isBlankTextNode(node) {
return node && dom5.isTextNode(node) && !/\S/.test(dom5.getTextContent(node));
},
hasOldPolymer: function hasOldPolymer(doc) {
return Boolean(dom5.query(doc, matchers.polymerElement));
},
removeElementAndNewline: function removeElementAndNewline(node, replacement) {
// when removing nodes, remove the newline after it as well
var parent = node.parentNode;
var nextIdx = parent.childNodes.indexOf(node) + 1;
var next = parent.childNodes[nextIdx];
// remove next node if it is blank text
if (this.isBlankTextNode(next)) {
dom5.remove(next);
}
if (replacement) {
dom5.replace(node, replacement);
} else {
dom5.remove(node);
}
},
isLicenseComment: function(node) {
if (dom5.isCommentNode(node)) {
return dom5.getTextContent(node).indexOf('@license') > -1;
}
return false;
},
moveToBodyMatcher: dom5.predicates.AND(
dom5.predicates.NOT(
dom5.predicates.parentMatches(
dom5.predicates.hasTagName('template'))),
dom5.predicates.OR(
dom5.predicates.hasTagName('script'),
dom5.predicates.hasTagName('link'),
matchers.CSS
),
dom5.predicates.NOT(
dom5.predicates.OR(
matchers.polymerExternalStyle,
dom5.predicates.hasAttrValue('rel', 'dns-prefetch'),
dom5.predicates.hasAttrValue('rel', 'icon'),
dom5.predicates.hasAttrValue('rel', 'manifest'),
dom5.predicates.hasAttrValue('rel', 'preconnect'),
dom5.predicates.hasAttrValue('rel', 'prefetch'),
dom5.predicates.hasAttrValue('rel', 'preload'),
dom5.predicates.hasAttrValue('rel', 'prerender')
)
)
),
ancestorWalk: function(node, target) {
while(node) {
if (node === target) {
return true;
}
node = node.parentNode;
}
return false;
},
isTemplated: function(node) {
while(node) {
if (dom5.isDocumentFragment(node)) {
return true;
}
node = node.parentNode;
}
return false;
},
isInsideTemplate: dom5.predicates.parentMatches(
dom5.predicates.hasTagName('template')),
flatten: function flatten(tree, mainDocUrl) {
var isMainDoc = (mainDocUrl === undefined);
if (isMainDoc) {
mainDocUrl = tree.href;
}
var doc = tree.html.ast;
var imports = tree.imports;
var head = dom5.query(doc, matchers.head);
var body = dom5.query(doc, matchers.body);
var importNodes = tree.html.import;
// early check for old polymer versions
if (this.hasOldPolymer(doc)) {
throw new Error(constants.OLD_POLYMER + ' File: ' + this.pathResolver.urlToPath(tree.href));
}
this.fixFakeExternalScripts(doc);
this.pathResolver.acid(doc, tree.href, this.polymer2);
var moveTarget;
if (isMainDoc) {
// hide bodies of imports from rendering in main document
moveTarget = dom5.constructors.element('div');
dom5.setAttribute(moveTarget, 'hidden', '');
dom5.setAttribute(moveTarget, 'by-vulcanize', '');
} else {
moveTarget = dom5.constructors.fragment();
}
var htmlImportEncountered = false;
// Once we encounter an html import, we need to move things into the body,
// because html imports contain things that can't be in document
// head.
dom5.queryAll(head, this.moveToBodyMatcher).forEach(function(n) {
if (!htmlImportEncountered && matchers.htmlImport(n)) {
htmlImportEncountered = true;
}
if (htmlImportEncountered) {
this.removeElementAndNewline(n);
dom5.append(moveTarget, n);
}
}, this);
this.prepend(body, moveTarget);
if (imports) {
for (var i = 0, im, thisImport; i < imports.length; i++) {
im = imports[i];
thisImport = importNodes[i];
if (this.isInsideTemplate(thisImport)) {
continue;
}
if (this.isDuplicateImport(im) || this.isStrippedImport(im)) {
this.removeElementAndNewline(thisImport);
continue;
}
if (this.isExcludedImport(im)) {
continue;
}
if (this.isTemplated(thisImport)) {
continue;
}
var bodyFragment = dom5.constructors.fragment();
var importDoc = this.flatten(im, mainDocUrl);
// rewrite urls
this.pathResolver.resolvePaths(importDoc, im.href, tree.href, this.polymer2);
var importHead = dom5.query(importDoc, matchers.head);
var importBody = dom5.query(importDoc, matchers.body);
// merge head and body tags for imports into main document
var importHeadChildren = importHead.childNodes;
var importBodyChildren = importBody.childNodes;
// make sure @license comments from import document make it into the import
var importHtml = importHead.parentNode;
var licenseComments = importDoc.childNodes.concat(importHtml.childNodes).filter(this.isLicenseComment);
// move children of <head> and <body> into importer's <body>
var reparentFn = this.reparent(bodyFragment);
importHeadChildren.forEach(reparentFn);
importBodyChildren.forEach(reparentFn);
bodyFragment.childNodes = bodyFragment.childNodes.concat(
licenseComments,
importHeadChildren,
importBodyChildren
);
// hide imports in main document, unless already hidden
if (isMainDoc && !this.ancestorWalk(thisImport, moveTarget)) {
this.hide(thisImport);
}
this.removeElementAndNewline(thisImport, bodyFragment);
}
}
// If hidden node is empty, remove it
if (isMainDoc && moveTarget.childNodes.length === 0) {
dom5.remove(moveTarget);
}
return doc;
},
hide: function(node) {
var hidden = dom5.constructors.element('div');
dom5.setAttribute(hidden, 'hidden', '');
dom5.setAttribute(hidden, 'by-vulcanize', '');
this.removeElementAndNewline(node, hidden);
dom5.append(hidden, node);
},
prepend: function prepend(parent, node) {
if (parent.childNodes.length) {
dom5.insertBefore(parent, parent.childNodes[0], node);
} else {
dom5.append(parent, node);
}
},
fixFakeExternalScripts: function fixFakeExternalScripts(doc) {
var scripts = dom5.queryAll(doc, matchers.JS_INLINE);
scripts.forEach(function(script) {
if (script.__hydrolysisInlined) {
dom5.setAttribute(script, 'src', script.__hydrolysisInlined);
dom5.setTextContent(script, '');
}
});
},
// inline scripts into document, returns a promise resolving to document.
inlineScripts: function inlineScripts(doc, href) {
var scripts = dom5.queryAll(doc, matchers.JS_SRC);
var scriptPromises = scripts.map(function(script) {
var src = dom5.getAttribute(script, 'src');
var uri = url.resolve(href, src);
// let the loader handle the requests
if (this.isExcludedHref(src)) {
return Promise.resolve(true);
}
return this.loader.request(uri).then(function(content) {
if (content) {
content = encodeString(content);
dom5.removeAttribute(script, 'src');
dom5.setTextContent(script, content);
}
});
}.bind(this));
// When all scripts are read, return the document
return Promise.all(scriptPromises).then(function(){ return {doc: doc, href: href}; });
},
// inline scripts into document, returns a promise resolving to document.
inlineCss: function inlineCss(doc, href) {
var lastPolymerExternalStyle = null;
var css_links = dom5.queryAll(doc, matchers.ALL_CSS_LINK);
var cssPromises = css_links.map(function(link) {
var tag = link;
var src = dom5.getAttribute(tag, 'href');
var media = dom5.getAttribute(tag, 'media');
var uri = url.resolve(href, src);
var isPolymerExternalStyle = matchers.polymerExternalStyle(tag);
var polymer2 = this.polymer2;
// let the loader handle the requests
if (this.isExcludedHref(src)) {
return Promise.resolve(true);
}
// let the loader handle the requests
return this.loader.request(uri).then(function(content) {
if (content) {
if (media) {
content = '@media ' + media + ' {' + content + '}';
}
var style = dom5.constructors.element('style');
if (isPolymerExternalStyle) {
// a polymer expternal style <link type="css" rel="import"> must be
// in a <dom-module> to be processed
var ownerDomModule = dom5.nodeWalkPrior(tag, dom5.predicates.hasTagName('dom-module'));
if (ownerDomModule) {
var domTemplate = dom5.query(ownerDomModule, dom5.predicates.hasTagName('template'));
if (polymer2) {
var assetpath = dom5.getAttribute(ownerDomModule, 'assetpath') || '';
content = this.pathResolver.rewriteURL(uri, url.resolve(href, assetpath), content);
} else {
content = this.pathResolver.rewriteURL(uri, href, content);
}
if (!domTemplate) {
// create a <template>, which has a fragment as childNodes[0]
domTemplate = dom5.constructors.element('template');
domTemplate.childNodes.push(dom5.constructors.fragment());
dom5.append(ownerDomModule, domTemplate);
}
dom5.remove(tag);
if (!lastPolymerExternalStyle) {
// put the style at the top of the dom-module's template
this.prepend(domTemplate.childNodes[0], style);
} else {
// put this style behind the last polymer external style
dom5.insertBefore(domTemplate.childNodes[0], nextSibling(lastPolymerExternalStyle), style);
}
lastPolymerExternalStyle = style;
}
} else {
content = this.pathResolver.rewriteURL(uri, href, content);
dom5.replace(tag, style);
}
dom5.setTextContent(style, '\n' + content + '\n');
}
}.bind(this));
}.bind(this));
// When all style imports are read, return the document
return Promise.all(cssPromises).then(function(){ return {doc: doc, href: href}; });
},
getImplicitExcludes: function getImplicitExcludes(excludes) {
// Build a loader that doesn't have to stop at our HTML excludes, since we
// need them. JS excludes should still be excluded.
var loader = buildLoader({
abspath: this.abspath,
fsResolver: this.fsResolver,
redirects: this.redirects,
excludes: excludes.filter(function(e) { return e.match(/.js$/i); })
});
var analyzer = new hyd.Analyzer(true, loader);
var analyzedExcludes = [];
excludes.forEach(function(exclude) {
if (exclude.match(/.js$/i)) {
return;
}
if (exclude.match(/.css$/i)) {
return;
}
if (exclude.slice(-1) === '/') {
return;
}
var depPromise = analyzer._getDependencies(exclude);
depPromise.catch(function(err) {
// include that this was an excluded url in the error message.
err.message += '. Could not read dependencies for excluded URL: ' + exclude;
});
analyzedExcludes.push(depPromise);
});
return Promise.all(analyzedExcludes).then(function(strippedExcludes) {
var dedupe = {};
strippedExcludes.forEach(function(excludeList){
excludeList.forEach(function(exclude) {
dedupe[exclude] = true;
});
});
return Object.keys(dedupe);
});
},
_process: function _process(target, cb) {
var chain = Promise.resolve(true);
if (this.implicitStrip && this.excludes) {
chain = this.getImplicitExcludes(this.excludes).then(function(implicitExcludes) {
implicitExcludes.forEach(function(strippedExclude) {
this.stripExcludes.push(strippedExclude);
}.bind(this));
}.bind(this));
}
var analyzer = new hyd.Analyzer(true, this.loader);
chain = chain.then(function(){
return analyzer.metadataTree(target);
}).then(function(tree) {
var flatDoc = this.flatten(tree);
// make sure there's a <meta charset> in the page to force UTF-8
var meta = dom5.query(flatDoc, matchers.meta);
var head = dom5.query(flatDoc, matchers.head);
for (var i = 0; i < this.addedImports.length; i++) {
var newImport = dom5.constructors.element('link');
dom5.setAttribute(newImport, 'rel', 'import');
dom5.setAttribute(newImport, 'href', this.addedImports[i]);
this.prepend(head, newImport);
}
if (!meta) {
meta = dom5.constructors.element('meta');
dom5.setAttribute(meta, 'charset', 'UTF-8');
this.prepend(head, meta);
}
return {doc: flatDoc, href: tree.href};
}.bind(this));
if (this.enableScriptInlining) {
chain = chain.then(function(docObj) {
return this.inlineScripts(docObj.doc, docObj.href);
}.bind(this));
}
if (this.enableCssInlining) {
chain = chain.then(function(docObj) {
return this.inlineCss(docObj.doc, docObj.href);
}.bind(this));
}
if (this.stripComments) {
chain = chain.then(function(docObj) {
var comments = new CommentMap();
var doc = docObj.doc;
var head = dom5.query(doc, matchers.head);
// remove all comments
dom5.nodeWalkAll(doc, dom5.isCommentNode).forEach(function(comment) {
comments.set(comment.data, comment);
dom5.remove(comment);
});
// Deduplicate license comments
comments.keys().forEach(function (commentData) {
if (commentData.indexOf("@license") == -1) {
return;
}
this.prepend(head, comments.get(commentData));
}, this);
return docObj;
}.bind(this));
}
chain.then(function(docObj) {
cb(null, dom5.serialize(docObj.doc));
}).catch(cb);
},
process: function process(target, cb) {
if (this.inputUrl) {
this._process(this.inputUrl, cb);
} else {
if (this.abspath) {
target = pathPosix.resolve('/', target);
} else {
target = this.pathResolver.pathToUrl(path.resolve(target));
}
this._process(target, cb);
}
}
};
Vulcan.process = function process(target, cb) {
singleton.process(target, cb);
};
Vulcan.setOptions = function setOptions(opts) {
singleton = new Vulcan(opts);
};
module.exports = Vulcan;

View File

@@ -0,0 +1,9 @@
# Master
# 2.0.0
* re-sync with RSVP. Many large performance improvements and bugfixes.
# 1.0.0
* first subset of RSVP

View File

@@ -0,0 +1,19 @@
Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@@ -0,0 +1,61 @@
# ES6-Promise (subset of [rsvp.js](https://github.com/tildeio/rsvp.js))
This is a polyfill of the [ES6 Promise](http://people.mozilla.org/~jorendorff/es6-draft.html#sec-promise-constructor). The implementation is a subset of [rsvp.js](https://github.com/tildeio/rsvp.js), if you're wanting extra features and more debugging options, check out the [full library](https://github.com/tildeio/rsvp.js).
For API details and how to use promises, see the <a href="http://www.html5rocks.com/en/tutorials/es6/promises/">JavaScript Promises HTML5Rocks article</a>.
## Downloads
* [es6-promise](https://raw.githubusercontent.com/jakearchibald/es6-promise/master/dist/es6-promise.js)
* [es6-promise-min](https://raw.githubusercontent.com/jakearchibald/es6-promise/master/dist/es6-promise.min.js)
## Node.js
To install:
```sh
npm install es6-promise
```
To use:
```js
var Promise = require('es6-promise').Promise;
```
## Usage in IE<9
`catch` is a reserved word in IE<9, meaning `promise.catch(func)` throws a syntax error. To work around this, you can use a string to access the property as shown in the following example.
However, please remember that such technique is already provided by most common minifiers, making the resulting code safe for old browsers and production:
```js
promise['catch'](function(err) {
// ...
});
```
Or use `.then` instead:
```js
promise.then(undefined, function(err) {
// ...
});
```
## Auto-polyfill
To polyfill the global environment (either in Node or in the browser via CommonJS) use the following code snippet:
```js
require('es6-promise').polyfill();
```
Notice that we don't assign the result of `polyfill()` to any variable. The `polyfill()` method will patch the global environment (in this case to the `Promise` name) when called.
## Building & Testing
* `npm run build` to build
* `npm test` to run tests
* `npm start` to run a build watcher, and webserver to test
* `npm run test:server` for a testem test runner and watching builder

View File

@@ -0,0 +1,972 @@
/*!
* @overview es6-promise - a tiny implementation of Promises/A+.
* @copyright Copyright (c) 2014 Yehuda Katz, Tom Dale, Stefan Penner and contributors (Conversion to ES6 API by Jake Archibald)
* @license Licensed under MIT license
* See https://raw.githubusercontent.com/jakearchibald/es6-promise/master/LICENSE
* @version 2.3.0
*/
(function() {
"use strict";
function lib$es6$promise$utils$$objectOrFunction(x) {
return typeof x === 'function' || (typeof x === 'object' && x !== null);
}
function lib$es6$promise$utils$$isFunction(x) {
return typeof x === 'function';
}
function lib$es6$promise$utils$$isMaybeThenable(x) {
return typeof x === 'object' && x !== null;
}
var lib$es6$promise$utils$$_isArray;
if (!Array.isArray) {
lib$es6$promise$utils$$_isArray = function (x) {
return Object.prototype.toString.call(x) === '[object Array]';
};
} else {
lib$es6$promise$utils$$_isArray = Array.isArray;
}
var lib$es6$promise$utils$$isArray = lib$es6$promise$utils$$_isArray;
var lib$es6$promise$asap$$len = 0;
var lib$es6$promise$asap$$toString = {}.toString;
var lib$es6$promise$asap$$vertxNext;
var lib$es6$promise$asap$$customSchedulerFn;
var lib$es6$promise$asap$$asap = function asap(callback, arg) {
lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len] = callback;
lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len + 1] = arg;
lib$es6$promise$asap$$len += 2;
if (lib$es6$promise$asap$$len === 2) {
// If len is 2, that means that we need to schedule an async flush.
// If additional callbacks are queued before the queue is flushed, they
// will be processed by this flush that we are scheduling.
if (lib$es6$promise$asap$$customSchedulerFn) {
lib$es6$promise$asap$$customSchedulerFn(lib$es6$promise$asap$$flush);
} else {
lib$es6$promise$asap$$scheduleFlush();
}
}
}
function lib$es6$promise$asap$$setScheduler(scheduleFn) {
lib$es6$promise$asap$$customSchedulerFn = scheduleFn;
}
function lib$es6$promise$asap$$setAsap(asapFn) {
lib$es6$promise$asap$$asap = asapFn;
}
var lib$es6$promise$asap$$browserWindow = (typeof window !== 'undefined') ? window : undefined;
var lib$es6$promise$asap$$browserGlobal = lib$es6$promise$asap$$browserWindow || {};
var lib$es6$promise$asap$$BrowserMutationObserver = lib$es6$promise$asap$$browserGlobal.MutationObserver || lib$es6$promise$asap$$browserGlobal.WebKitMutationObserver;
var lib$es6$promise$asap$$isNode = typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
// test for web worker but not in IE10
var lib$es6$promise$asap$$isWorker = typeof Uint8ClampedArray !== 'undefined' &&
typeof importScripts !== 'undefined' &&
typeof MessageChannel !== 'undefined';
// node
function lib$es6$promise$asap$$useNextTick() {
var nextTick = process.nextTick;
// node version 0.10.x displays a deprecation warning when nextTick is used recursively
// setImmediate should be used instead instead
var version = process.versions.node.match(/^(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)$/);
if (Array.isArray(version) && version[1] === '0' && version[2] === '10') {
nextTick = setImmediate;
}
return function() {
nextTick(lib$es6$promise$asap$$flush);
};
}
// vertx
function lib$es6$promise$asap$$useVertxTimer() {
return function() {
lib$es6$promise$asap$$vertxNext(lib$es6$promise$asap$$flush);
};
}
function lib$es6$promise$asap$$useMutationObserver() {
var iterations = 0;
var observer = new lib$es6$promise$asap$$BrowserMutationObserver(lib$es6$promise$asap$$flush);
var node = document.createTextNode('');
observer.observe(node, { characterData: true });
return function() {
node.data = (iterations = ++iterations % 2);
};
}
// web worker
function lib$es6$promise$asap$$useMessageChannel() {
var channel = new MessageChannel();
channel.port1.onmessage = lib$es6$promise$asap$$flush;
return function () {
channel.port2.postMessage(0);
};
}
function lib$es6$promise$asap$$useSetTimeout() {
return function() {
setTimeout(lib$es6$promise$asap$$flush, 1);
};
}
var lib$es6$promise$asap$$queue = new Array(1000);
function lib$es6$promise$asap$$flush() {
for (var i = 0; i < lib$es6$promise$asap$$len; i+=2) {
var callback = lib$es6$promise$asap$$queue[i];
var arg = lib$es6$promise$asap$$queue[i+1];
callback(arg);
lib$es6$promise$asap$$queue[i] = undefined;
lib$es6$promise$asap$$queue[i+1] = undefined;
}
lib$es6$promise$asap$$len = 0;
}
function lib$es6$promise$asap$$attemptVertex() {
try {
var r = require;
var vertx = r('vertx');
lib$es6$promise$asap$$vertxNext = vertx.runOnLoop || vertx.runOnContext;
return lib$es6$promise$asap$$useVertxTimer();
} catch(e) {
return lib$es6$promise$asap$$useSetTimeout();
}
}
var lib$es6$promise$asap$$scheduleFlush;
// Decide what async method to use to triggering processing of queued callbacks:
if (lib$es6$promise$asap$$isNode) {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useNextTick();
} else if (lib$es6$promise$asap$$BrowserMutationObserver) {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMutationObserver();
} else if (lib$es6$promise$asap$$isWorker) {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMessageChannel();
} else if (lib$es6$promise$asap$$browserWindow === undefined && typeof require === 'function') {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$attemptVertex();
} else {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useSetTimeout();
}
function lib$es6$promise$$internal$$noop() {}
var lib$es6$promise$$internal$$PENDING = void 0;
var lib$es6$promise$$internal$$FULFILLED = 1;
var lib$es6$promise$$internal$$REJECTED = 2;
var lib$es6$promise$$internal$$GET_THEN_ERROR = new lib$es6$promise$$internal$$ErrorObject();
function lib$es6$promise$$internal$$selfFullfillment() {
return new TypeError("You cannot resolve a promise with itself");
}
function lib$es6$promise$$internal$$cannotReturnOwn() {
return new TypeError('A promises callback cannot return that same promise.');
}
function lib$es6$promise$$internal$$getThen(promise) {
try {
return promise.then;
} catch(error) {
lib$es6$promise$$internal$$GET_THEN_ERROR.error = error;
return lib$es6$promise$$internal$$GET_THEN_ERROR;
}
}
function lib$es6$promise$$internal$$tryThen(then, value, fulfillmentHandler, rejectionHandler) {
try {
then.call(value, fulfillmentHandler, rejectionHandler);
} catch(e) {
return e;
}
}
function lib$es6$promise$$internal$$handleForeignThenable(promise, thenable, then) {
lib$es6$promise$asap$$asap(function(promise) {
var sealed = false;
var error = lib$es6$promise$$internal$$tryThen(then, thenable, function(value) {
if (sealed) { return; }
sealed = true;
if (thenable !== value) {
lib$es6$promise$$internal$$resolve(promise, value);
} else {
lib$es6$promise$$internal$$fulfill(promise, value);
}
}, function(reason) {
if (sealed) { return; }
sealed = true;
lib$es6$promise$$internal$$reject(promise, reason);
}, 'Settle: ' + (promise._label || ' unknown promise'));
if (!sealed && error) {
sealed = true;
lib$es6$promise$$internal$$reject(promise, error);
}
}, promise);
}
function lib$es6$promise$$internal$$handleOwnThenable(promise, thenable) {
if (thenable._state === lib$es6$promise$$internal$$FULFILLED) {
lib$es6$promise$$internal$$fulfill(promise, thenable._result);
} else if (thenable._state === lib$es6$promise$$internal$$REJECTED) {
lib$es6$promise$$internal$$reject(promise, thenable._result);
} else {
lib$es6$promise$$internal$$subscribe(thenable, undefined, function(value) {
lib$es6$promise$$internal$$resolve(promise, value);
}, function(reason) {
lib$es6$promise$$internal$$reject(promise, reason);
});
}
}
function lib$es6$promise$$internal$$handleMaybeThenable(promise, maybeThenable) {
if (maybeThenable.constructor === promise.constructor) {
lib$es6$promise$$internal$$handleOwnThenable(promise, maybeThenable);
} else {
var then = lib$es6$promise$$internal$$getThen(maybeThenable);
if (then === lib$es6$promise$$internal$$GET_THEN_ERROR) {
lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$GET_THEN_ERROR.error);
} else if (then === undefined) {
lib$es6$promise$$internal$$fulfill(promise, maybeThenable);
} else if (lib$es6$promise$utils$$isFunction(then)) {
lib$es6$promise$$internal$$handleForeignThenable(promise, maybeThenable, then);
} else {
lib$es6$promise$$internal$$fulfill(promise, maybeThenable);
}
}
}
function lib$es6$promise$$internal$$resolve(promise, value) {
if (promise === value) {
lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$selfFullfillment());
} else if (lib$es6$promise$utils$$objectOrFunction(value)) {
lib$es6$promise$$internal$$handleMaybeThenable(promise, value);
} else {
lib$es6$promise$$internal$$fulfill(promise, value);
}
}
function lib$es6$promise$$internal$$publishRejection(promise) {
if (promise._onerror) {
promise._onerror(promise._result);
}
lib$es6$promise$$internal$$publish(promise);
}
function lib$es6$promise$$internal$$fulfill(promise, value) {
if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }
promise._result = value;
promise._state = lib$es6$promise$$internal$$FULFILLED;
if (promise._subscribers.length !== 0) {
lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, promise);
}
}
function lib$es6$promise$$internal$$reject(promise, reason) {
if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }
promise._state = lib$es6$promise$$internal$$REJECTED;
promise._result = reason;
lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publishRejection, promise);
}
function lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection) {
var subscribers = parent._subscribers;
var length = subscribers.length;
parent._onerror = null;
subscribers[length] = child;
subscribers[length + lib$es6$promise$$internal$$FULFILLED] = onFulfillment;
subscribers[length + lib$es6$promise$$internal$$REJECTED] = onRejection;
if (length === 0 && parent._state) {
lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, parent);
}
}
function lib$es6$promise$$internal$$publish(promise) {
var subscribers = promise._subscribers;
var settled = promise._state;
if (subscribers.length === 0) { return; }
var child, callback, detail = promise._result;
for (var i = 0; i < subscribers.length; i += 3) {
child = subscribers[i];
callback = subscribers[i + settled];
if (child) {
lib$es6$promise$$internal$$invokeCallback(settled, child, callback, detail);
} else {
callback(detail);
}
}
promise._subscribers.length = 0;
}
function lib$es6$promise$$internal$$ErrorObject() {
this.error = null;
}
var lib$es6$promise$$internal$$TRY_CATCH_ERROR = new lib$es6$promise$$internal$$ErrorObject();
function lib$es6$promise$$internal$$tryCatch(callback, detail) {
try {
return callback(detail);
} catch(e) {
lib$es6$promise$$internal$$TRY_CATCH_ERROR.error = e;
return lib$es6$promise$$internal$$TRY_CATCH_ERROR;
}
}
function lib$es6$promise$$internal$$invokeCallback(settled, promise, callback, detail) {
var hasCallback = lib$es6$promise$utils$$isFunction(callback),
value, error, succeeded, failed;
if (hasCallback) {
value = lib$es6$promise$$internal$$tryCatch(callback, detail);
if (value === lib$es6$promise$$internal$$TRY_CATCH_ERROR) {
failed = true;
error = value.error;
value = null;
} else {
succeeded = true;
}
if (promise === value) {
lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$cannotReturnOwn());
return;
}
} else {
value = detail;
succeeded = true;
}
if (promise._state !== lib$es6$promise$$internal$$PENDING) {
// noop
} else if (hasCallback && succeeded) {
lib$es6$promise$$internal$$resolve(promise, value);
} else if (failed) {
lib$es6$promise$$internal$$reject(promise, error);
} else if (settled === lib$es6$promise$$internal$$FULFILLED) {
lib$es6$promise$$internal$$fulfill(promise, value);
} else if (settled === lib$es6$promise$$internal$$REJECTED) {
lib$es6$promise$$internal$$reject(promise, value);
}
}
function lib$es6$promise$$internal$$initializePromise(promise, resolver) {
try {
resolver(function resolvePromise(value){
lib$es6$promise$$internal$$resolve(promise, value);
}, function rejectPromise(reason) {
lib$es6$promise$$internal$$reject(promise, reason);
});
} catch(e) {
lib$es6$promise$$internal$$reject(promise, e);
}
}
function lib$es6$promise$enumerator$$Enumerator(Constructor, input) {
var enumerator = this;
enumerator._instanceConstructor = Constructor;
enumerator.promise = new Constructor(lib$es6$promise$$internal$$noop);
if (enumerator._validateInput(input)) {
enumerator._input = input;
enumerator.length = input.length;
enumerator._remaining = input.length;
enumerator._init();
if (enumerator.length === 0) {
lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result);
} else {
enumerator.length = enumerator.length || 0;
enumerator._enumerate();
if (enumerator._remaining === 0) {
lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result);
}
}
} else {
lib$es6$promise$$internal$$reject(enumerator.promise, enumerator._validationError());
}
}
lib$es6$promise$enumerator$$Enumerator.prototype._validateInput = function(input) {
return lib$es6$promise$utils$$isArray(input);
};
lib$es6$promise$enumerator$$Enumerator.prototype._validationError = function() {
return new Error('Array Methods must be provided an Array');
};
lib$es6$promise$enumerator$$Enumerator.prototype._init = function() {
this._result = new Array(this.length);
};
var lib$es6$promise$enumerator$$default = lib$es6$promise$enumerator$$Enumerator;
lib$es6$promise$enumerator$$Enumerator.prototype._enumerate = function() {
var enumerator = this;
var length = enumerator.length;
var promise = enumerator.promise;
var input = enumerator._input;
for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {
enumerator._eachEntry(input[i], i);
}
};
lib$es6$promise$enumerator$$Enumerator.prototype._eachEntry = function(entry, i) {
var enumerator = this;
var c = enumerator._instanceConstructor;
if (lib$es6$promise$utils$$isMaybeThenable(entry)) {
if (entry.constructor === c && entry._state !== lib$es6$promise$$internal$$PENDING) {
entry._onerror = null;
enumerator._settledAt(entry._state, i, entry._result);
} else {
enumerator._willSettleAt(c.resolve(entry), i);
}
} else {
enumerator._remaining--;
enumerator._result[i] = entry;
}
};
lib$es6$promise$enumerator$$Enumerator.prototype._settledAt = function(state, i, value) {
var enumerator = this;
var promise = enumerator.promise;
if (promise._state === lib$es6$promise$$internal$$PENDING) {
enumerator._remaining--;
if (state === lib$es6$promise$$internal$$REJECTED) {
lib$es6$promise$$internal$$reject(promise, value);
} else {
enumerator._result[i] = value;
}
}
if (enumerator._remaining === 0) {
lib$es6$promise$$internal$$fulfill(promise, enumerator._result);
}
};
lib$es6$promise$enumerator$$Enumerator.prototype._willSettleAt = function(promise, i) {
var enumerator = this;
lib$es6$promise$$internal$$subscribe(promise, undefined, function(value) {
enumerator._settledAt(lib$es6$promise$$internal$$FULFILLED, i, value);
}, function(reason) {
enumerator._settledAt(lib$es6$promise$$internal$$REJECTED, i, reason);
});
};
function lib$es6$promise$promise$all$$all(entries) {
return new lib$es6$promise$enumerator$$default(this, entries).promise;
}
var lib$es6$promise$promise$all$$default = lib$es6$promise$promise$all$$all;
function lib$es6$promise$promise$race$$race(entries) {
/*jshint validthis:true */
var Constructor = this;
var promise = new Constructor(lib$es6$promise$$internal$$noop);
if (!lib$es6$promise$utils$$isArray(entries)) {
lib$es6$promise$$internal$$reject(promise, new TypeError('You must pass an array to race.'));
return promise;
}
var length = entries.length;
function onFulfillment(value) {
lib$es6$promise$$internal$$resolve(promise, value);
}
function onRejection(reason) {
lib$es6$promise$$internal$$reject(promise, reason);
}
for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {
lib$es6$promise$$internal$$subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);
}
return promise;
}
var lib$es6$promise$promise$race$$default = lib$es6$promise$promise$race$$race;
function lib$es6$promise$promise$resolve$$resolve(object) {
/*jshint validthis:true */
var Constructor = this;
if (object && typeof object === 'object' && object.constructor === Constructor) {
return object;
}
var promise = new Constructor(lib$es6$promise$$internal$$noop);
lib$es6$promise$$internal$$resolve(promise, object);
return promise;
}
var lib$es6$promise$promise$resolve$$default = lib$es6$promise$promise$resolve$$resolve;
function lib$es6$promise$promise$reject$$reject(reason) {
/*jshint validthis:true */
var Constructor = this;
var promise = new Constructor(lib$es6$promise$$internal$$noop);
lib$es6$promise$$internal$$reject(promise, reason);
return promise;
}
var lib$es6$promise$promise$reject$$default = lib$es6$promise$promise$reject$$reject;
var lib$es6$promise$promise$$counter = 0;
function lib$es6$promise$promise$$needsResolver() {
throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
}
function lib$es6$promise$promise$$needsNew() {
throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
}
var lib$es6$promise$promise$$default = lib$es6$promise$promise$$Promise;
/**
Promise objects represent the eventual result of an asynchronous operation. The
primary way of interacting with a promise is through its `then` method, which
registers callbacks to receive either a promise's eventual value or the reason
why the promise cannot be fulfilled.
Terminology
-----------
- `promise` is an object or function with a `then` method whose behavior conforms to this specification.
- `thenable` is an object or function that defines a `then` method.
- `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
- `exception` is a value that is thrown using the throw statement.
- `reason` is a value that indicates why a promise was rejected.
- `settled` the final resting state of a promise, fulfilled or rejected.
A promise can be in one of three states: pending, fulfilled, or rejected.
Promises that are fulfilled have a fulfillment value and are in the fulfilled
state. Promises that are rejected have a rejection reason and are in the
rejected state. A fulfillment value is never a thenable.
Promises can also be said to *resolve* a value. If this value is also a
promise, then the original promise's settled state will match the value's
settled state. So a promise that *resolves* a promise that rejects will
itself reject, and a promise that *resolves* a promise that fulfills will
itself fulfill.
Basic Usage:
------------
```js
var promise = new Promise(function(resolve, reject) {
// on success
resolve(value);
// on failure
reject(reason);
});
promise.then(function(value) {
// on fulfillment
}, function(reason) {
// on rejection
});
```
Advanced Usage:
---------------
Promises shine when abstracting away asynchronous interactions such as
`XMLHttpRequest`s.
```js
function getJSON(url) {
return new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = handler;
xhr.responseType = 'json';
xhr.setRequestHeader('Accept', 'application/json');
xhr.send();
function handler() {
if (this.readyState === this.DONE) {
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
}
}
};
});
}
getJSON('/posts.json').then(function(json) {
// on fulfillment
}, function(reason) {
// on rejection
});
```
Unlike callbacks, promises are great composable primitives.
```js
Promise.all([
getJSON('/posts'),
getJSON('/comments')
]).then(function(values){
values[0] // => postsJSON
values[1] // => commentsJSON
return values;
});
```
@class Promise
@param {function} resolver
Useful for tooling.
@constructor
*/
function lib$es6$promise$promise$$Promise(resolver) {
this._id = lib$es6$promise$promise$$counter++;
this._state = undefined;
this._result = undefined;
this._subscribers = [];
if (lib$es6$promise$$internal$$noop !== resolver) {
if (!lib$es6$promise$utils$$isFunction(resolver)) {
lib$es6$promise$promise$$needsResolver();
}
if (!(this instanceof lib$es6$promise$promise$$Promise)) {
lib$es6$promise$promise$$needsNew();
}
lib$es6$promise$$internal$$initializePromise(this, resolver);
}
}
lib$es6$promise$promise$$Promise.all = lib$es6$promise$promise$all$$default;
lib$es6$promise$promise$$Promise.race = lib$es6$promise$promise$race$$default;
lib$es6$promise$promise$$Promise.resolve = lib$es6$promise$promise$resolve$$default;
lib$es6$promise$promise$$Promise.reject = lib$es6$promise$promise$reject$$default;
lib$es6$promise$promise$$Promise._setScheduler = lib$es6$promise$asap$$setScheduler;
lib$es6$promise$promise$$Promise._setAsap = lib$es6$promise$asap$$setAsap;
lib$es6$promise$promise$$Promise._asap = lib$es6$promise$asap$$asap;
lib$es6$promise$promise$$Promise.prototype = {
constructor: lib$es6$promise$promise$$Promise,
/**
The primary way of interacting with a promise is through its `then` method,
which registers callbacks to receive either a promise's eventual value or the
reason why the promise cannot be fulfilled.
```js
findUser().then(function(user){
// user is available
}, function(reason){
// user is unavailable, and you are given the reason why
});
```
Chaining
--------
The return value of `then` is itself a promise. This second, 'downstream'
promise is resolved with the return value of the first promise's fulfillment
or rejection handler, or rejected if the handler throws an exception.
```js
findUser().then(function (user) {
return user.name;
}, function (reason) {
return 'default name';
}).then(function (userName) {
// If `findUser` fulfilled, `userName` will be the user's name, otherwise it
// will be `'default name'`
});
findUser().then(function (user) {
throw new Error('Found user, but still unhappy');
}, function (reason) {
throw new Error('`findUser` rejected and we're unhappy');
}).then(function (value) {
// never reached
}, function (reason) {
// if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
// If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
});
```
If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
```js
findUser().then(function (user) {
throw new PedagogicalException('Upstream error');
}).then(function (value) {
// never reached
}).then(function (value) {
// never reached
}, function (reason) {
// The `PedgagocialException` is propagated all the way down to here
});
```
Assimilation
------------
Sometimes the value you want to propagate to a downstream promise can only be
retrieved asynchronously. This can be achieved by returning a promise in the
fulfillment or rejection handler. The downstream promise will then be pending
until the returned promise is settled. This is called *assimilation*.
```js
findUser().then(function (user) {
return findCommentsByAuthor(user);
}).then(function (comments) {
// The user's comments are now available
});
```
If the assimliated promise rejects, then the downstream promise will also reject.
```js
findUser().then(function (user) {
return findCommentsByAuthor(user);
}).then(function (comments) {
// If `findCommentsByAuthor` fulfills, we'll have the value here
}, function (reason) {
// If `findCommentsByAuthor` rejects, we'll have the reason here
});
```
Simple Example
--------------
Synchronous Example
```javascript
var result;
try {
result = findResult();
// success
} catch(reason) {
// failure
}
```
Errback Example
```js
findResult(function(result, err){
if (err) {
// failure
} else {
// success
}
});
```
Promise Example;
```javascript
findResult().then(function(result){
// success
}, function(reason){
// failure
});
```
Advanced Example
--------------
Synchronous Example
```javascript
var author, books;
try {
author = findAuthor();
books = findBooksByAuthor(author);
// success
} catch(reason) {
// failure
}
```
Errback Example
```js
function foundBooks(books) {
}
function failure(reason) {
}
findAuthor(function(author, err){
if (err) {
failure(err);
// failure
} else {
try {
findBoooksByAuthor(author, function(books, err) {
if (err) {
failure(err);
} else {
try {
foundBooks(books);
} catch(reason) {
failure(reason);
}
}
});
} catch(error) {
failure(err);
}
// success
}
});
```
Promise Example;
```javascript
findAuthor().
then(findBooksByAuthor).
then(function(books){
// found books
}).catch(function(reason){
// something went wrong
});
```
@method then
@param {Function} onFulfilled
@param {Function} onRejected
Useful for tooling.
@return {Promise}
*/
then: function(onFulfillment, onRejection) {
var parent = this;
var state = parent._state;
if (state === lib$es6$promise$$internal$$FULFILLED && !onFulfillment || state === lib$es6$promise$$internal$$REJECTED && !onRejection) {
return this;
}
var child = new this.constructor(lib$es6$promise$$internal$$noop);
var result = parent._result;
if (state) {
var callback = arguments[state - 1];
lib$es6$promise$asap$$asap(function(){
lib$es6$promise$$internal$$invokeCallback(state, child, callback, result);
});
} else {
lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection);
}
return child;
},
/**
`catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
as the catch block of a try/catch statement.
```js
function findAuthor(){
throw new Error('couldn't find that author');
}
// synchronous
try {
findAuthor();
} catch(reason) {
// something went wrong
}
// async with promises
findAuthor().catch(function(reason){
// something went wrong
});
```
@method catch
@param {Function} onRejection
Useful for tooling.
@return {Promise}
*/
'catch': function(onRejection) {
return this.then(null, onRejection);
}
};
function lib$es6$promise$polyfill$$polyfill() {
var local;
if (typeof global !== 'undefined') {
local = global;
} else if (typeof self !== 'undefined') {
local = self;
} else {
try {
local = Function('return this')();
} catch (e) {
throw new Error('polyfill failed because global object is unavailable in this environment');
}
}
var P = local.Promise;
if (P && Object.prototype.toString.call(P.resolve()) === '[object Promise]' && !P.cast) {
return;
}
local.Promise = lib$es6$promise$promise$$default;
}
var lib$es6$promise$polyfill$$default = lib$es6$promise$polyfill$$polyfill;
var lib$es6$promise$umd$$ES6Promise = {
'Promise': lib$es6$promise$promise$$default,
'polyfill': lib$es6$promise$polyfill$$default
};
/* global define:true module:true window: true */
if (typeof define === 'function' && define['amd']) {
define(function() { return lib$es6$promise$umd$$ES6Promise; });
} else if (typeof module !== 'undefined' && module['exports']) {
module['exports'] = lib$es6$promise$umd$$ES6Promise;
} else if (typeof this !== 'undefined') {
this['ES6Promise'] = lib$es6$promise$umd$$ES6Promise;
}
lib$es6$promise$polyfill$$default();
}).call(this);

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,965 @@
(function() {
"use strict";
function lib$es6$promise$utils$$objectOrFunction(x) {
return typeof x === 'function' || (typeof x === 'object' && x !== null);
}
function lib$es6$promise$utils$$isFunction(x) {
return typeof x === 'function';
}
function lib$es6$promise$utils$$isMaybeThenable(x) {
return typeof x === 'object' && x !== null;
}
var lib$es6$promise$utils$$_isArray;
if (!Array.isArray) {
lib$es6$promise$utils$$_isArray = function (x) {
return Object.prototype.toString.call(x) === '[object Array]';
};
} else {
lib$es6$promise$utils$$_isArray = Array.isArray;
}
var lib$es6$promise$utils$$isArray = lib$es6$promise$utils$$_isArray;
var lib$es6$promise$asap$$len = 0;
var lib$es6$promise$asap$$toString = {}.toString;
var lib$es6$promise$asap$$vertxNext;
var lib$es6$promise$asap$$customSchedulerFn;
var lib$es6$promise$asap$$asap = function asap(callback, arg) {
lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len] = callback;
lib$es6$promise$asap$$queue[lib$es6$promise$asap$$len + 1] = arg;
lib$es6$promise$asap$$len += 2;
if (lib$es6$promise$asap$$len === 2) {
// If len is 2, that means that we need to schedule an async flush.
// If additional callbacks are queued before the queue is flushed, they
// will be processed by this flush that we are scheduling.
if (lib$es6$promise$asap$$customSchedulerFn) {
lib$es6$promise$asap$$customSchedulerFn(lib$es6$promise$asap$$flush);
} else {
lib$es6$promise$asap$$scheduleFlush();
}
}
}
function lib$es6$promise$asap$$setScheduler(scheduleFn) {
lib$es6$promise$asap$$customSchedulerFn = scheduleFn;
}
function lib$es6$promise$asap$$setAsap(asapFn) {
lib$es6$promise$asap$$asap = asapFn;
}
var lib$es6$promise$asap$$browserWindow = (typeof window !== 'undefined') ? window : undefined;
var lib$es6$promise$asap$$browserGlobal = lib$es6$promise$asap$$browserWindow || {};
var lib$es6$promise$asap$$BrowserMutationObserver = lib$es6$promise$asap$$browserGlobal.MutationObserver || lib$es6$promise$asap$$browserGlobal.WebKitMutationObserver;
var lib$es6$promise$asap$$isNode = typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
// test for web worker but not in IE10
var lib$es6$promise$asap$$isWorker = typeof Uint8ClampedArray !== 'undefined' &&
typeof importScripts !== 'undefined' &&
typeof MessageChannel !== 'undefined';
// node
function lib$es6$promise$asap$$useNextTick() {
var nextTick = process.nextTick;
// node version 0.10.x displays a deprecation warning when nextTick is used recursively
// setImmediate should be used instead instead
var version = process.versions.node.match(/^(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)$/);
if (Array.isArray(version) && version[1] === '0' && version[2] === '10') {
nextTick = setImmediate;
}
return function() {
nextTick(lib$es6$promise$asap$$flush);
};
}
// vertx
function lib$es6$promise$asap$$useVertxTimer() {
return function() {
lib$es6$promise$asap$$vertxNext(lib$es6$promise$asap$$flush);
};
}
function lib$es6$promise$asap$$useMutationObserver() {
var iterations = 0;
var observer = new lib$es6$promise$asap$$BrowserMutationObserver(lib$es6$promise$asap$$flush);
var node = document.createTextNode('');
observer.observe(node, { characterData: true });
return function() {
node.data = (iterations = ++iterations % 2);
};
}
// web worker
function lib$es6$promise$asap$$useMessageChannel() {
var channel = new MessageChannel();
channel.port1.onmessage = lib$es6$promise$asap$$flush;
return function () {
channel.port2.postMessage(0);
};
}
function lib$es6$promise$asap$$useSetTimeout() {
return function() {
setTimeout(lib$es6$promise$asap$$flush, 1);
};
}
var lib$es6$promise$asap$$queue = new Array(1000);
function lib$es6$promise$asap$$flush() {
for (var i = 0; i < lib$es6$promise$asap$$len; i+=2) {
var callback = lib$es6$promise$asap$$queue[i];
var arg = lib$es6$promise$asap$$queue[i+1];
callback(arg);
lib$es6$promise$asap$$queue[i] = undefined;
lib$es6$promise$asap$$queue[i+1] = undefined;
}
lib$es6$promise$asap$$len = 0;
}
function lib$es6$promise$asap$$attemptVertex() {
try {
var r = require;
var vertx = r('vertx');
lib$es6$promise$asap$$vertxNext = vertx.runOnLoop || vertx.runOnContext;
return lib$es6$promise$asap$$useVertxTimer();
} catch(e) {
return lib$es6$promise$asap$$useSetTimeout();
}
}
var lib$es6$promise$asap$$scheduleFlush;
// Decide what async method to use to triggering processing of queued callbacks:
if (lib$es6$promise$asap$$isNode) {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useNextTick();
} else if (lib$es6$promise$asap$$BrowserMutationObserver) {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMutationObserver();
} else if (lib$es6$promise$asap$$isWorker) {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useMessageChannel();
} else if (lib$es6$promise$asap$$browserWindow === undefined && typeof require === 'function') {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$attemptVertex();
} else {
lib$es6$promise$asap$$scheduleFlush = lib$es6$promise$asap$$useSetTimeout();
}
function lib$es6$promise$$internal$$noop() {}
var lib$es6$promise$$internal$$PENDING = void 0;
var lib$es6$promise$$internal$$FULFILLED = 1;
var lib$es6$promise$$internal$$REJECTED = 2;
var lib$es6$promise$$internal$$GET_THEN_ERROR = new lib$es6$promise$$internal$$ErrorObject();
function lib$es6$promise$$internal$$selfFullfillment() {
return new TypeError("You cannot resolve a promise with itself");
}
function lib$es6$promise$$internal$$cannotReturnOwn() {
return new TypeError('A promises callback cannot return that same promise.');
}
function lib$es6$promise$$internal$$getThen(promise) {
try {
return promise.then;
} catch(error) {
lib$es6$promise$$internal$$GET_THEN_ERROR.error = error;
return lib$es6$promise$$internal$$GET_THEN_ERROR;
}
}
function lib$es6$promise$$internal$$tryThen(then, value, fulfillmentHandler, rejectionHandler) {
try {
then.call(value, fulfillmentHandler, rejectionHandler);
} catch(e) {
return e;
}
}
function lib$es6$promise$$internal$$handleForeignThenable(promise, thenable, then) {
lib$es6$promise$asap$$asap(function(promise) {
var sealed = false;
var error = lib$es6$promise$$internal$$tryThen(then, thenable, function(value) {
if (sealed) { return; }
sealed = true;
if (thenable !== value) {
lib$es6$promise$$internal$$resolve(promise, value);
} else {
lib$es6$promise$$internal$$fulfill(promise, value);
}
}, function(reason) {
if (sealed) { return; }
sealed = true;
lib$es6$promise$$internal$$reject(promise, reason);
}, 'Settle: ' + (promise._label || ' unknown promise'));
if (!sealed && error) {
sealed = true;
lib$es6$promise$$internal$$reject(promise, error);
}
}, promise);
}
function lib$es6$promise$$internal$$handleOwnThenable(promise, thenable) {
if (thenable._state === lib$es6$promise$$internal$$FULFILLED) {
lib$es6$promise$$internal$$fulfill(promise, thenable._result);
} else if (thenable._state === lib$es6$promise$$internal$$REJECTED) {
lib$es6$promise$$internal$$reject(promise, thenable._result);
} else {
lib$es6$promise$$internal$$subscribe(thenable, undefined, function(value) {
lib$es6$promise$$internal$$resolve(promise, value);
}, function(reason) {
lib$es6$promise$$internal$$reject(promise, reason);
});
}
}
function lib$es6$promise$$internal$$handleMaybeThenable(promise, maybeThenable) {
if (maybeThenable.constructor === promise.constructor) {
lib$es6$promise$$internal$$handleOwnThenable(promise, maybeThenable);
} else {
var then = lib$es6$promise$$internal$$getThen(maybeThenable);
if (then === lib$es6$promise$$internal$$GET_THEN_ERROR) {
lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$GET_THEN_ERROR.error);
} else if (then === undefined) {
lib$es6$promise$$internal$$fulfill(promise, maybeThenable);
} else if (lib$es6$promise$utils$$isFunction(then)) {
lib$es6$promise$$internal$$handleForeignThenable(promise, maybeThenable, then);
} else {
lib$es6$promise$$internal$$fulfill(promise, maybeThenable);
}
}
}
function lib$es6$promise$$internal$$resolve(promise, value) {
if (promise === value) {
lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$selfFullfillment());
} else if (lib$es6$promise$utils$$objectOrFunction(value)) {
lib$es6$promise$$internal$$handleMaybeThenable(promise, value);
} else {
lib$es6$promise$$internal$$fulfill(promise, value);
}
}
function lib$es6$promise$$internal$$publishRejection(promise) {
if (promise._onerror) {
promise._onerror(promise._result);
}
lib$es6$promise$$internal$$publish(promise);
}
function lib$es6$promise$$internal$$fulfill(promise, value) {
if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }
promise._result = value;
promise._state = lib$es6$promise$$internal$$FULFILLED;
if (promise._subscribers.length !== 0) {
lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, promise);
}
}
function lib$es6$promise$$internal$$reject(promise, reason) {
if (promise._state !== lib$es6$promise$$internal$$PENDING) { return; }
promise._state = lib$es6$promise$$internal$$REJECTED;
promise._result = reason;
lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publishRejection, promise);
}
function lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection) {
var subscribers = parent._subscribers;
var length = subscribers.length;
parent._onerror = null;
subscribers[length] = child;
subscribers[length + lib$es6$promise$$internal$$FULFILLED] = onFulfillment;
subscribers[length + lib$es6$promise$$internal$$REJECTED] = onRejection;
if (length === 0 && parent._state) {
lib$es6$promise$asap$$asap(lib$es6$promise$$internal$$publish, parent);
}
}
function lib$es6$promise$$internal$$publish(promise) {
var subscribers = promise._subscribers;
var settled = promise._state;
if (subscribers.length === 0) { return; }
var child, callback, detail = promise._result;
for (var i = 0; i < subscribers.length; i += 3) {
child = subscribers[i];
callback = subscribers[i + settled];
if (child) {
lib$es6$promise$$internal$$invokeCallback(settled, child, callback, detail);
} else {
callback(detail);
}
}
promise._subscribers.length = 0;
}
function lib$es6$promise$$internal$$ErrorObject() {
this.error = null;
}
var lib$es6$promise$$internal$$TRY_CATCH_ERROR = new lib$es6$promise$$internal$$ErrorObject();
function lib$es6$promise$$internal$$tryCatch(callback, detail) {
try {
return callback(detail);
} catch(e) {
lib$es6$promise$$internal$$TRY_CATCH_ERROR.error = e;
return lib$es6$promise$$internal$$TRY_CATCH_ERROR;
}
}
function lib$es6$promise$$internal$$invokeCallback(settled, promise, callback, detail) {
var hasCallback = lib$es6$promise$utils$$isFunction(callback),
value, error, succeeded, failed;
if (hasCallback) {
value = lib$es6$promise$$internal$$tryCatch(callback, detail);
if (value === lib$es6$promise$$internal$$TRY_CATCH_ERROR) {
failed = true;
error = value.error;
value = null;
} else {
succeeded = true;
}
if (promise === value) {
lib$es6$promise$$internal$$reject(promise, lib$es6$promise$$internal$$cannotReturnOwn());
return;
}
} else {
value = detail;
succeeded = true;
}
if (promise._state !== lib$es6$promise$$internal$$PENDING) {
// noop
} else if (hasCallback && succeeded) {
lib$es6$promise$$internal$$resolve(promise, value);
} else if (failed) {
lib$es6$promise$$internal$$reject(promise, error);
} else if (settled === lib$es6$promise$$internal$$FULFILLED) {
lib$es6$promise$$internal$$fulfill(promise, value);
} else if (settled === lib$es6$promise$$internal$$REJECTED) {
lib$es6$promise$$internal$$reject(promise, value);
}
}
function lib$es6$promise$$internal$$initializePromise(promise, resolver) {
try {
resolver(function resolvePromise(value){
lib$es6$promise$$internal$$resolve(promise, value);
}, function rejectPromise(reason) {
lib$es6$promise$$internal$$reject(promise, reason);
});
} catch(e) {
lib$es6$promise$$internal$$reject(promise, e);
}
}
function lib$es6$promise$enumerator$$Enumerator(Constructor, input) {
var enumerator = this;
enumerator._instanceConstructor = Constructor;
enumerator.promise = new Constructor(lib$es6$promise$$internal$$noop);
if (enumerator._validateInput(input)) {
enumerator._input = input;
enumerator.length = input.length;
enumerator._remaining = input.length;
enumerator._init();
if (enumerator.length === 0) {
lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result);
} else {
enumerator.length = enumerator.length || 0;
enumerator._enumerate();
if (enumerator._remaining === 0) {
lib$es6$promise$$internal$$fulfill(enumerator.promise, enumerator._result);
}
}
} else {
lib$es6$promise$$internal$$reject(enumerator.promise, enumerator._validationError());
}
}
lib$es6$promise$enumerator$$Enumerator.prototype._validateInput = function(input) {
return lib$es6$promise$utils$$isArray(input);
};
lib$es6$promise$enumerator$$Enumerator.prototype._validationError = function() {
return new Error('Array Methods must be provided an Array');
};
lib$es6$promise$enumerator$$Enumerator.prototype._init = function() {
this._result = new Array(this.length);
};
var lib$es6$promise$enumerator$$default = lib$es6$promise$enumerator$$Enumerator;
lib$es6$promise$enumerator$$Enumerator.prototype._enumerate = function() {
var enumerator = this;
var length = enumerator.length;
var promise = enumerator.promise;
var input = enumerator._input;
for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {
enumerator._eachEntry(input[i], i);
}
};
lib$es6$promise$enumerator$$Enumerator.prototype._eachEntry = function(entry, i) {
var enumerator = this;
var c = enumerator._instanceConstructor;
if (lib$es6$promise$utils$$isMaybeThenable(entry)) {
if (entry.constructor === c && entry._state !== lib$es6$promise$$internal$$PENDING) {
entry._onerror = null;
enumerator._settledAt(entry._state, i, entry._result);
} else {
enumerator._willSettleAt(c.resolve(entry), i);
}
} else {
enumerator._remaining--;
enumerator._result[i] = entry;
}
};
lib$es6$promise$enumerator$$Enumerator.prototype._settledAt = function(state, i, value) {
var enumerator = this;
var promise = enumerator.promise;
if (promise._state === lib$es6$promise$$internal$$PENDING) {
enumerator._remaining--;
if (state === lib$es6$promise$$internal$$REJECTED) {
lib$es6$promise$$internal$$reject(promise, value);
} else {
enumerator._result[i] = value;
}
}
if (enumerator._remaining === 0) {
lib$es6$promise$$internal$$fulfill(promise, enumerator._result);
}
};
lib$es6$promise$enumerator$$Enumerator.prototype._willSettleAt = function(promise, i) {
var enumerator = this;
lib$es6$promise$$internal$$subscribe(promise, undefined, function(value) {
enumerator._settledAt(lib$es6$promise$$internal$$FULFILLED, i, value);
}, function(reason) {
enumerator._settledAt(lib$es6$promise$$internal$$REJECTED, i, reason);
});
};
function lib$es6$promise$promise$all$$all(entries) {
return new lib$es6$promise$enumerator$$default(this, entries).promise;
}
var lib$es6$promise$promise$all$$default = lib$es6$promise$promise$all$$all;
function lib$es6$promise$promise$race$$race(entries) {
/*jshint validthis:true */
var Constructor = this;
var promise = new Constructor(lib$es6$promise$$internal$$noop);
if (!lib$es6$promise$utils$$isArray(entries)) {
lib$es6$promise$$internal$$reject(promise, new TypeError('You must pass an array to race.'));
return promise;
}
var length = entries.length;
function onFulfillment(value) {
lib$es6$promise$$internal$$resolve(promise, value);
}
function onRejection(reason) {
lib$es6$promise$$internal$$reject(promise, reason);
}
for (var i = 0; promise._state === lib$es6$promise$$internal$$PENDING && i < length; i++) {
lib$es6$promise$$internal$$subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);
}
return promise;
}
var lib$es6$promise$promise$race$$default = lib$es6$promise$promise$race$$race;
function lib$es6$promise$promise$resolve$$resolve(object) {
/*jshint validthis:true */
var Constructor = this;
if (object && typeof object === 'object' && object.constructor === Constructor) {
return object;
}
var promise = new Constructor(lib$es6$promise$$internal$$noop);
lib$es6$promise$$internal$$resolve(promise, object);
return promise;
}
var lib$es6$promise$promise$resolve$$default = lib$es6$promise$promise$resolve$$resolve;
function lib$es6$promise$promise$reject$$reject(reason) {
/*jshint validthis:true */
var Constructor = this;
var promise = new Constructor(lib$es6$promise$$internal$$noop);
lib$es6$promise$$internal$$reject(promise, reason);
return promise;
}
var lib$es6$promise$promise$reject$$default = lib$es6$promise$promise$reject$$reject;
var lib$es6$promise$promise$$counter = 0;
function lib$es6$promise$promise$$needsResolver() {
throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
}
function lib$es6$promise$promise$$needsNew() {
throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
}
var lib$es6$promise$promise$$default = lib$es6$promise$promise$$Promise;
/**
Promise objects represent the eventual result of an asynchronous operation. The
primary way of interacting with a promise is through its `then` method, which
registers callbacks to receive either a promise's eventual value or the reason
why the promise cannot be fulfilled.
Terminology
-----------
- `promise` is an object or function with a `then` method whose behavior conforms to this specification.
- `thenable` is an object or function that defines a `then` method.
- `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
- `exception` is a value that is thrown using the throw statement.
- `reason` is a value that indicates why a promise was rejected.
- `settled` the final resting state of a promise, fulfilled or rejected.
A promise can be in one of three states: pending, fulfilled, or rejected.
Promises that are fulfilled have a fulfillment value and are in the fulfilled
state. Promises that are rejected have a rejection reason and are in the
rejected state. A fulfillment value is never a thenable.
Promises can also be said to *resolve* a value. If this value is also a
promise, then the original promise's settled state will match the value's
settled state. So a promise that *resolves* a promise that rejects will
itself reject, and a promise that *resolves* a promise that fulfills will
itself fulfill.
Basic Usage:
------------
```js
var promise = new Promise(function(resolve, reject) {
// on success
resolve(value);
// on failure
reject(reason);
});
promise.then(function(value) {
// on fulfillment
}, function(reason) {
// on rejection
});
```
Advanced Usage:
---------------
Promises shine when abstracting away asynchronous interactions such as
`XMLHttpRequest`s.
```js
function getJSON(url) {
return new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = handler;
xhr.responseType = 'json';
xhr.setRequestHeader('Accept', 'application/json');
xhr.send();
function handler() {
if (this.readyState === this.DONE) {
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
}
}
};
});
}
getJSON('/posts.json').then(function(json) {
// on fulfillment
}, function(reason) {
// on rejection
});
```
Unlike callbacks, promises are great composable primitives.
```js
Promise.all([
getJSON('/posts'),
getJSON('/comments')
]).then(function(values){
values[0] // => postsJSON
values[1] // => commentsJSON
return values;
});
```
@class Promise
@param {function} resolver
Useful for tooling.
@constructor
*/
function lib$es6$promise$promise$$Promise(resolver) {
this._id = lib$es6$promise$promise$$counter++;
this._state = undefined;
this._result = undefined;
this._subscribers = [];
if (lib$es6$promise$$internal$$noop !== resolver) {
if (!lib$es6$promise$utils$$isFunction(resolver)) {
lib$es6$promise$promise$$needsResolver();
}
if (!(this instanceof lib$es6$promise$promise$$Promise)) {
lib$es6$promise$promise$$needsNew();
}
lib$es6$promise$$internal$$initializePromise(this, resolver);
}
}
lib$es6$promise$promise$$Promise.all = lib$es6$promise$promise$all$$default;
lib$es6$promise$promise$$Promise.race = lib$es6$promise$promise$race$$default;
lib$es6$promise$promise$$Promise.resolve = lib$es6$promise$promise$resolve$$default;
lib$es6$promise$promise$$Promise.reject = lib$es6$promise$promise$reject$$default;
lib$es6$promise$promise$$Promise._setScheduler = lib$es6$promise$asap$$setScheduler;
lib$es6$promise$promise$$Promise._setAsap = lib$es6$promise$asap$$setAsap;
lib$es6$promise$promise$$Promise._asap = lib$es6$promise$asap$$asap;
lib$es6$promise$promise$$Promise.prototype = {
constructor: lib$es6$promise$promise$$Promise,
/**
The primary way of interacting with a promise is through its `then` method,
which registers callbacks to receive either a promise's eventual value or the
reason why the promise cannot be fulfilled.
```js
findUser().then(function(user){
// user is available
}, function(reason){
// user is unavailable, and you are given the reason why
});
```
Chaining
--------
The return value of `then` is itself a promise. This second, 'downstream'
promise is resolved with the return value of the first promise's fulfillment
or rejection handler, or rejected if the handler throws an exception.
```js
findUser().then(function (user) {
return user.name;
}, function (reason) {
return 'default name';
}).then(function (userName) {
// If `findUser` fulfilled, `userName` will be the user's name, otherwise it
// will be `'default name'`
});
findUser().then(function (user) {
throw new Error('Found user, but still unhappy');
}, function (reason) {
throw new Error('`findUser` rejected and we're unhappy');
}).then(function (value) {
// never reached
}, function (reason) {
// if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
// If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
});
```
If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
```js
findUser().then(function (user) {
throw new PedagogicalException('Upstream error');
}).then(function (value) {
// never reached
}).then(function (value) {
// never reached
}, function (reason) {
// The `PedgagocialException` is propagated all the way down to here
});
```
Assimilation
------------
Sometimes the value you want to propagate to a downstream promise can only be
retrieved asynchronously. This can be achieved by returning a promise in the
fulfillment or rejection handler. The downstream promise will then be pending
until the returned promise is settled. This is called *assimilation*.
```js
findUser().then(function (user) {
return findCommentsByAuthor(user);
}).then(function (comments) {
// The user's comments are now available
});
```
If the assimliated promise rejects, then the downstream promise will also reject.
```js
findUser().then(function (user) {
return findCommentsByAuthor(user);
}).then(function (comments) {
// If `findCommentsByAuthor` fulfills, we'll have the value here
}, function (reason) {
// If `findCommentsByAuthor` rejects, we'll have the reason here
});
```
Simple Example
--------------
Synchronous Example
```javascript
var result;
try {
result = findResult();
// success
} catch(reason) {
// failure
}
```
Errback Example
```js
findResult(function(result, err){
if (err) {
// failure
} else {
// success
}
});
```
Promise Example;
```javascript
findResult().then(function(result){
// success
}, function(reason){
// failure
});
```
Advanced Example
--------------
Synchronous Example
```javascript
var author, books;
try {
author = findAuthor();
books = findBooksByAuthor(author);
// success
} catch(reason) {
// failure
}
```
Errback Example
```js
function foundBooks(books) {
}
function failure(reason) {
}
findAuthor(function(author, err){
if (err) {
failure(err);
// failure
} else {
try {
findBoooksByAuthor(author, function(books, err) {
if (err) {
failure(err);
} else {
try {
foundBooks(books);
} catch(reason) {
failure(reason);
}
}
});
} catch(error) {
failure(err);
}
// success
}
});
```
Promise Example;
```javascript
findAuthor().
then(findBooksByAuthor).
then(function(books){
// found books
}).catch(function(reason){
// something went wrong
});
```
@method then
@param {Function} onFulfilled
@param {Function} onRejected
Useful for tooling.
@return {Promise}
*/
then: function(onFulfillment, onRejection) {
var parent = this;
var state = parent._state;
if (state === lib$es6$promise$$internal$$FULFILLED && !onFulfillment || state === lib$es6$promise$$internal$$REJECTED && !onRejection) {
return this;
}
var child = new this.constructor(lib$es6$promise$$internal$$noop);
var result = parent._result;
if (state) {
var callback = arguments[state - 1];
lib$es6$promise$asap$$asap(function(){
lib$es6$promise$$internal$$invokeCallback(state, child, callback, result);
});
} else {
lib$es6$promise$$internal$$subscribe(parent, child, onFulfillment, onRejection);
}
return child;
},
/**
`catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
as the catch block of a try/catch statement.
```js
function findAuthor(){
throw new Error('couldn't find that author');
}
// synchronous
try {
findAuthor();
} catch(reason) {
// something went wrong
}
// async with promises
findAuthor().catch(function(reason){
// something went wrong
});
```
@method catch
@param {Function} onRejection
Useful for tooling.
@return {Promise}
*/
'catch': function(onRejection) {
return this.then(null, onRejection);
}
};
function lib$es6$promise$polyfill$$polyfill() {
var local;
if (typeof global !== 'undefined') {
local = global;
} else if (typeof self !== 'undefined') {
local = self;
} else {
try {
local = Function('return this')();
} catch (e) {
throw new Error('polyfill failed because global object is unavailable in this environment');
}
}
var P = local.Promise;
if (P && Object.prototype.toString.call(P.resolve()) === '[object Promise]' && !P.cast) {
return;
}
local.Promise = lib$es6$promise$promise$$default;
}
var lib$es6$promise$polyfill$$default = lib$es6$promise$polyfill$$polyfill;
var lib$es6$promise$umd$$ES6Promise = {
'Promise': lib$es6$promise$promise$$default,
'polyfill': lib$es6$promise$polyfill$$default
};
/* global define:true module:true window: true */
if (typeof define === 'function' && define['amd']) {
define(function() { return lib$es6$promise$umd$$ES6Promise; });
} else if (typeof module !== 'undefined' && module['exports']) {
module['exports'] = lib$es6$promise$umd$$ES6Promise;
} else if (typeof this !== 'undefined') {
this['ES6Promise'] = lib$es6$promise$umd$$ES6Promise;
}
lib$es6$promise$polyfill$$default();
}).call(this);
//# sourceMappingURL=es6-promise.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,25 @@
<html>
<head>
<meta charset="utf-8">
<title>rsvp.js Tests</title>
<link rel="stylesheet" href="mocha.css" />
</head>
<body>
<div id="mocha"></div>
<script src="json3.js"></script>
<script src="mocha.js"></script>
<script src="/testem.js"></script>
<script>
mocha.setup({
ui: 'bdd',
timeout: 200,
ignoreLeaks: true
});
</script>
<script src="browserify.js"></script>
<script>
if (window.mochaPhantomJS) { mochaPhantomJS.run(); }
else { mocha.run(); }
</script>
</body>
</html>

View File

@@ -0,0 +1,902 @@
/*! JSON v3.3.2 | http://bestiejs.github.io/json3 | Copyright 2012-2014, Kit Cambridge | http://kit.mit-license.org */
;(function () {
// Detect the `define` function exposed by asynchronous module loaders. The
// strict `define` check is necessary for compatibility with `r.js`.
var isLoader = typeof define === "function" && define.amd;
// A set of types used to distinguish objects from primitives.
var objectTypes = {
"function": true,
"object": true
};
// Detect the `exports` object exposed by CommonJS implementations.
var freeExports = objectTypes[typeof exports] && exports && !exports.nodeType && exports;
// Use the `global` object exposed by Node (including Browserify via
// `insert-module-globals`), Narwhal, and Ringo as the default context,
// and the `window` object in browsers. Rhino exports a `global` function
// instead.
var root = objectTypes[typeof window] && window || this,
freeGlobal = freeExports && objectTypes[typeof module] && module && !module.nodeType && typeof global == "object" && global;
if (freeGlobal && (freeGlobal["global"] === freeGlobal || freeGlobal["window"] === freeGlobal || freeGlobal["self"] === freeGlobal)) {
root = freeGlobal;
}
// Public: Initializes JSON 3 using the given `context` object, attaching the
// `stringify` and `parse` functions to the specified `exports` object.
function runInContext(context, exports) {
context || (context = root["Object"]());
exports || (exports = root["Object"]());
// Native constructor aliases.
var Number = context["Number"] || root["Number"],
String = context["String"] || root["String"],
Object = context["Object"] || root["Object"],
Date = context["Date"] || root["Date"],
SyntaxError = context["SyntaxError"] || root["SyntaxError"],
TypeError = context["TypeError"] || root["TypeError"],
Math = context["Math"] || root["Math"],
nativeJSON = context["JSON"] || root["JSON"];
// Delegate to the native `stringify` and `parse` implementations.
if (typeof nativeJSON == "object" && nativeJSON) {
exports.stringify = nativeJSON.stringify;
exports.parse = nativeJSON.parse;
}
// Convenience aliases.
var objectProto = Object.prototype,
getClass = objectProto.toString,
isProperty, forEach, undef;
// Test the `Date#getUTC*` methods. Based on work by @Yaffle.
var isExtended = new Date(-3509827334573292);
try {
// The `getUTCFullYear`, `Month`, and `Date` methods return nonsensical
// results for certain dates in Opera >= 10.53.
isExtended = isExtended.getUTCFullYear() == -109252 && isExtended.getUTCMonth() === 0 && isExtended.getUTCDate() === 1 &&
// Safari < 2.0.2 stores the internal millisecond time value correctly,
// but clips the values returned by the date methods to the range of
// signed 32-bit integers ([-2 ** 31, 2 ** 31 - 1]).
isExtended.getUTCHours() == 10 && isExtended.getUTCMinutes() == 37 && isExtended.getUTCSeconds() == 6 && isExtended.getUTCMilliseconds() == 708;
} catch (exception) {}
// Internal: Determines whether the native `JSON.stringify` and `parse`
// implementations are spec-compliant. Based on work by Ken Snyder.
function has(name) {
if (has[name] !== undef) {
// Return cached feature test result.
return has[name];
}
var isSupported;
if (name == "bug-string-char-index") {
// IE <= 7 doesn't support accessing string characters using square
// bracket notation. IE 8 only supports this for primitives.
isSupported = "a"[0] != "a";
} else if (name == "json") {
// Indicates whether both `JSON.stringify` and `JSON.parse` are
// supported.
isSupported = has("json-stringify") && has("json-parse");
} else {
var value, serialized = '{"a":[1,true,false,null,"\\u0000\\b\\n\\f\\r\\t"]}';
// Test `JSON.stringify`.
if (name == "json-stringify") {
var stringify = exports.stringify, stringifySupported = typeof stringify == "function" && isExtended;
if (stringifySupported) {
// A test function object with a custom `toJSON` method.
(value = function () {
return 1;
}).toJSON = value;
try {
stringifySupported =
// Firefox 3.1b1 and b2 serialize string, number, and boolean
// primitives as object literals.
stringify(0) === "0" &&
// FF 3.1b1, b2, and JSON 2 serialize wrapped primitives as object
// literals.
stringify(new Number()) === "0" &&
stringify(new String()) == '""' &&
// FF 3.1b1, 2 throw an error if the value is `null`, `undefined`, or
// does not define a canonical JSON representation (this applies to
// objects with `toJSON` properties as well, *unless* they are nested
// within an object or array).
stringify(getClass) === undef &&
// IE 8 serializes `undefined` as `"undefined"`. Safari <= 5.1.7 and
// FF 3.1b3 pass this test.
stringify(undef) === undef &&
// Safari <= 5.1.7 and FF 3.1b3 throw `Error`s and `TypeError`s,
// respectively, if the value is omitted entirely.
stringify() === undef &&
// FF 3.1b1, 2 throw an error if the given value is not a number,
// string, array, object, Boolean, or `null` literal. This applies to
// objects with custom `toJSON` methods as well, unless they are nested
// inside object or array literals. YUI 3.0.0b1 ignores custom `toJSON`
// methods entirely.
stringify(value) === "1" &&
stringify([value]) == "[1]" &&
// Prototype <= 1.6.1 serializes `[undefined]` as `"[]"` instead of
// `"[null]"`.
stringify([undef]) == "[null]" &&
// YUI 3.0.0b1 fails to serialize `null` literals.
stringify(null) == "null" &&
// FF 3.1b1, 2 halts serialization if an array contains a function:
// `[1, true, getClass, 1]` serializes as "[1,true,],". FF 3.1b3
// elides non-JSON values from objects and arrays, unless they
// define custom `toJSON` methods.
stringify([undef, getClass, null]) == "[null,null,null]" &&
// Simple serialization test. FF 3.1b1 uses Unicode escape sequences
// where character escape codes are expected (e.g., `\b` => `\u0008`).
stringify({ "a": [value, true, false, null, "\x00\b\n\f\r\t"] }) == serialized &&
// FF 3.1b1 and b2 ignore the `filter` and `width` arguments.
stringify(null, value) === "1" &&
stringify([1, 2], null, 1) == "[\n 1,\n 2\n]" &&
// JSON 2, Prototype <= 1.7, and older WebKit builds incorrectly
// serialize extended years.
stringify(new Date(-8.64e15)) == '"-271821-04-20T00:00:00.000Z"' &&
// The milliseconds are optional in ES 5, but required in 5.1.
stringify(new Date(8.64e15)) == '"+275760-09-13T00:00:00.000Z"' &&
// Firefox <= 11.0 incorrectly serializes years prior to 0 as negative
// four-digit years instead of six-digit years. Credits: @Yaffle.
stringify(new Date(-621987552e5)) == '"-000001-01-01T00:00:00.000Z"' &&
// Safari <= 5.1.5 and Opera >= 10.53 incorrectly serialize millisecond
// values less than 1000. Credits: @Yaffle.
stringify(new Date(-1)) == '"1969-12-31T23:59:59.999Z"';
} catch (exception) {
stringifySupported = false;
}
}
isSupported = stringifySupported;
}
// Test `JSON.parse`.
if (name == "json-parse") {
var parse = exports.parse;
if (typeof parse == "function") {
try {
// FF 3.1b1, b2 will throw an exception if a bare literal is provided.
// Conforming implementations should also coerce the initial argument to
// a string prior to parsing.
if (parse("0") === 0 && !parse(false)) {
// Simple parsing test.
value = parse(serialized);
var parseSupported = value["a"].length == 5 && value["a"][0] === 1;
if (parseSupported) {
try {
// Safari <= 5.1.2 and FF 3.1b1 allow unescaped tabs in strings.
parseSupported = !parse('"\t"');
} catch (exception) {}
if (parseSupported) {
try {
// FF 4.0 and 4.0.1 allow leading `+` signs and leading
// decimal points. FF 4.0, 4.0.1, and IE 9-10 also allow
// certain octal literals.
parseSupported = parse("01") !== 1;
} catch (exception) {}
}
if (parseSupported) {
try {
// FF 4.0, 4.0.1, and Rhino 1.7R3-R4 allow trailing decimal
// points. These environments, along with FF 3.1b1 and 2,
// also allow trailing commas in JSON objects and arrays.
parseSupported = parse("1.") !== 1;
} catch (exception) {}
}
}
}
} catch (exception) {
parseSupported = false;
}
}
isSupported = parseSupported;
}
}
return has[name] = !!isSupported;
}
if (!has("json")) {
// Common `[[Class]]` name aliases.
var functionClass = "[object Function]",
dateClass = "[object Date]",
numberClass = "[object Number]",
stringClass = "[object String]",
arrayClass = "[object Array]",
booleanClass = "[object Boolean]";
// Detect incomplete support for accessing string characters by index.
var charIndexBuggy = has("bug-string-char-index");
// Define additional utility methods if the `Date` methods are buggy.
if (!isExtended) {
var floor = Math.floor;
// A mapping between the months of the year and the number of days between
// January 1st and the first of the respective month.
var Months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334];
// Internal: Calculates the number of days between the Unix epoch and the
// first day of the given month.
var getDay = function (year, month) {
return Months[month] + 365 * (year - 1970) + floor((year - 1969 + (month = +(month > 1))) / 4) - floor((year - 1901 + month) / 100) + floor((year - 1601 + month) / 400);
};
}
// Internal: Determines if a property is a direct property of the given
// object. Delegates to the native `Object#hasOwnProperty` method.
if (!(isProperty = objectProto.hasOwnProperty)) {
isProperty = function (property) {
var members = {}, constructor;
if ((members.__proto__ = null, members.__proto__ = {
// The *proto* property cannot be set multiple times in recent
// versions of Firefox and SeaMonkey.
"toString": 1
}, members).toString != getClass) {
// Safari <= 2.0.3 doesn't implement `Object#hasOwnProperty`, but
// supports the mutable *proto* property.
isProperty = function (property) {
// Capture and break the object's prototype chain (see section 8.6.2
// of the ES 5.1 spec). The parenthesized expression prevents an
// unsafe transformation by the Closure Compiler.
var original = this.__proto__, result = property in (this.__proto__ = null, this);
// Restore the original prototype chain.
this.__proto__ = original;
return result;
};
} else {
// Capture a reference to the top-level `Object` constructor.
constructor = members.constructor;
// Use the `constructor` property to simulate `Object#hasOwnProperty` in
// other environments.
isProperty = function (property) {
var parent = (this.constructor || constructor).prototype;
return property in this && !(property in parent && this[property] === parent[property]);
};
}
members = null;
return isProperty.call(this, property);
};
}
// Internal: Normalizes the `for...in` iteration algorithm across
// environments. Each enumerated key is yielded to a `callback` function.
forEach = function (object, callback) {
var size = 0, Properties, members, property;
// Tests for bugs in the current environment's `for...in` algorithm. The
// `valueOf` property inherits the non-enumerable flag from
// `Object.prototype` in older versions of IE, Netscape, and Mozilla.
(Properties = function () {
this.valueOf = 0;
}).prototype.valueOf = 0;
// Iterate over a new instance of the `Properties` class.
members = new Properties();
for (property in members) {
// Ignore all properties inherited from `Object.prototype`.
if (isProperty.call(members, property)) {
size++;
}
}
Properties = members = null;
// Normalize the iteration algorithm.
if (!size) {
// A list of non-enumerable properties inherited from `Object.prototype`.
members = ["valueOf", "toString", "toLocaleString", "propertyIsEnumerable", "isPrototypeOf", "hasOwnProperty", "constructor"];
// IE <= 8, Mozilla 1.0, and Netscape 6.2 ignore shadowed non-enumerable
// properties.
forEach = function (object, callback) {
var isFunction = getClass.call(object) == functionClass, property, length;
var hasProperty = !isFunction && typeof object.constructor != "function" && objectTypes[typeof object.hasOwnProperty] && object.hasOwnProperty || isProperty;
for (property in object) {
// Gecko <= 1.0 enumerates the `prototype` property of functions under
// certain conditions; IE does not.
if (!(isFunction && property == "prototype") && hasProperty.call(object, property)) {
callback(property);
}
}
// Manually invoke the callback for each non-enumerable property.
for (length = members.length; property = members[--length]; hasProperty.call(object, property) && callback(property));
};
} else if (size == 2) {
// Safari <= 2.0.4 enumerates shadowed properties twice.
forEach = function (object, callback) {
// Create a set of iterated properties.
var members = {}, isFunction = getClass.call(object) == functionClass, property;
for (property in object) {
// Store each property name to prevent double enumeration. The
// `prototype` property of functions is not enumerated due to cross-
// environment inconsistencies.
if (!(isFunction && property == "prototype") && !isProperty.call(members, property) && (members[property] = 1) && isProperty.call(object, property)) {
callback(property);
}
}
};
} else {
// No bugs detected; use the standard `for...in` algorithm.
forEach = function (object, callback) {
var isFunction = getClass.call(object) == functionClass, property, isConstructor;
for (property in object) {
if (!(isFunction && property == "prototype") && isProperty.call(object, property) && !(isConstructor = property === "constructor")) {
callback(property);
}
}
// Manually invoke the callback for the `constructor` property due to
// cross-environment inconsistencies.
if (isConstructor || isProperty.call(object, (property = "constructor"))) {
callback(property);
}
};
}
return forEach(object, callback);
};
// Public: Serializes a JavaScript `value` as a JSON string. The optional
// `filter` argument may specify either a function that alters how object and
// array members are serialized, or an array of strings and numbers that
// indicates which properties should be serialized. The optional `width`
// argument may be either a string or number that specifies the indentation
// level of the output.
if (!has("json-stringify")) {
// Internal: A map of control characters and their escaped equivalents.
var Escapes = {
92: "\\\\",
34: '\\"',
8: "\\b",
12: "\\f",
10: "\\n",
13: "\\r",
9: "\\t"
};
// Internal: Converts `value` into a zero-padded string such that its
// length is at least equal to `width`. The `width` must be <= 6.
var leadingZeroes = "000000";
var toPaddedString = function (width, value) {
// The `|| 0` expression is necessary to work around a bug in
// Opera <= 7.54u2 where `0 == -0`, but `String(-0) !== "0"`.
return (leadingZeroes + (value || 0)).slice(-width);
};
// Internal: Double-quotes a string `value`, replacing all ASCII control
// characters (characters with code unit values between 0 and 31) with
// their escaped equivalents. This is an implementation of the
// `Quote(value)` operation defined in ES 5.1 section 15.12.3.
var unicodePrefix = "\\u00";
var quote = function (value) {
var result = '"', index = 0, length = value.length, useCharIndex = !charIndexBuggy || length > 10;
var symbols = useCharIndex && (charIndexBuggy ? value.split("") : value);
for (; index < length; index++) {
var charCode = value.charCodeAt(index);
// If the character is a control character, append its Unicode or
// shorthand escape sequence; otherwise, append the character as-is.
switch (charCode) {
case 8: case 9: case 10: case 12: case 13: case 34: case 92:
result += Escapes[charCode];
break;
default:
if (charCode < 32) {
result += unicodePrefix + toPaddedString(2, charCode.toString(16));
break;
}
result += useCharIndex ? symbols[index] : value.charAt(index);
}
}
return result + '"';
};
// Internal: Recursively serializes an object. Implements the
// `Str(key, holder)`, `JO(value)`, and `JA(value)` operations.
var serialize = function (property, object, callback, properties, whitespace, indentation, stack) {
var value, className, year, month, date, time, hours, minutes, seconds, milliseconds, results, element, index, length, prefix, result;
try {
// Necessary for host object support.
value = object[property];
} catch (exception) {}
if (typeof value == "object" && value) {
className = getClass.call(value);
if (className == dateClass && !isProperty.call(value, "toJSON")) {
if (value > -1 / 0 && value < 1 / 0) {
// Dates are serialized according to the `Date#toJSON` method
// specified in ES 5.1 section 15.9.5.44. See section 15.9.1.15
// for the ISO 8601 date time string format.
if (getDay) {
// Manually compute the year, month, date, hours, minutes,
// seconds, and milliseconds if the `getUTC*` methods are
// buggy. Adapted from @Yaffle's `date-shim` project.
date = floor(value / 864e5);
for (year = floor(date / 365.2425) + 1970 - 1; getDay(year + 1, 0) <= date; year++);
for (month = floor((date - getDay(year, 0)) / 30.42); getDay(year, month + 1) <= date; month++);
date = 1 + date - getDay(year, month);
// The `time` value specifies the time within the day (see ES
// 5.1 section 15.9.1.2). The formula `(A % B + B) % B` is used
// to compute `A modulo B`, as the `%` operator does not
// correspond to the `modulo` operation for negative numbers.
time = (value % 864e5 + 864e5) % 864e5;
// The hours, minutes, seconds, and milliseconds are obtained by
// decomposing the time within the day. See section 15.9.1.10.
hours = floor(time / 36e5) % 24;
minutes = floor(time / 6e4) % 60;
seconds = floor(time / 1e3) % 60;
milliseconds = time % 1e3;
} else {
year = value.getUTCFullYear();
month = value.getUTCMonth();
date = value.getUTCDate();
hours = value.getUTCHours();
minutes = value.getUTCMinutes();
seconds = value.getUTCSeconds();
milliseconds = value.getUTCMilliseconds();
}
// Serialize extended years correctly.
value = (year <= 0 || year >= 1e4 ? (year < 0 ? "-" : "+") + toPaddedString(6, year < 0 ? -year : year) : toPaddedString(4, year)) +
"-" + toPaddedString(2, month + 1) + "-" + toPaddedString(2, date) +
// Months, dates, hours, minutes, and seconds should have two
// digits; milliseconds should have three.
"T" + toPaddedString(2, hours) + ":" + toPaddedString(2, minutes) + ":" + toPaddedString(2, seconds) +
// Milliseconds are optional in ES 5.0, but required in 5.1.
"." + toPaddedString(3, milliseconds) + "Z";
} else {
value = null;
}
} else if (typeof value.toJSON == "function" && ((className != numberClass && className != stringClass && className != arrayClass) || isProperty.call(value, "toJSON"))) {
// Prototype <= 1.6.1 adds non-standard `toJSON` methods to the
// `Number`, `String`, `Date`, and `Array` prototypes. JSON 3
// ignores all `toJSON` methods on these objects unless they are
// defined directly on an instance.
value = value.toJSON(property);
}
}
if (callback) {
// If a replacement function was provided, call it to obtain the value
// for serialization.
value = callback.call(object, property, value);
}
if (value === null) {
return "null";
}
className = getClass.call(value);
if (className == booleanClass) {
// Booleans are represented literally.
return "" + value;
} else if (className == numberClass) {
// JSON numbers must be finite. `Infinity` and `NaN` are serialized as
// `"null"`.
return value > -1 / 0 && value < 1 / 0 ? "" + value : "null";
} else if (className == stringClass) {
// Strings are double-quoted and escaped.
return quote("" + value);
}
// Recursively serialize objects and arrays.
if (typeof value == "object") {
// Check for cyclic structures. This is a linear search; performance
// is inversely proportional to the number of unique nested objects.
for (length = stack.length; length--;) {
if (stack[length] === value) {
// Cyclic structures cannot be serialized by `JSON.stringify`.
throw TypeError();
}
}
// Add the object to the stack of traversed objects.
stack.push(value);
results = [];
// Save the current indentation level and indent one additional level.
prefix = indentation;
indentation += whitespace;
if (className == arrayClass) {
// Recursively serialize array elements.
for (index = 0, length = value.length; index < length; index++) {
element = serialize(index, value, callback, properties, whitespace, indentation, stack);
results.push(element === undef ? "null" : element);
}
result = results.length ? (whitespace ? "[\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "]" : ("[" + results.join(",") + "]")) : "[]";
} else {
// Recursively serialize object members. Members are selected from
// either a user-specified list of property names, or the object
// itself.
forEach(properties || value, function (property) {
var element = serialize(property, value, callback, properties, whitespace, indentation, stack);
if (element !== undef) {
// According to ES 5.1 section 15.12.3: "If `gap` {whitespace}
// is not the empty string, let `member` {quote(property) + ":"}
// be the concatenation of `member` and the `space` character."
// The "`space` character" refers to the literal space
// character, not the `space` {width} argument provided to
// `JSON.stringify`.
results.push(quote(property) + ":" + (whitespace ? " " : "") + element);
}
});
result = results.length ? (whitespace ? "{\n" + indentation + results.join(",\n" + indentation) + "\n" + prefix + "}" : ("{" + results.join(",") + "}")) : "{}";
}
// Remove the object from the traversed object stack.
stack.pop();
return result;
}
};
// Public: `JSON.stringify`. See ES 5.1 section 15.12.3.
exports.stringify = function (source, filter, width) {
var whitespace, callback, properties, className;
if (objectTypes[typeof filter] && filter) {
if ((className = getClass.call(filter)) == functionClass) {
callback = filter;
} else if (className == arrayClass) {
// Convert the property names array into a makeshift set.
properties = {};
for (var index = 0, length = filter.length, value; index < length; value = filter[index++], ((className = getClass.call(value)), className == stringClass || className == numberClass) && (properties[value] = 1));
}
}
if (width) {
if ((className = getClass.call(width)) == numberClass) {
// Convert the `width` to an integer and create a string containing
// `width` number of space characters.
if ((width -= width % 1) > 0) {
for (whitespace = "", width > 10 && (width = 10); whitespace.length < width; whitespace += " ");
}
} else if (className == stringClass) {
whitespace = width.length <= 10 ? width : width.slice(0, 10);
}
}
// Opera <= 7.54u2 discards the values associated with empty string keys
// (`""`) only if they are used directly within an object member list
// (e.g., `!("" in { "": 1})`).
return serialize("", (value = {}, value[""] = source, value), callback, properties, whitespace, "", []);
};
}
// Public: Parses a JSON source string.
if (!has("json-parse")) {
var fromCharCode = String.fromCharCode;
// Internal: A map of escaped control characters and their unescaped
// equivalents.
var Unescapes = {
92: "\\",
34: '"',
47: "/",
98: "\b",
116: "\t",
110: "\n",
102: "\f",
114: "\r"
};
// Internal: Stores the parser state.
var Index, Source;
// Internal: Resets the parser state and throws a `SyntaxError`.
var abort = function () {
Index = Source = null;
throw SyntaxError();
};
// Internal: Returns the next token, or `"$"` if the parser has reached
// the end of the source string. A token may be a string, number, `null`
// literal, or Boolean literal.
var lex = function () {
var source = Source, length = source.length, value, begin, position, isSigned, charCode;
while (Index < length) {
charCode = source.charCodeAt(Index);
switch (charCode) {
case 9: case 10: case 13: case 32:
// Skip whitespace tokens, including tabs, carriage returns, line
// feeds, and space characters.
Index++;
break;
case 123: case 125: case 91: case 93: case 58: case 44:
// Parse a punctuator token (`{`, `}`, `[`, `]`, `:`, or `,`) at
// the current position.
value = charIndexBuggy ? source.charAt(Index) : source[Index];
Index++;
return value;
case 34:
// `"` delimits a JSON string; advance to the next character and
// begin parsing the string. String tokens are prefixed with the
// sentinel `@` character to distinguish them from punctuators and
// end-of-string tokens.
for (value = "@", Index++; Index < length;) {
charCode = source.charCodeAt(Index);
if (charCode < 32) {
// Unescaped ASCII control characters (those with a code unit
// less than the space character) are not permitted.
abort();
} else if (charCode == 92) {
// A reverse solidus (`\`) marks the beginning of an escaped
// control character (including `"`, `\`, and `/`) or Unicode
// escape sequence.
charCode = source.charCodeAt(++Index);
switch (charCode) {
case 92: case 34: case 47: case 98: case 116: case 110: case 102: case 114:
// Revive escaped control characters.
value += Unescapes[charCode];
Index++;
break;
case 117:
// `\u` marks the beginning of a Unicode escape sequence.
// Advance to the first character and validate the
// four-digit code point.
begin = ++Index;
for (position = Index + 4; Index < position; Index++) {
charCode = source.charCodeAt(Index);
// A valid sequence comprises four hexdigits (case-
// insensitive) that form a single hexadecimal value.
if (!(charCode >= 48 && charCode <= 57 || charCode >= 97 && charCode <= 102 || charCode >= 65 && charCode <= 70)) {
// Invalid Unicode escape sequence.
abort();
}
}
// Revive the escaped character.
value += fromCharCode("0x" + source.slice(begin, Index));
break;
default:
// Invalid escape sequence.
abort();
}
} else {
if (charCode == 34) {
// An unescaped double-quote character marks the end of the
// string.
break;
}
charCode = source.charCodeAt(Index);
begin = Index;
// Optimize for the common case where a string is valid.
while (charCode >= 32 && charCode != 92 && charCode != 34) {
charCode = source.charCodeAt(++Index);
}
// Append the string as-is.
value += source.slice(begin, Index);
}
}
if (source.charCodeAt(Index) == 34) {
// Advance to the next character and return the revived string.
Index++;
return value;
}
// Unterminated string.
abort();
default:
// Parse numbers and literals.
begin = Index;
// Advance past the negative sign, if one is specified.
if (charCode == 45) {
isSigned = true;
charCode = source.charCodeAt(++Index);
}
// Parse an integer or floating-point value.
if (charCode >= 48 && charCode <= 57) {
// Leading zeroes are interpreted as octal literals.
if (charCode == 48 && ((charCode = source.charCodeAt(Index + 1)), charCode >= 48 && charCode <= 57)) {
// Illegal octal literal.
abort();
}
isSigned = false;
// Parse the integer component.
for (; Index < length && ((charCode = source.charCodeAt(Index)), charCode >= 48 && charCode <= 57); Index++);
// Floats cannot contain a leading decimal point; however, this
// case is already accounted for by the parser.
if (source.charCodeAt(Index) == 46) {
position = ++Index;
// Parse the decimal component.
for (; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);
if (position == Index) {
// Illegal trailing decimal.
abort();
}
Index = position;
}
// Parse exponents. The `e` denoting the exponent is
// case-insensitive.
charCode = source.charCodeAt(Index);
if (charCode == 101 || charCode == 69) {
charCode = source.charCodeAt(++Index);
// Skip past the sign following the exponent, if one is
// specified.
if (charCode == 43 || charCode == 45) {
Index++;
}
// Parse the exponential component.
for (position = Index; position < length && ((charCode = source.charCodeAt(position)), charCode >= 48 && charCode <= 57); position++);
if (position == Index) {
// Illegal empty exponent.
abort();
}
Index = position;
}
// Coerce the parsed value to a JavaScript number.
return +source.slice(begin, Index);
}
// A negative sign may only precede numbers.
if (isSigned) {
abort();
}
// `true`, `false`, and `null` literals.
if (source.slice(Index, Index + 4) == "true") {
Index += 4;
return true;
} else if (source.slice(Index, Index + 5) == "false") {
Index += 5;
return false;
} else if (source.slice(Index, Index + 4) == "null") {
Index += 4;
return null;
}
// Unrecognized token.
abort();
}
}
// Return the sentinel `$` character if the parser has reached the end
// of the source string.
return "$";
};
// Internal: Parses a JSON `value` token.
var get = function (value) {
var results, hasMembers;
if (value == "$") {
// Unexpected end of input.
abort();
}
if (typeof value == "string") {
if ((charIndexBuggy ? value.charAt(0) : value[0]) == "@") {
// Remove the sentinel `@` character.
return value.slice(1);
}
// Parse object and array literals.
if (value == "[") {
// Parses a JSON array, returning a new JavaScript array.
results = [];
for (;; hasMembers || (hasMembers = true)) {
value = lex();
// A closing square bracket marks the end of the array literal.
if (value == "]") {
break;
}
// If the array literal contains elements, the current token
// should be a comma separating the previous element from the
// next.
if (hasMembers) {
if (value == ",") {
value = lex();
if (value == "]") {
// Unexpected trailing `,` in array literal.
abort();
}
} else {
// A `,` must separate each array element.
abort();
}
}
// Elisions and leading commas are not permitted.
if (value == ",") {
abort();
}
results.push(get(value));
}
return results;
} else if (value == "{") {
// Parses a JSON object, returning a new JavaScript object.
results = {};
for (;; hasMembers || (hasMembers = true)) {
value = lex();
// A closing curly brace marks the end of the object literal.
if (value == "}") {
break;
}
// If the object literal contains members, the current token
// should be a comma separator.
if (hasMembers) {
if (value == ",") {
value = lex();
if (value == "}") {
// Unexpected trailing `,` in object literal.
abort();
}
} else {
// A `,` must separate each object member.
abort();
}
}
// Leading commas are not permitted, object property names must be
// double-quoted strings, and a `:` must separate each property
// name and value.
if (value == "," || typeof value != "string" || (charIndexBuggy ? value.charAt(0) : value[0]) != "@" || lex() != ":") {
abort();
}
results[value.slice(1)] = get(lex());
}
return results;
}
// Unexpected token encountered.
abort();
}
return value;
};
// Internal: Updates a traversed object member.
var update = function (source, property, callback) {
var element = walk(source, property, callback);
if (element === undef) {
delete source[property];
} else {
source[property] = element;
}
};
// Internal: Recursively traverses a parsed JSON object, invoking the
// `callback` function for each value. This is an implementation of the
// `Walk(holder, name)` operation defined in ES 5.1 section 15.12.2.
var walk = function (source, property, callback) {
var value = source[property], length;
if (typeof value == "object" && value) {
// `forEach` can't be used to traverse an array in Opera <= 8.54
// because its `Object#hasOwnProperty` implementation returns `false`
// for array indices (e.g., `![1, 2, 3].hasOwnProperty("0")`).
if (getClass.call(value) == arrayClass) {
for (length = value.length; length--;) {
update(value, length, callback);
}
} else {
forEach(value, function (property) {
update(value, property, callback);
});
}
}
return callback.call(source, property, value);
};
// Public: `JSON.parse`. See ES 5.1 section 15.12.2.
exports.parse = function (source, callback) {
var result, value;
Index = 0;
Source = "" + source;
result = get(lex());
// If a JSON string contains multiple tokens, it is invalid.
if (lex() != "$") {
abort();
}
// Reset the parser state.
Index = Source = null;
return callback && getClass.call(callback) == functionClass ? walk((value = {}, value[""] = result, value), "", callback) : result;
};
}
}
exports["runInContext"] = runInContext;
return exports;
}
if (freeExports && !isLoader) {
// Export for CommonJS environments.
runInContext(root, freeExports);
} else {
// Export for web browsers and JavaScript engines.
var nativeJSON = root.JSON,
previousJSON = root["JSON3"],
isRestored = false;
var JSON3 = runInContext(root, (root["JSON3"] = {
// Public: Restores the original value of the global `JSON` object and
// returns a reference to the `JSON3` object.
"noConflict": function () {
if (!isRestored) {
isRestored = true;
root.JSON = nativeJSON;
root["JSON3"] = previousJSON;
nativeJSON = previousJSON = null;
}
return JSON3;
}
}));
root.JSON = {
"parse": JSON3.parse,
"stringify": JSON3.stringify
};
}
// Export for asynchronous module loaders.
if (isLoader) {
define(function () {
return JSON3;
});
}
}).call(this);

View File

@@ -0,0 +1,270 @@
@charset "utf-8";
body {
margin:0;
}
#mocha {
font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
margin: 60px 50px;
}
#mocha ul,
#mocha li {
margin: 0;
padding: 0;
}
#mocha ul {
list-style: none;
}
#mocha h1,
#mocha h2 {
margin: 0;
}
#mocha h1 {
margin-top: 15px;
font-size: 1em;
font-weight: 200;
}
#mocha h1 a {
text-decoration: none;
color: inherit;
}
#mocha h1 a:hover {
text-decoration: underline;
}
#mocha .suite .suite h1 {
margin-top: 0;
font-size: .8em;
}
#mocha .hidden {
display: none;
}
#mocha h2 {
font-size: 12px;
font-weight: normal;
cursor: pointer;
}
#mocha .suite {
margin-left: 15px;
}
#mocha .test {
margin-left: 15px;
overflow: hidden;
}
#mocha .test.pending:hover h2::after {
content: '(pending)';
font-family: arial, sans-serif;
}
#mocha .test.pass.medium .duration {
background: #c09853;
}
#mocha .test.pass.slow .duration {
background: #b94a48;
}
#mocha .test.pass::before {
content: '✓';
font-size: 12px;
display: block;
float: left;
margin-right: 5px;
color: #00d6b2;
}
#mocha .test.pass .duration {
font-size: 9px;
margin-left: 5px;
padding: 2px 5px;
color: #fff;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
-webkit-border-radius: 5px;
-moz-border-radius: 5px;
-ms-border-radius: 5px;
-o-border-radius: 5px;
border-radius: 5px;
}
#mocha .test.pass.fast .duration {
display: none;
}
#mocha .test.pending {
color: #0b97c4;
}
#mocha .test.pending::before {
content: '◦';
color: #0b97c4;
}
#mocha .test.fail {
color: #c00;
}
#mocha .test.fail pre {
color: black;
}
#mocha .test.fail::before {
content: '✖';
font-size: 12px;
display: block;
float: left;
margin-right: 5px;
color: #c00;
}
#mocha .test pre.error {
color: #c00;
max-height: 300px;
overflow: auto;
}
/**
* (1): approximate for browsers not supporting calc
* (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)
* ^^ seriously
*/
#mocha .test pre {
display: block;
float: left;
clear: left;
font: 12px/1.5 monaco, monospace;
margin: 5px;
padding: 15px;
border: 1px solid #eee;
max-width: 85%; /*(1)*/
max-width: calc(100% - 42px); /*(2)*/
word-wrap: break-word;
border-bottom-color: #ddd;
-webkit-border-radius: 3px;
-webkit-box-shadow: 0 1px 3px #eee;
-moz-border-radius: 3px;
-moz-box-shadow: 0 1px 3px #eee;
border-radius: 3px;
}
#mocha .test h2 {
position: relative;
}
#mocha .test a.replay {
position: absolute;
top: 3px;
right: 0;
text-decoration: none;
vertical-align: middle;
display: block;
width: 15px;
height: 15px;
line-height: 15px;
text-align: center;
background: #eee;
font-size: 15px;
-moz-border-radius: 15px;
border-radius: 15px;
-webkit-transition: opacity 200ms;
-moz-transition: opacity 200ms;
transition: opacity 200ms;
opacity: 0.3;
color: #888;
}
#mocha .test:hover a.replay {
opacity: 1;
}
#mocha-report.pass .test.fail {
display: none;
}
#mocha-report.fail .test.pass {
display: none;
}
#mocha-report.pending .test.pass,
#mocha-report.pending .test.fail {
display: none;
}
#mocha-report.pending .test.pass.pending {
display: block;
}
#mocha-error {
color: #c00;
font-size: 1.5em;
font-weight: 100;
letter-spacing: 1px;
}
#mocha-stats {
position: fixed;
top: 15px;
right: 10px;
font-size: 12px;
margin: 0;
color: #888;
z-index: 1;
}
#mocha-stats .progress {
float: right;
padding-top: 0;
}
#mocha-stats em {
color: black;
}
#mocha-stats a {
text-decoration: none;
color: inherit;
}
#mocha-stats a:hover {
border-bottom: 1px solid #eee;
}
#mocha-stats li {
display: inline-block;
margin: 0 5px;
list-style: none;
padding-top: 11px;
}
#mocha-stats canvas {
width: 40px;
height: 40px;
}
#mocha code .comment { color: #ddd; }
#mocha code .init { color: #2f6fad; }
#mocha code .string { color: #5890ad; }
#mocha code .keyword { color: #8a6343; }
#mocha code .number { color: #2f6fad; }
@media screen and (max-device-width: 480px) {
#mocha {
margin: 60px 0px;
}
#mocha #stats {
position: absolute;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,16 @@
importScripts('es6-promise.js');
new ES6Promise.Promise(function(resolve, reject) {
self.onmessage = function (e) {
if (e.data === 'ping') {
resolve('pong');
} else {
reject(new Error('wrong message'));
}
};
}).then(function (result) {
self.postMessage(result);
}, function (err){
setTimeout(function () {
throw err;
});
});

View File

@@ -0,0 +1,18 @@
import Promise from './es6-promise/promise';
import polyfill from './es6-promise/polyfill';
var ES6Promise = {
'Promise': Promise,
'polyfill': polyfill
};
/* global define:true module:true window: true */
if (typeof define === 'function' && define['amd']) {
define(function() { return ES6Promise; });
} else if (typeof module !== 'undefined' && module['exports']) {
module['exports'] = ES6Promise;
} else if (typeof this !== 'undefined') {
this['ES6Promise'] = ES6Promise;
}
polyfill();

View File

@@ -0,0 +1,252 @@
import {
objectOrFunction,
isFunction
} from './utils';
import {
asap
} from './asap';
function noop() {}
var PENDING = void 0;
var FULFILLED = 1;
var REJECTED = 2;
var GET_THEN_ERROR = new ErrorObject();
function selfFullfillment() {
return new TypeError("You cannot resolve a promise with itself");
}
function cannotReturnOwn() {
return new TypeError('A promises callback cannot return that same promise.');
}
function getThen(promise) {
try {
return promise.then;
} catch(error) {
GET_THEN_ERROR.error = error;
return GET_THEN_ERROR;
}
}
function tryThen(then, value, fulfillmentHandler, rejectionHandler) {
try {
then.call(value, fulfillmentHandler, rejectionHandler);
} catch(e) {
return e;
}
}
function handleForeignThenable(promise, thenable, then) {
asap(function(promise) {
var sealed = false;
var error = tryThen(then, thenable, function(value) {
if (sealed) { return; }
sealed = true;
if (thenable !== value) {
resolve(promise, value);
} else {
fulfill(promise, value);
}
}, function(reason) {
if (sealed) { return; }
sealed = true;
reject(promise, reason);
}, 'Settle: ' + (promise._label || ' unknown promise'));
if (!sealed && error) {
sealed = true;
reject(promise, error);
}
}, promise);
}
function handleOwnThenable(promise, thenable) {
if (thenable._state === FULFILLED) {
fulfill(promise, thenable._result);
} else if (thenable._state === REJECTED) {
reject(promise, thenable._result);
} else {
subscribe(thenable, undefined, function(value) {
resolve(promise, value);
}, function(reason) {
reject(promise, reason);
});
}
}
function handleMaybeThenable(promise, maybeThenable) {
if (maybeThenable.constructor === promise.constructor) {
handleOwnThenable(promise, maybeThenable);
} else {
var then = getThen(maybeThenable);
if (then === GET_THEN_ERROR) {
reject(promise, GET_THEN_ERROR.error);
} else if (then === undefined) {
fulfill(promise, maybeThenable);
} else if (isFunction(then)) {
handleForeignThenable(promise, maybeThenable, then);
} else {
fulfill(promise, maybeThenable);
}
}
}
function resolve(promise, value) {
if (promise === value) {
reject(promise, selfFullfillment());
} else if (objectOrFunction(value)) {
handleMaybeThenable(promise, value);
} else {
fulfill(promise, value);
}
}
function publishRejection(promise) {
if (promise._onerror) {
promise._onerror(promise._result);
}
publish(promise);
}
function fulfill(promise, value) {
if (promise._state !== PENDING) { return; }
promise._result = value;
promise._state = FULFILLED;
if (promise._subscribers.length !== 0) {
asap(publish, promise);
}
}
function reject(promise, reason) {
if (promise._state !== PENDING) { return; }
promise._state = REJECTED;
promise._result = reason;
asap(publishRejection, promise);
}
function subscribe(parent, child, onFulfillment, onRejection) {
var subscribers = parent._subscribers;
var length = subscribers.length;
parent._onerror = null;
subscribers[length] = child;
subscribers[length + FULFILLED] = onFulfillment;
subscribers[length + REJECTED] = onRejection;
if (length === 0 && parent._state) {
asap(publish, parent);
}
}
function publish(promise) {
var subscribers = promise._subscribers;
var settled = promise._state;
if (subscribers.length === 0) { return; }
var child, callback, detail = promise._result;
for (var i = 0; i < subscribers.length; i += 3) {
child = subscribers[i];
callback = subscribers[i + settled];
if (child) {
invokeCallback(settled, child, callback, detail);
} else {
callback(detail);
}
}
promise._subscribers.length = 0;
}
function ErrorObject() {
this.error = null;
}
var TRY_CATCH_ERROR = new ErrorObject();
function tryCatch(callback, detail) {
try {
return callback(detail);
} catch(e) {
TRY_CATCH_ERROR.error = e;
return TRY_CATCH_ERROR;
}
}
function invokeCallback(settled, promise, callback, detail) {
var hasCallback = isFunction(callback),
value, error, succeeded, failed;
if (hasCallback) {
value = tryCatch(callback, detail);
if (value === TRY_CATCH_ERROR) {
failed = true;
error = value.error;
value = null;
} else {
succeeded = true;
}
if (promise === value) {
reject(promise, cannotReturnOwn());
return;
}
} else {
value = detail;
succeeded = true;
}
if (promise._state !== PENDING) {
// noop
} else if (hasCallback && succeeded) {
resolve(promise, value);
} else if (failed) {
reject(promise, error);
} else if (settled === FULFILLED) {
fulfill(promise, value);
} else if (settled === REJECTED) {
reject(promise, value);
}
}
function initializePromise(promise, resolver) {
try {
resolver(function resolvePromise(value){
resolve(promise, value);
}, function rejectPromise(reason) {
reject(promise, reason);
});
} catch(e) {
reject(promise, e);
}
}
export {
noop,
resolve,
reject,
fulfill,
subscribe,
publish,
publishRejection,
initializePromise,
invokeCallback,
FULFILLED,
REJECTED,
PENDING
};

View File

@@ -0,0 +1,125 @@
var len = 0;
var toString = {}.toString;
var vertxNext;
var customSchedulerFn;
export var asap = function asap(callback, arg) {
queue[len] = callback;
queue[len + 1] = arg;
len += 2;
if (len === 2) {
// If len is 2, that means that we need to schedule an async flush.
// If additional callbacks are queued before the queue is flushed, they
// will be processed by this flush that we are scheduling.
if (customSchedulerFn) {
customSchedulerFn(flush);
} else {
scheduleFlush();
}
}
}
export function setScheduler(scheduleFn) {
customSchedulerFn = scheduleFn;
}
export function setAsap(asapFn) {
asap = asapFn;
}
var browserWindow = (typeof window !== 'undefined') ? window : undefined;
var browserGlobal = browserWindow || {};
var BrowserMutationObserver = browserGlobal.MutationObserver || browserGlobal.WebKitMutationObserver;
var isNode = typeof process !== 'undefined' && {}.toString.call(process) === '[object process]';
// test for web worker but not in IE10
var isWorker = typeof Uint8ClampedArray !== 'undefined' &&
typeof importScripts !== 'undefined' &&
typeof MessageChannel !== 'undefined';
// node
function useNextTick() {
var nextTick = process.nextTick;
// node version 0.10.x displays a deprecation warning when nextTick is used recursively
// setImmediate should be used instead instead
var version = process.versions.node.match(/^(?:(\d+)\.)?(?:(\d+)\.)?(\*|\d+)$/);
if (Array.isArray(version) && version[1] === '0' && version[2] === '10') {
nextTick = setImmediate;
}
return function() {
nextTick(flush);
};
}
// vertx
function useVertxTimer() {
return function() {
vertxNext(flush);
};
}
function useMutationObserver() {
var iterations = 0;
var observer = new BrowserMutationObserver(flush);
var node = document.createTextNode('');
observer.observe(node, { characterData: true });
return function() {
node.data = (iterations = ++iterations % 2);
};
}
// web worker
function useMessageChannel() {
var channel = new MessageChannel();
channel.port1.onmessage = flush;
return function () {
channel.port2.postMessage(0);
};
}
function useSetTimeout() {
return function() {
setTimeout(flush, 1);
};
}
var queue = new Array(1000);
function flush() {
for (var i = 0; i < len; i+=2) {
var callback = queue[i];
var arg = queue[i+1];
callback(arg);
queue[i] = undefined;
queue[i+1] = undefined;
}
len = 0;
}
function attemptVertex() {
try {
var r = require;
var vertx = r('vertx');
vertxNext = vertx.runOnLoop || vertx.runOnContext;
return useVertxTimer();
} catch(e) {
return useSetTimeout();
}
}
var scheduleFlush;
// Decide what async method to use to triggering processing of queued callbacks:
if (isNode) {
scheduleFlush = useNextTick();
} else if (BrowserMutationObserver) {
scheduleFlush = useMutationObserver();
} else if (isWorker) {
scheduleFlush = useMessageChannel();
} else if (browserWindow === undefined && typeof require === 'function') {
scheduleFlush = attemptVertex();
} else {
scheduleFlush = useSetTimeout();
}

View File

@@ -0,0 +1,113 @@
import {
isArray,
isMaybeThenable
} from './utils';
import {
noop,
reject,
fulfill,
subscribe,
FULFILLED,
REJECTED,
PENDING
} from './-internal';
function Enumerator(Constructor, input) {
var enumerator = this;
enumerator._instanceConstructor = Constructor;
enumerator.promise = new Constructor(noop);
if (enumerator._validateInput(input)) {
enumerator._input = input;
enumerator.length = input.length;
enumerator._remaining = input.length;
enumerator._init();
if (enumerator.length === 0) {
fulfill(enumerator.promise, enumerator._result);
} else {
enumerator.length = enumerator.length || 0;
enumerator._enumerate();
if (enumerator._remaining === 0) {
fulfill(enumerator.promise, enumerator._result);
}
}
} else {
reject(enumerator.promise, enumerator._validationError());
}
}
Enumerator.prototype._validateInput = function(input) {
return isArray(input);
};
Enumerator.prototype._validationError = function() {
return new Error('Array Methods must be provided an Array');
};
Enumerator.prototype._init = function() {
this._result = new Array(this.length);
};
export default Enumerator;
Enumerator.prototype._enumerate = function() {
var enumerator = this;
var length = enumerator.length;
var promise = enumerator.promise;
var input = enumerator._input;
for (var i = 0; promise._state === PENDING && i < length; i++) {
enumerator._eachEntry(input[i], i);
}
};
Enumerator.prototype._eachEntry = function(entry, i) {
var enumerator = this;
var c = enumerator._instanceConstructor;
if (isMaybeThenable(entry)) {
if (entry.constructor === c && entry._state !== PENDING) {
entry._onerror = null;
enumerator._settledAt(entry._state, i, entry._result);
} else {
enumerator._willSettleAt(c.resolve(entry), i);
}
} else {
enumerator._remaining--;
enumerator._result[i] = entry;
}
};
Enumerator.prototype._settledAt = function(state, i, value) {
var enumerator = this;
var promise = enumerator.promise;
if (promise._state === PENDING) {
enumerator._remaining--;
if (state === REJECTED) {
reject(promise, value);
} else {
enumerator._result[i] = value;
}
}
if (enumerator._remaining === 0) {
fulfill(promise, enumerator._result);
}
};
Enumerator.prototype._willSettleAt = function(promise, i) {
var enumerator = this;
subscribe(promise, undefined, function(value) {
enumerator._settledAt(FULFILLED, i, value);
}, function(reason) {
enumerator._settledAt(REJECTED, i, reason);
});
};

View File

@@ -0,0 +1,26 @@
/*global self*/
import Promise from './promise';
export default function polyfill() {
var local;
if (typeof global !== 'undefined') {
local = global;
} else if (typeof self !== 'undefined') {
local = self;
} else {
try {
local = Function('return this')();
} catch (e) {
throw new Error('polyfill failed because global object is unavailable in this environment');
}
}
var P = local.Promise;
if (P && Object.prototype.toString.call(P.resolve()) === '[object Promise]' && !P.cast) {
return;
}
local.Promise = Promise;
}

View File

@@ -0,0 +1,415 @@
import {
isFunction
} from './utils';
import {
noop,
subscribe,
initializePromise,
invokeCallback,
FULFILLED,
REJECTED
} from './-internal';
import {
asap,
setAsap,
setScheduler
} from './asap';
import all from './promise/all';
import race from './promise/race';
import Resolve from './promise/resolve';
import Reject from './promise/reject';
var counter = 0;
function needsResolver() {
throw new TypeError('You must pass a resolver function as the first argument to the promise constructor');
}
function needsNew() {
throw new TypeError("Failed to construct 'Promise': Please use the 'new' operator, this object constructor cannot be called as a function.");
}
export default Promise;
/**
Promise objects represent the eventual result of an asynchronous operation. The
primary way of interacting with a promise is through its `then` method, which
registers callbacks to receive either a promise's eventual value or the reason
why the promise cannot be fulfilled.
Terminology
-----------
- `promise` is an object or function with a `then` method whose behavior conforms to this specification.
- `thenable` is an object or function that defines a `then` method.
- `value` is any legal JavaScript value (including undefined, a thenable, or a promise).
- `exception` is a value that is thrown using the throw statement.
- `reason` is a value that indicates why a promise was rejected.
- `settled` the final resting state of a promise, fulfilled or rejected.
A promise can be in one of three states: pending, fulfilled, or rejected.
Promises that are fulfilled have a fulfillment value and are in the fulfilled
state. Promises that are rejected have a rejection reason and are in the
rejected state. A fulfillment value is never a thenable.
Promises can also be said to *resolve* a value. If this value is also a
promise, then the original promise's settled state will match the value's
settled state. So a promise that *resolves* a promise that rejects will
itself reject, and a promise that *resolves* a promise that fulfills will
itself fulfill.
Basic Usage:
------------
```js
var promise = new Promise(function(resolve, reject) {
// on success
resolve(value);
// on failure
reject(reason);
});
promise.then(function(value) {
// on fulfillment
}, function(reason) {
// on rejection
});
```
Advanced Usage:
---------------
Promises shine when abstracting away asynchronous interactions such as
`XMLHttpRequest`s.
```js
function getJSON(url) {
return new Promise(function(resolve, reject){
var xhr = new XMLHttpRequest();
xhr.open('GET', url);
xhr.onreadystatechange = handler;
xhr.responseType = 'json';
xhr.setRequestHeader('Accept', 'application/json');
xhr.send();
function handler() {
if (this.readyState === this.DONE) {
if (this.status === 200) {
resolve(this.response);
} else {
reject(new Error('getJSON: `' + url + '` failed with status: [' + this.status + ']'));
}
}
};
});
}
getJSON('/posts.json').then(function(json) {
// on fulfillment
}, function(reason) {
// on rejection
});
```
Unlike callbacks, promises are great composable primitives.
```js
Promise.all([
getJSON('/posts'),
getJSON('/comments')
]).then(function(values){
values[0] // => postsJSON
values[1] // => commentsJSON
return values;
});
```
@class Promise
@param {function} resolver
Useful for tooling.
@constructor
*/
function Promise(resolver) {
this._id = counter++;
this._state = undefined;
this._result = undefined;
this._subscribers = [];
if (noop !== resolver) {
if (!isFunction(resolver)) {
needsResolver();
}
if (!(this instanceof Promise)) {
needsNew();
}
initializePromise(this, resolver);
}
}
Promise.all = all;
Promise.race = race;
Promise.resolve = Resolve;
Promise.reject = Reject;
Promise._setScheduler = setScheduler;
Promise._setAsap = setAsap;
Promise._asap = asap;
Promise.prototype = {
constructor: Promise,
/**
The primary way of interacting with a promise is through its `then` method,
which registers callbacks to receive either a promise's eventual value or the
reason why the promise cannot be fulfilled.
```js
findUser().then(function(user){
// user is available
}, function(reason){
// user is unavailable, and you are given the reason why
});
```
Chaining
--------
The return value of `then` is itself a promise. This second, 'downstream'
promise is resolved with the return value of the first promise's fulfillment
or rejection handler, or rejected if the handler throws an exception.
```js
findUser().then(function (user) {
return user.name;
}, function (reason) {
return 'default name';
}).then(function (userName) {
// If `findUser` fulfilled, `userName` will be the user's name, otherwise it
// will be `'default name'`
});
findUser().then(function (user) {
throw new Error('Found user, but still unhappy');
}, function (reason) {
throw new Error('`findUser` rejected and we're unhappy');
}).then(function (value) {
// never reached
}, function (reason) {
// if `findUser` fulfilled, `reason` will be 'Found user, but still unhappy'.
// If `findUser` rejected, `reason` will be '`findUser` rejected and we're unhappy'.
});
```
If the downstream promise does not specify a rejection handler, rejection reasons will be propagated further downstream.
```js
findUser().then(function (user) {
throw new PedagogicalException('Upstream error');
}).then(function (value) {
// never reached
}).then(function (value) {
// never reached
}, function (reason) {
// The `PedgagocialException` is propagated all the way down to here
});
```
Assimilation
------------
Sometimes the value you want to propagate to a downstream promise can only be
retrieved asynchronously. This can be achieved by returning a promise in the
fulfillment or rejection handler. The downstream promise will then be pending
until the returned promise is settled. This is called *assimilation*.
```js
findUser().then(function (user) {
return findCommentsByAuthor(user);
}).then(function (comments) {
// The user's comments are now available
});
```
If the assimliated promise rejects, then the downstream promise will also reject.
```js
findUser().then(function (user) {
return findCommentsByAuthor(user);
}).then(function (comments) {
// If `findCommentsByAuthor` fulfills, we'll have the value here
}, function (reason) {
// If `findCommentsByAuthor` rejects, we'll have the reason here
});
```
Simple Example
--------------
Synchronous Example
```javascript
var result;
try {
result = findResult();
// success
} catch(reason) {
// failure
}
```
Errback Example
```js
findResult(function(result, err){
if (err) {
// failure
} else {
// success
}
});
```
Promise Example;
```javascript
findResult().then(function(result){
// success
}, function(reason){
// failure
});
```
Advanced Example
--------------
Synchronous Example
```javascript
var author, books;
try {
author = findAuthor();
books = findBooksByAuthor(author);
// success
} catch(reason) {
// failure
}
```
Errback Example
```js
function foundBooks(books) {
}
function failure(reason) {
}
findAuthor(function(author, err){
if (err) {
failure(err);
// failure
} else {
try {
findBoooksByAuthor(author, function(books, err) {
if (err) {
failure(err);
} else {
try {
foundBooks(books);
} catch(reason) {
failure(reason);
}
}
});
} catch(error) {
failure(err);
}
// success
}
});
```
Promise Example;
```javascript
findAuthor().
then(findBooksByAuthor).
then(function(books){
// found books
}).catch(function(reason){
// something went wrong
});
```
@method then
@param {Function} onFulfilled
@param {Function} onRejected
Useful for tooling.
@return {Promise}
*/
then: function(onFulfillment, onRejection) {
var parent = this;
var state = parent._state;
if (state === FULFILLED && !onFulfillment || state === REJECTED && !onRejection) {
return this;
}
var child = new this.constructor(noop);
var result = parent._result;
if (state) {
var callback = arguments[state - 1];
asap(function(){
invokeCallback(state, child, callback, result);
});
} else {
subscribe(parent, child, onFulfillment, onRejection);
}
return child;
},
/**
`catch` is simply sugar for `then(undefined, onRejection)` which makes it the same
as the catch block of a try/catch statement.
```js
function findAuthor(){
throw new Error('couldn't find that author');
}
// synchronous
try {
findAuthor();
} catch(reason) {
// something went wrong
}
// async with promises
findAuthor().catch(function(reason){
// something went wrong
});
```
@method catch
@param {Function} onRejection
Useful for tooling.
@return {Promise}
*/
'catch': function(onRejection) {
return this.then(null, onRejection);
}
};

View File

@@ -0,0 +1,52 @@
import Enumerator from '../enumerator';
/**
`Promise.all` accepts an array of promises, and returns a new promise which
is fulfilled with an array of fulfillment values for the passed promises, or
rejected with the reason of the first passed promise to be rejected. It casts all
elements of the passed iterable to promises as it runs this algorithm.
Example:
```javascript
var promise1 = resolve(1);
var promise2 = resolve(2);
var promise3 = resolve(3);
var promises = [ promise1, promise2, promise3 ];
Promise.all(promises).then(function(array){
// The array here would be [ 1, 2, 3 ];
});
```
If any of the `promises` given to `all` are rejected, the first promise
that is rejected will be given as an argument to the returned promises's
rejection handler. For example:
Example:
```javascript
var promise1 = resolve(1);
var promise2 = reject(new Error("2"));
var promise3 = reject(new Error("3"));
var promises = [ promise1, promise2, promise3 ];
Promise.all(promises).then(function(array){
// Code here never runs because there are rejected promises!
}, function(error) {
// error.message === "2"
});
```
@method all
@static
@param {Array} entries array of promises
@param {String} label optional string for labeling the promise.
Useful for tooling.
@return {Promise} promise that is fulfilled when all `promises` have been
fulfilled, or rejected if any of them become rejected.
@static
*/
export default function all(entries) {
return new Enumerator(this, entries).promise;
}

View File

@@ -0,0 +1,104 @@
import {
isArray
} from "../utils";
import {
noop,
resolve,
reject,
subscribe,
PENDING
} from '../-internal';
/**
`Promise.race` returns a new promise which is settled in the same way as the
first passed promise to settle.
Example:
```javascript
var promise1 = new Promise(function(resolve, reject){
setTimeout(function(){
resolve('promise 1');
}, 200);
});
var promise2 = new Promise(function(resolve, reject){
setTimeout(function(){
resolve('promise 2');
}, 100);
});
Promise.race([promise1, promise2]).then(function(result){
// result === 'promise 2' because it was resolved before promise1
// was resolved.
});
```
`Promise.race` is deterministic in that only the state of the first
settled promise matters. For example, even if other promises given to the
`promises` array argument are resolved, but the first settled promise has
become rejected before the other promises became fulfilled, the returned
promise will become rejected:
```javascript
var promise1 = new Promise(function(resolve, reject){
setTimeout(function(){
resolve('promise 1');
}, 200);
});
var promise2 = new Promise(function(resolve, reject){
setTimeout(function(){
reject(new Error('promise 2'));
}, 100);
});
Promise.race([promise1, promise2]).then(function(result){
// Code here never runs
}, function(reason){
// reason.message === 'promise 2' because promise 2 became rejected before
// promise 1 became fulfilled
});
```
An example real-world use case is implementing timeouts:
```javascript
Promise.race([ajax('foo.json'), timeout(5000)])
```
@method race
@static
@param {Array} promises array of promises to observe
Useful for tooling.
@return {Promise} a promise which settles in the same way as the first passed
promise to settle.
*/
export default function race(entries) {
/*jshint validthis:true */
var Constructor = this;
var promise = new Constructor(noop);
if (!isArray(entries)) {
reject(promise, new TypeError('You must pass an array to race.'));
return promise;
}
var length = entries.length;
function onFulfillment(value) {
resolve(promise, value);
}
function onRejection(reason) {
reject(promise, reason);
}
for (var i = 0; promise._state === PENDING && i < length; i++) {
subscribe(Constructor.resolve(entries[i]), undefined, onFulfillment, onRejection);
}
return promise;
}

View File

@@ -0,0 +1,46 @@
import {
noop,
reject as _reject
} from '../-internal';
/**
`Promise.reject` returns a promise rejected with the passed `reason`.
It is shorthand for the following:
```javascript
var promise = new Promise(function(resolve, reject){
reject(new Error('WHOOPS'));
});
promise.then(function(value){
// Code here doesn't run because the promise is rejected!
}, function(reason){
// reason.message === 'WHOOPS'
});
```
Instead of writing the above, your code now simply becomes the following:
```javascript
var promise = Promise.reject(new Error('WHOOPS'));
promise.then(function(value){
// Code here doesn't run because the promise is rejected!
}, function(reason){
// reason.message === 'WHOOPS'
});
```
@method reject
@static
@param {Any} reason value that the returned promise will be rejected with.
Useful for tooling.
@return {Promise} a promise rejected with the given `reason`.
*/
export default function reject(reason) {
/*jshint validthis:true */
var Constructor = this;
var promise = new Constructor(noop);
_reject(promise, reason);
return promise;
}

View File

@@ -0,0 +1,48 @@
import {
noop,
resolve as _resolve
} from '../-internal';
/**
`Promise.resolve` returns a promise that will become resolved with the
passed `value`. It is shorthand for the following:
```javascript
var promise = new Promise(function(resolve, reject){
resolve(1);
});
promise.then(function(value){
// value === 1
});
```
Instead of writing the above, your code now simply becomes the following:
```javascript
var promise = Promise.resolve(1);
promise.then(function(value){
// value === 1
});
```
@method resolve
@static
@param {Any} value value that the returned promise will be resolved with
Useful for tooling.
@return {Promise} a promise that will become fulfilled with the given
`value`
*/
export default function resolve(object) {
/*jshint validthis:true */
var Constructor = this;
if (object && typeof object === 'object' && object.constructor === Constructor) {
return object;
}
var promise = new Constructor(noop);
_resolve(promise, object);
return promise;
}

View File

@@ -0,0 +1,22 @@
export function objectOrFunction(x) {
return typeof x === 'function' || (typeof x === 'object' && x !== null);
}
export function isFunction(x) {
return typeof x === 'function';
}
export function isMaybeThenable(x) {
return typeof x === 'object' && x !== null;
}
var _isArray;
if (!Array.isArray) {
_isArray = function (x) {
return Object.prototype.toString.call(x) === '[object Array]';
};
} else {
_isArray = Array.isArray;
}
export var isArray = _isArray;

View File

@@ -0,0 +1,92 @@
{
"_from": "es6-promise@^2.1.0",
"_id": "es6-promise@2.3.0",
"_inBundle": false,
"_integrity": "sha1-lu258v2wGZWCKyY92KratnSBgbw=",
"_location": "/vulcanize/es6-promise",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "es6-promise@^2.1.0",
"name": "es6-promise",
"escapedName": "es6-promise",
"rawSpec": "^2.1.0",
"saveSpec": null,
"fetchSpec": "^2.1.0"
},
"_requiredBy": [
"/vulcanize"
],
"_resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-2.3.0.tgz",
"_shasum": "96edb9f2fdb01995822b263dd8aadab6748181bc",
"_spec": "es6-promise@^2.1.0",
"_where": "/Users/asciidisco/Desktop/asciidisco.com/build/node_modules/vulcanize",
"author": {
"name": "Yehuda Katz, Tom Dale, Stefan Penner and contributors",
"url": "Conversion to ES6 API by Jake Archibald"
},
"browser": {
"vertx": false
},
"bugs": {
"url": "https://github.com/jakearchibald/ES6-Promises/issues"
},
"bundleDependencies": false,
"deprecated": false,
"description": "A lightweight library that provides tools for organizing asynchronous code",
"devDependencies": {
"bower": "^1.3.9",
"brfs": "0.0.8",
"broccoli-es3-safe-recast": "0.0.8",
"broccoli-es6-module-transpiler": "^0.5.0",
"broccoli-jshint": "^0.5.1",
"broccoli-merge-trees": "^0.1.4",
"broccoli-replace": "^0.2.0",
"broccoli-stew": "0.0.6",
"broccoli-uglify-js": "^0.1.3",
"broccoli-watchify": "^0.2.0",
"ember-cli": "0.2.3",
"ember-publisher": "0.0.7",
"git-repo-version": "0.0.2",
"json3": "^3.3.2",
"minimatch": "^2.0.1",
"mocha": "^1.20.1",
"promises-aplus-tests-phantom": "^2.1.0-revise",
"release-it": "0.0.10"
},
"directories": {
"lib": "lib"
},
"files": [
"dist",
"lib"
],
"homepage": "https://github.com/jakearchibald/ES6-Promises#readme",
"keywords": [
"promises",
"futures"
],
"license": "MIT",
"main": "dist/es6-promise.js",
"name": "es6-promise",
"namespace": "es6-promise",
"repository": {
"type": "git",
"url": "git://github.com/jakearchibald/ES6-Promises.git"
},
"scripts": {
"build": "ember build",
"dry-run-release": "ember build --environment production && release-it --dry-run --non-interactive",
"lint": "jshint lib",
"prepublish": "ember build --environment production",
"start": "ember s",
"test": "ember test",
"test:node": "ember build && mocha ./dist/test/browserify",
"test:server": "ember test --server"
},
"spm": {
"main": "dist/es6-promise.js"
},
"version": "2.3.0"
}

69
build/node_modules/vulcanize/package.json generated vendored Normal file
View File

@@ -0,0 +1,69 @@
{
"_from": "vulcanize@^1.13.1",
"_id": "vulcanize@1.16.0",
"_inBundle": false,
"_integrity": "sha512-TYlFljSc896b5+0FmMiw0JAMrHNBiHx0IAFC/dQR3Dxdb9Nx43ohm6wMWTlPXQn4sk/0WkqfgoAA6SLxyvPCLQ==",
"_location": "/vulcanize",
"_phantomChildren": {},
"_requested": {
"type": "range",
"registry": true,
"raw": "vulcanize@^1.13.1",
"name": "vulcanize",
"escapedName": "vulcanize",
"rawSpec": "^1.13.1",
"saveSpec": null,
"fetchSpec": "^1.13.1"
},
"_requiredBy": [
"/http2-push-manifest"
],
"_resolved": "https://registry.npmjs.org/vulcanize/-/vulcanize-1.16.0.tgz",
"_shasum": "b0ce3b0044d194ad4908ae4f1a6c6110a6e4d5e6",
"_spec": "vulcanize@^1.13.1",
"_where": "/Users/asciidisco/Desktop/asciidisco.com/build/node_modules/http2-push-manifest",
"author": {
"name": "The Polymer Project Authors"
},
"bin": {
"vulcanize": "bin/vulcanize"
},
"bugs": {
"url": "https://github.com/Polymer/vulcanize/issues"
},
"bundleDependencies": false,
"dependencies": {
"dom5": "^1.3.1",
"es6-promise": "^2.1.0",
"hydrolysis": "^1.19.1",
"nopt": "^3.0.1",
"path-posix": "^1.0.0"
},
"deprecated": false,
"description": "Process Web Components into one output file",
"devDependencies": {
"chai": "^3.4.1",
"eslint": "^2.8.0",
"firebase": "^2.4.1",
"mocha": "^2.2.4"
},
"directories": {
"test": "test"
},
"homepage": "https://github.com/Polymer/vulcanize#readme",
"keywords": [
"web components",
"polymer"
],
"license": "BSD-3-Clause",
"main": "lib/vulcan.js",
"name": "vulcanize",
"repository": {
"type": "git",
"url": "git://github.com/Polymer/vulcanize.git"
},
"scripts": {
"test": "eslint lib bin test && mocha"
},
"version": "1.16.0"
}

View File

@@ -0,0 +1,29 @@
UglifyJS is released under the BSD license:
Copyright 2012-2013 (c) Mihai Bazon <mihai.bazon@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials
provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

View File

@@ -0,0 +1,18 @@
# Contents
Slim copy of [UglifyJS2](https://github.com/mishoo/UglifyJS2) output library.
# Original Copy
https://raw.githubusercontent.com/mishoo/UglifyJS2/v2.6.1/lib/output.js
# Modifications
- Removed all functions except `encode_string`.
- Replaced call `var ret = make_string(str, quote)` with `var ret = str`
- Added default `options` object
- Added CommonJS `module.exports` line
- Added `jshint` settins line
- Removed semicolon from defintion of `encode_string`
- Escape scripts with `\x3c/script` syntax
# License
BSD-2-Clause: [License](https://raw.githubusercontent.com/mishoo/UglifyJS2/v2.6.1/LICENSE)

View File

@@ -0,0 +1,62 @@
/***********************************************************************
A JavaScript tokenizer / parser / beautifier / compressor.
https://github.com/mishoo/UglifyJS2
-------------------------------- (C) ---------------------------------
Author: Mihai Bazon
<mihai.bazon@gmail.com>
http://mihai.bazon.net/blog
Distributed under the BSD license:
Copyright 2012 (c) Mihai Bazon <mihai.bazon@gmail.com>
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
* Redistributions of source code must retain the above
copyright notice, this list of conditions and the following
disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials
provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER “AS IS” AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
***********************************************************************/
// jshint node: true
"use strict";
var options = {
inline_script: true
};
function encode_string(str, quote) {
var ret = str;
if (options.inline_script) {
ret = ret.replace(/(<|\\x3c)\x2fscript([>\/\t\n\f\r ])/gi, "$1\\/script$2");
ret = ret.replace(/\x3c!--/g, "\\x3c!--");
ret = ret.replace(/--\x3e/g, "--\\x3e");
}
return ret;
}
module.exports = encode_string;