Merge pull request #658 from webcomponents/v1-cleanup

Massively clean up `v1` branch
This commit is contained in:
Monica Dinculescu
2017-01-05 10:09:19 -08:00
committed by GitHub
306 changed files with 565 additions and 30059 deletions

View File

@@ -3,19 +3,17 @@ sudo: required
dist: trusty
node_js: stable
addons:
sauce_connect: true
firefox: 48.0
firefox: latest
apt:
sources:
- google-chrome
packages:
- google-chrome-stable
before_script:
- export PATH=$PWD/node_modules/.bin:$PATH
script:
- npm run build
- npm install -g bower
- bower install
- xvfb-run wct
- if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then wct -s 'default'; fi
- if [ "${TRAVIS_PULL_REQUEST}" = "false" ]; then wct -s 'windows 10/microsoftedge@14' -s 'windows 8.1/internet explorer@11' -s 'os x 10.11/safari@10' -s 'os x 10.11/safari@9'; fi
env:
global:
- secure: Fpp9LwJSGOdTrSIImQTlbzxozBsqe/2AJN5OfTXSe12FZxqzz50gevdxQcIlLypKaNyCtjb980DJbwdJR2cXUqaunLZAPWxrKa7ZPwamUxW+zVL7EHqy5zuvD+yJ+Vmk3ahs3WBTVyJ8T3XoaSfo9VumDIcKggWGJwgvM3blIMg=

View File

@@ -11,9 +11,6 @@ A suite of polyfills supporting the [Web Components](http://webcomponents.org) s
**Shadow DOM**: provides encapsulation by hiding DOM subtrees under shadow roots ([spec](https://w3c.github.io/webcomponents/spec/shadow/)).
This also folds in polyfills for `MutationObserver` and `WeakMap`.
## Releases
Pre-built (concatenated & minified) versions of the polyfills are maintained in the [tagged versions](https://github.com/webcomponents/webcomponentsjs/releases) of this repo. There are two variants:
@@ -75,9 +72,9 @@ Copyright (c) 2015 The Polymer Authors. All rights reserved.
### `WebComponentsReady`
Under native HTML Imports, `<script>` tags in the main document block the loading of such imports. This is to ensure the imports have loaded and any registered elements in them have been upgraded.
Under native HTML Imports, `<script>` tags in the main document block the loading of such imports. This is to ensure the imports have loaded and any registered elements in them have been upgraded.
The webcomponents.js and webcomponents-lite.js polyfills parse element definitions and handle their upgrade asynchronously. If prematurely fetching the element from the DOM before it has an opportunity to upgrade, you'll be working with an `HTMLUnknownElement`.
The webcomponents.js and webcomponents-lite.js polyfills parse element definitions and handle their upgrade asynchronously. If prematurely fetching the element from the DOM before it has an opportunity to upgrade, you'll be working with an `HTMLUnknownElement`.
For these situations (or when you need an approximate replacement for the Polymer 0.5 `polymer-ready` behavior), you can use the `WebComponentsReady` event as a signal before interacting with the element. The criteria for this event to fire is all Custom Elements with definitions registered by the time HTML Imports available at load time have loaded have upgraded.
@@ -144,7 +141,7 @@ polyfill-next-selector { content: '.foo :host.bar, :host.foo.bar'; }
```
### ShadowCSS: :host(.zot:not(.bar:nth-child(2))) doesn't work <a id="nestedparens"></a>
ShadowCSS `:host()` rules can only have (at most) 1-level of nested parentheses in its argument selector under ShadowCSS. For example, `:host(.zot)` and `:host(.zot:not(.bar))` both work, but `:host(.zot:not(.bar:nth-child(2)))` does not.
ShadowCSS `:host()` rules can only have (at most) 1-level of nested parentheses in its argument selector under ShadowCSS. For example, `:host(.zot)` and `:host(.zot:not(.bar))` both work, but `:host(.zot:not(.bar:nth-child(2)))` does not.
### HTML imports: document.currentScript doesn't work as expected <a id="currentscript"></a>
In native HTML Imports, document.currentScript.ownerDocument references the import document itself. In the polyfill use document._currentScript.ownerDocument (note the underscore).

View File

@@ -15,8 +15,13 @@
],
"dependencies": {
"custom-elements": "webcomponents/custom-elements#master",
"es6-promise": "stefanpenner/es6-promise#^4.0.0",
"html-imports": "webcomponents/html-imports#v0",
"shadydom": "webcomponents/shadydom#master",
"shadycss": "webcomponents/shadycss#master"
"shadycss": "webcomponents/shadycss#master",
"template": "webcomponents/template#master",
"URL": "webcomponents/URL#master",
"webcomponents-platform": "webcomponents/webcomponents-platform#master"
},
"license": "BSD",
"ignore": [],

View File

@@ -1,3 +0,0 @@
var CustomElementRegistry;
CustomElementRegistry.prototype.enableFlush = false;
CustomElementRegistry.prototype.forcePolyfill = false;

View File

@@ -1 +0,0 @@
MutationObserver.prototype.takeRecords = function() {};

View File

@@ -121,14 +121,11 @@ gulp.task('copy-bower', function() {
return gulp.src(['bower.json', 'package.json', 'README.md']).pipe(gulp.dest('dist/'));
});
defineBuildTask('webcomponents', './src/WebComponents/build.json');
defineBuildTask('webcomponents-lite', './src/WebComponents/build-lite.json');
defineBuildTask('webcomponents', './src/build.json');
defineBuildTask('webcomponents-lite', './src/build-lite.json');
defineBuildTask('HTMLImports');
defineBuildTask('ShadowDOM');
defineBuildTask('MutationObserver');
gulp.task('build', ['webcomponents', 'webcomponents-lite', 'HTMLImports', 'ShadowDOM', 'copy-bower',
'MutationObserver']);
gulp.task('build', ['webcomponents', 'webcomponents-lite', 'HTMLImports', 'copy-bower']);
gulp.task('release', function(cb) {
isRelease = true;

View File

@@ -28,6 +28,6 @@
"gulp-rename": "^1.2.2",
"gulp-uglify": "^1.0.1",
"run-sequence": "^1.0.1",
"web-component-tester": "^4.0.1"
"web-component-tester": "^6.0.0-prerelease.4"
}
}

View File

@@ -1,58 +0,0 @@
/**
* @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() {
// Establish polyfill scope. We do this here to store flags. Flags are not
// supported in the build.
window.HTMLImports = window.HTMLImports || {flags:{}};
// Flags. Convert url arguments to flags
var flags = {};
if (!flags.noOpts) {
location.search.slice(1).split('&').forEach(function(option) {
var parts = option.split('=');
var match;
if (parts[0] && (match = parts[0].match(/wc-(.+)/))) {
flags[match[1]] = parts[1] || true;
}
});
}
// Load.
var file = 'HTMLImports.js';
var modules = [
'../WeakMap/WeakMap.js',
'../MutationObserver/MutationObserver.js',
'../WebComponents/dom.js',
'base.js',
'module.js',
'path.js',
'xhr.js',
'Loader.js',
'Observer.js',
'parser.js',
'importer.js',
'dynamic.js',
'boot.js'
];
var src =
document.querySelector('script[src*="' + file + '"]').getAttribute('src');
var basePath = src.slice(0, src.indexOf(file));
modules.forEach(function(f) {
document.write('<script src="' + basePath + f + '"></script>');
});
// exports
window.HTMLImports.flags = flags;
})();

View File

@@ -1,140 +0,0 @@
/**
* @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
*/
window.HTMLImports.addModule(function(scope) {
// imports
var xhr = scope.xhr;
var flags = scope.flags;
// This loader supports a dynamic list of urls
// and an oncomplete callback that is called when the loader is done.
// NOTE: The polyfill currently does *not* need this dynamism or the
// onComplete concept. Because of this, the loader could be simplified
// quite a bit.
var Loader = function(onLoad, onComplete) {
this.cache = {};
this.onload = onLoad;
this.oncomplete = onComplete;
this.inflight = 0;
this.pending = {};
};
Loader.prototype = {
addNodes: function(nodes) {
// number of transactions to complete
this.inflight += nodes.length;
// commence transactions
for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) {
this.require(n);
}
// anything to do?
this.checkDone();
},
addNode: function(node) {
// number of transactions to complete
this.inflight++;
// commence transactions
this.require(node);
// anything to do?
this.checkDone();
},
require: function(elt) {
var url = elt.src || elt.href;
// ensure we have a standard url that can be used
// reliably for deduping.
// TODO(sjmiles): ad-hoc
elt.__nodeUrl = url;
// deduplication
if (!this.dedupe(url, elt)) {
// fetch this resource
this.fetch(url, elt);
}
},
dedupe: function(url, elt) {
if (this.pending[url]) {
// add to list of nodes waiting for inUrl
this.pending[url].push(elt);
// don't need fetch
return true;
}
var resource;
if (this.cache[url]) {
this.onload(url, elt, this.cache[url]);
// finished this transaction
this.tail();
// don't need fetch
return true;
}
// first node waiting for inUrl
this.pending[url] = [elt];
// need fetch (not a dupe)
return false;
},
fetch: function(url, elt) {
flags.load && console.log('fetch', url, elt);
if (!url) {
setTimeout(function() {
this.receive(url, elt, {error: 'href must be specified'}, null);
}.bind(this), 0);
} else if (url.match(/^data:/)) {
// Handle Data URI Scheme
var pieces = url.split(',');
var header = pieces[0];
var body = pieces[1];
if(header.indexOf(';base64') > -1) {
body = atob(body);
} else {
body = decodeURIComponent(body);
}
setTimeout(function() {
this.receive(url, elt, null, body);
}.bind(this), 0);
} else {
var receiveXhr = function(err, resource, redirectedUrl) {
this.receive(url, elt, err, resource, redirectedUrl);
}.bind(this);
xhr.load(url, receiveXhr);
}
},
receive: function(url, elt, err, resource, redirectedUrl) {
this.cache[url] = resource;
var $p = this.pending[url];
for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) {
// If url was redirected, use the redirected location so paths are
// calculated relative to that.
this.onload(url, p, resource, err, redirectedUrl);
this.tail();
}
this.pending[url] = null;
},
tail: function() {
--this.inflight;
this.checkDone();
},
checkDone: function() {
if (!this.inflight) {
this.oncomplete();
}
}
};
// exports
scope.Loader = Loader;
});

View File

@@ -1,51 +0,0 @@
/**
* @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
*/
window.HTMLImports.addModule(function(scope) {
/*
Use a mutation observer to call a callback for all added nodes.
*/
var Observer = function(addCallback) {
this.addCallback = addCallback;
this.mo = new MutationObserver(this.handler.bind(this));
};
Observer.prototype = {
// we track mutations for addedNodes, looking for imports
handler: function(mutations) {
for (var i=0, l=mutations.length, m; (i<l) && (m=mutations[i]); i++) {
if (m.type === 'childList' && m.addedNodes.length) {
this.addedNodes(m.addedNodes);
}
}
},
addedNodes: function(nodes) {
if (this.addCallback) {
this.addCallback(nodes);
}
for (var i=0, l=nodes.length, n, loading; (i<l) && (n=nodes[i]); i++) {
if (n.children && n.children.length) {
this.addedNodes(n.children);
}
}
},
observe: function(root) {
this.mo.observe(root, {childList: true, subtree: true});
}
};
// exports
scope.Observer = Observer;
});

View File

@@ -1,241 +0,0 @@
/**
* @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
*/
/*
* PLEASE NOTE: This file is duplicated within Polymer. Please keep it in sync!
* https://github.com/Polymer/polymer/blob/master/src/system/HTMLImports/base.js
*/
/*
Create polyfill scope and feature detect native support.
*/
window.HTMLImports = window.HTMLImports || {flags:{}};
(function(scope) {
/**
Basic setup and simple module executer. We collect modules and then execute
the code later, only if it's necessary for polyfilling.
*/
var IMPORT_LINK_TYPE = 'import';
var useNative = Boolean(IMPORT_LINK_TYPE in document.createElement('link'));
/**
Support `currentScript` on all browsers as `document._currentScript.`
NOTE: We cannot polyfill `document.currentScript` because it's not possible
both to override and maintain the ability to capture the native value.
Therefore we choose to expose `_currentScript` both when native imports
and the polyfill are in use.
*/
// NOTE: ShadowDOMPolyfill intrusion.
var hasShadowDOMPolyfill = Boolean(window.ShadowDOMPolyfill);
var wrap = function(node) {
return hasShadowDOMPolyfill ? window.ShadowDOMPolyfill.wrapIfNeeded(node) : node;
};
var rootDocument = wrap(document);
var currentScriptDescriptor = {
get: function() {
var script = window.HTMLImports.currentScript || document.currentScript ||
// NOTE: only works when called in synchronously executing code.
// readyState should check if `loading` but IE10 is
// interactive when scripts run so we cheat.
(document.readyState !== 'complete' ?
document.scripts[document.scripts.length - 1] : null);
return wrap(script);
},
configurable: true
};
Object.defineProperty(document, '_currentScript', currentScriptDescriptor);
Object.defineProperty(rootDocument, '_currentScript', currentScriptDescriptor);
/**
Add support for the `HTMLImportsLoaded` event and the `HTMLImports.whenReady`
method. This api is necessary because unlike the native implementation,
script elements do not force imports to resolve. Instead, users should wrap
code in either an `HTMLImportsLoaded` handler or after load time in an
`HTMLImports.whenReady(callback)` call.
NOTE: This module also supports these apis under the native implementation.
Therefore, if this file is loaded, the same code can be used under both
the polyfill and native implementation.
*/
var isIE = /Trident/.test(navigator.userAgent);
// call a callback when all HTMLImports in the document at call time
// (or at least document ready) have loaded.
// 1. ensure the document is in a ready state (has dom), then
// 2. watch for loading of imports and call callback when done
function whenReady(callback, doc) {
doc = doc || rootDocument;
// if document is loading, wait and try again
whenDocumentReady(function() {
watchImportsLoad(callback, doc);
}, doc);
}
// call the callback when the document is in a ready state (has dom)
var requiredReadyState = isIE ? 'complete' : 'interactive';
var READY_EVENT = 'readystatechange';
function isDocumentReady(doc) {
return (doc.readyState === 'complete' ||
doc.readyState === requiredReadyState);
}
// call <callback> when we ensure the document is in a ready state
function whenDocumentReady(callback, doc) {
if (!isDocumentReady(doc)) {
var checkReady = function() {
if (doc.readyState === 'complete' ||
doc.readyState === requiredReadyState) {
doc.removeEventListener(READY_EVENT, checkReady);
whenDocumentReady(callback, doc);
}
};
doc.addEventListener(READY_EVENT, checkReady);
} else if (callback) {
callback();
}
}
function markTargetLoaded(event) {
event.target.__loaded = true;
}
// call <callback> when we ensure all imports have loaded
function watchImportsLoad(callback, doc) {
var imports = doc.querySelectorAll('link[rel=import]');
var parsedCount = 0, importCount = imports.length, newImports = [], errorImports = [];
function checkDone() {
if (parsedCount == importCount && callback) {
callback({
allImports: imports,
loadedImports: newImports,
errorImports: errorImports
});
}
}
function loadedImport(e) {
markTargetLoaded(e);
newImports.push(this);
parsedCount++;
checkDone();
}
function errorLoadingImport(e) {
errorImports.push(this);
parsedCount++;
checkDone();
}
if (importCount) {
for (var i=0, imp; i<importCount && (imp=imports[i]); i++) {
if (isImportLoaded(imp)) {
newImports.push(this);
parsedCount++;
checkDone();
} else {
imp.addEventListener('load', loadedImport);
imp.addEventListener('error', errorLoadingImport);
}
}
} else {
checkDone();
}
}
// NOTE: test for native imports loading is based on explicitly watching
// all imports (see below).
// However, we cannot rely on this entirely without watching the entire document
// for import links. For perf reasons, currently only head is watched.
// Instead, we fallback to checking if the import property is available
// and the document is not itself loading.
function isImportLoaded(link) {
return useNative ? link.__loaded ||
(link.import && link.import.readyState !== 'loading') :
link.__importParsed;
}
// TODO(sorvell): Workaround for
// https://www.w3.org/Bugs/Public/show_bug.cgi?id=25007, should be removed when
// this bug is addressed.
// (1) Install a mutation observer to see when HTMLImports have loaded
// (2) if this script is run during document load it will watch any existing
// imports for loading.
//
// NOTE: The workaround has restricted functionality: (1) it's only compatible
// with imports that are added to document.head since the mutation observer
// watches only head for perf reasons, (2) it requires this script
// to run before any imports have completed loading.
if (useNative) {
new MutationObserver(function(mxns) {
for (var i=0, l=mxns.length, m; (i < l) && (m=mxns[i]); i++) {
if (m.addedNodes) {
handleImports(m.addedNodes);
}
}
}).observe(document.head, {childList: true});
function handleImports(nodes) {
for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) {
if (isImport(n)) {
handleImport(n);
}
}
}
function isImport(element) {
return element.localName === 'link' && element.rel === 'import';
}
function handleImport(element) {
var loaded = element.import;
if (loaded) {
markTargetLoaded({target: element});
} else {
element.addEventListener('load', markTargetLoaded);
element.addEventListener('error', markTargetLoaded);
}
}
// make sure to catch any imports that are in the process of loading
// when this script is run.
(function() {
if (document.readyState === 'loading') {
var imports = document.querySelectorAll('link[rel=import]');
for (var i=0, l=imports.length, imp; (i<l) && (imp=imports[i]); i++) {
handleImport(imp);
}
}
})();
}
// Fire the 'HTMLImportsLoaded' event when imports in document at load time
// have loaded. This event is required to simulate the script blocking
// behavior of native imports. A main document script that needs to be sure
// imports have loaded should wait for this event.
whenReady(function(detail) {
window.HTMLImports.ready = true;
window.HTMLImports.readyTime = new Date().getTime();
var evt = rootDocument.createEvent("CustomEvent");
evt.initCustomEvent("HTMLImportsLoaded", true, true, detail);
rootDocument.dispatchEvent(evt);
});
// exports
scope.IMPORT_LINK_TYPE = IMPORT_LINK_TYPE;
scope.useNative = useNative;
scope.rootDocument = rootDocument;
scope.whenReady = whenReady;
scope.isIE = isIE;
})(window.HTMLImports);

View File

@@ -1,55 +0,0 @@
/**
* @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(scope){
// imports
var initializeModules = scope.initializeModules;
var isIE = scope.isIE;
/*
NOTE: Even when native HTMLImports exists, the following api is available by
loading the polyfill. This provides api compatibility where the polyfill
cannot be "correct":
* `document._currentScript`
* `HTMLImportsLoaded` event
* `HTMLImports.whenReady(callback)
*/
if (scope.useNative) {
return;
}
// Initialize polyfill modules. Note, polyfill modules are loaded but not
// executed; this is a convenient way to control which modules run when
// the polyfill is required and allows the polyfill to load even when it's
// not needed.
initializeModules();
// imports
var rootDocument = scope.rootDocument;
/*
Bootstrap the imports machine.
*/
function bootstrap() {
window.HTMLImports.importer.bootDocument(rootDocument);
}
// TODO(sorvell): SD polyfill does *not* generate mutations for nodes added
// by the parser. For this reason, we must wait until the dom exists to
// bootstrap.
if (document.readyState === 'complete' ||
(document.readyState === 'interactive' && !window.attachEvent)) {
bootstrap();
} else {
document.addEventListener('DOMContentLoaded', bootstrap);
}
})(window.HTMLImports);

View File

@@ -1,15 +0,0 @@
[
"../WeakMap/WeakMap.js",
"../MutationObserver/MutationObserver.js",
"../WebComponents/dom.js",
"base.js",
"module.js",
"path.js",
"xhr.js",
"Loader.js",
"Observer.js",
"parser.js",
"importer.js",
"dynamic.js",
"boot.js"
]

View File

@@ -1,65 +0,0 @@
/**
* @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
*/
window.HTMLImports.addModule(function(scope) {
// imports
var parser = scope.parser;
var importer = scope.importer;
// dynamic
// highlander object to manage elements dynamically added to imports
// for any observed document, dynamic:
// - tells the importer to load any imports that are added.
// - tells the parser to parse any added elements that need to be parsed.
// dynamic importer)
var dynamic = {
// process (load/parse) any nodes added to imported documents.
added: function(nodes) {
var owner, parsed, loading;
for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) {
if (!owner) {
owner = n.ownerDocument;
parsed = parser.isParsed(owner);
}
// note: the act of loading kicks the parser, so we use parseDynamic's
// 2nd argument to control if this added node needs to kick the parser.
loading = this.shouldLoadNode(n);
if (loading) {
importer.loadNode(n);
}
if (this.shouldParseNode(n) && parsed) {
parser.parseDynamic(n, loading);
}
}
},
shouldLoadNode: function(node) {
return (node.nodeType === 1) && matches.call(node,
importer.loadSelectorsForNode(node));
},
shouldParseNode: function(node) {
return (node.nodeType === 1) && matches.call(node,
parser.parseSelectorsForNode(node));
}
};
// let the dynamic element helper tie into the import observer.
importer.observer.addCallback = dynamic.added.bind(dynamic);
// x-plat matches
var matches = HTMLElement.prototype.matches ||
HTMLElement.prototype.matchesSelector ||
HTMLElement.prototype.webkitMatchesSelector ||
HTMLElement.prototype.mozMatchesSelector ||
HTMLElement.prototype.msMatchesSelector;
});

View File

@@ -1,173 +0,0 @@
/**
* @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
*/
window.HTMLImports.addModule(function(scope) {
// imports
var flags = scope.flags;
var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
var IMPORT_SELECTOR = scope.IMPORT_SELECTOR;
var rootDocument = scope.rootDocument;
var Loader = scope.Loader;
var Observer = scope.Observer;
var parser = scope.parser;
// importer
// highlander object to manage loading of imports
// for any document, importer:
// - loads any linked import documents (with deduping)
// - whenever an import is loaded, prompts the parser to try to parse
// - observes imported documents for new elements (these are handled via the
// dynamic importer)
var importer = {
documents: {},
// nodes to load in the mian document
documentPreloadSelectors: IMPORT_SELECTOR,
// nodes to load in imports
importsPreloadSelectors: [
IMPORT_SELECTOR
].join(','),
loadNode: function(node) {
importLoader.addNode(node);
},
// load all loadable elements within the parent element
loadSubtree: function(parent) {
var nodes = this.marshalNodes(parent);
// add these nodes to loader's queue
importLoader.addNodes(nodes);
},
marshalNodes: function(parent) {
// all preloadable nodes in inDocument
return parent.querySelectorAll(this.loadSelectorsForNode(parent));
},
// find the proper set of load selectors for a given node
loadSelectorsForNode: function(node) {
var doc = node.ownerDocument || node;
return doc === rootDocument ? this.documentPreloadSelectors :
this.importsPreloadSelectors;
},
loaded: function(url, elt, resource, err, redirectedUrl) {
flags.load && console.log('loaded', url, elt);
// store generic resource
// TODO(sorvell): fails for nodes inside <template>.content
// see https://code.google.com/p/chromium/issues/detail?id=249381.
elt.__resource = resource;
elt.__error = err;
if (isImportLink(elt)) {
var doc = this.documents[url];
// if we've never seen a document at this url
if (doc === undefined) {
// generate an HTMLDocument from data
doc = err ? null : makeDocument(resource, redirectedUrl || url);
if (doc) {
doc.__importLink = elt;
// note, we cannot use MO to detect parsed nodes because
// SD polyfill does not report these as mutations.
this.bootDocument(doc);
}
// cache document
this.documents[url] = doc;
}
// don't store import record until we're actually loaded
// store document resource
elt.__doc = doc;
}
parser.parseNext();
},
bootDocument: function(doc) {
this.loadSubtree(doc);
// observe documents for new elements being added
this.observer.observe(doc);
parser.parseNext();
},
loadedAll: function() {
parser.parseNext();
}
};
// loader singleton to handle loading imports
var importLoader = new Loader(importer.loaded.bind(importer),
importer.loadedAll.bind(importer));
// observer singleton to handle observing elements in imports
// NOTE: the observer has a node added callback and this is set
// by the dynamic importer module.
importer.observer = new Observer();
function isImportLink(elt) {
return isLinkRel(elt, IMPORT_LINK_TYPE);
}
function isLinkRel(elt, rel) {
return elt.localName === 'link' && elt.getAttribute('rel') === rel;
}
function hasBaseURIAccessor(doc) {
return !! Object.getOwnPropertyDescriptor(doc, 'baseURI');
}
function makeDocument(resource, url) {
// create a new HTML document
var doc = document.implementation.createHTMLDocument(IMPORT_LINK_TYPE);
// cache the new document's source url
doc._URL = url;
// establish a relative path via <base>
var base = doc.createElement('base');
base.setAttribute('href', url);
// add baseURI support to browsers (IE) that lack it.
if (!doc.baseURI && !hasBaseURIAccessor(doc)) {
// Use defineProperty since Safari throws an exception when using assignment.
Object.defineProperty(doc, 'baseURI', {value:url});
}
// ensure UTF-8 charset
var meta = doc.createElement('meta');
meta.setAttribute('charset', 'utf-8');
doc.head.appendChild(meta);
doc.head.appendChild(base);
// install html
doc.body.innerHTML = resource;
// TODO(sorvell): ideally this code is not aware of Template polyfill,
// but for now the polyfill needs help to bootstrap these templates
if (window.HTMLTemplateElement && HTMLTemplateElement.bootstrap) {
HTMLTemplateElement.bootstrap(doc);
}
return doc;
}
// Polyfill document.baseURI for browsers without it.
if (!document.baseURI) {
var baseURIDescriptor = {
get: function() {
var base = document.querySelector('base');
return base ? base.href : window.location.href;
},
configurable: true
};
Object.defineProperty(document, 'baseURI', baseURIDescriptor);
Object.defineProperty(rootDocument, 'baseURI', baseURIDescriptor);
}
// exports
scope.importer = importer;
scope.importLoader = importLoader;
});

View File

@@ -1,29 +0,0 @@
/**
* @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(scope) {
// world's simplest module initializer
var modules = [];
var addModule = function(module) {
modules.push(module);
};
var initializeModules = function() {
modules.forEach(function(module) {
module(scope);
});
};
// exports
scope.addModule = addModule;
scope.initializeModules = initializeModules;
})(window.HTMLImports);

View File

@@ -1,339 +0,0 @@
/**
* @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
*/
window.HTMLImports.addModule(function(scope) {
// imports
var path = scope.path;
var rootDocument = scope.rootDocument;
var flags = scope.flags;
var isIE = scope.isIE;
var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
var IMPORT_SELECTOR = 'link[rel=' + IMPORT_LINK_TYPE + ']';
// importParser
// highlander object to manage parsing of imports
// parses import related elements and ensures proper parse order
// parse order is enforced by crawling the tree and monitoring which elements
// have been parsed;
// elements can be dynamically added to imports. These are maintained in a
// separate queue and parsed after all other elements.
var importParser = {
// parse selectors for main document elements
documentSelectors: IMPORT_SELECTOR,
// parse selectors for import document elements
importsSelectors: [
IMPORT_SELECTOR,
'link[rel=stylesheet]:not([type])',
'style:not([type])',
'script:not([type])',
'script[type="application/javascript"]',
'script[type="text/javascript"]'
].join(','),
map: {
link: 'parseLink',
script: 'parseScript',
style: 'parseStyle'
},
dynamicElements: [],
// try to parse the next import in the tree
parseNext: function() {
var next = this.nextToParse();
if (next) {
this.parse(next);
}
},
parse: function(elt) {
if (this.isParsed(elt)) {
flags.parse && console.log('[%s] is already parsed', elt.localName);
return;
}
var fn = this[this.map[elt.localName]];
if (fn) {
this.markParsing(elt);
fn.call(this, elt);
}
},
// marks an element for dynamic parsing and attempts to parse the next element
parseDynamic: function(elt, quiet) {
this.dynamicElements.push(elt);
if (!quiet) {
this.parseNext();
}
},
// only 1 element may be parsed at a time; parsing is async so each
// parsing implementation must inform the system that parsing is complete
// via markParsingComplete.
// To prompt the system to parse the next element, parseNext should then be
// called.
// Note, parseNext used to be included at the end of markParsingComplete, but
// we must not do this so that, for example, we can (1) mark parsing complete
// then (2) fire an import load event, and then (3) parse the next resource.
markParsing: function(elt) {
flags.parse && console.log('parsing', elt);
this.parsingElement = elt;
},
markParsingComplete: function(elt) {
elt.__importParsed = true;
this.markDynamicParsingComplete(elt);
if (elt.__importElement) {
elt.__importElement.__importParsed = true;
this.markDynamicParsingComplete(elt.__importElement);
}
this.parsingElement = null;
flags.parse && console.log('completed', elt);
},
markDynamicParsingComplete: function(elt) {
var i = this.dynamicElements.indexOf(elt);
if (i >= 0) {
this.dynamicElements.splice(i, 1);
}
},
parseImport: function(elt) {
elt.import = elt.__doc;
if (window.HTMLImports.__importsParsingHook) {
window.HTMLImports.__importsParsingHook(elt);
}
if (elt.import) {
elt.import.__importParsed = true;
}
this.markParsingComplete(elt);
// fire load event
if (elt.__resource && !elt.__error) {
elt.dispatchEvent(new CustomEvent('load', {bubbles: false}));
} else {
elt.dispatchEvent(new CustomEvent('error', {bubbles: false}));
}
// TODO(sorvell): workaround for Safari addEventListener not working
// for elements not in the main document.
if (elt.__pending) {
var fn;
while (elt.__pending.length) {
fn = elt.__pending.shift();
if (fn) {
fn({target: elt});
}
}
}
this.parseNext();
},
parseLink: function(linkElt) {
if (nodeIsImport(linkElt)) {
this.parseImport(linkElt);
} else {
// make href absolute
linkElt.href = linkElt.href;
this.parseGeneric(linkElt);
}
},
parseStyle: function(elt) {
// TODO(sorvell): style element load event can just not fire so clone styles
var src = elt;
elt = cloneStyle(elt);
src.__appliedElement = elt;
elt.__importElement = src;
this.parseGeneric(elt);
},
parseGeneric: function(elt) {
this.trackElement(elt);
this.addElementToDocument(elt);
},
rootImportForElement: function(elt) {
var n = elt;
while (n.ownerDocument.__importLink) {
n = n.ownerDocument.__importLink;
}
return n;
},
addElementToDocument: function(elt) {
var port = this.rootImportForElement(elt.__importElement || elt);
port.parentNode.insertBefore(elt, port);
},
// tracks when a loadable element has loaded
trackElement: function(elt, callback) {
var self = this;
var done = function(e) {
// make sure we don't get multiple load/error signals (FF seems to do
// this sometimes when <style> elments change)
elt.removeEventListener('load', done);
elt.removeEventListener('error', done);
if (callback) {
callback(e);
}
self.markParsingComplete(elt);
self.parseNext();
};
elt.addEventListener('load', done);
elt.addEventListener('error', done);
// NOTE: IE does not fire "load" event for styles that have already loaded
// This is in violation of the spec, so we try our hardest to work around it
if (isIE && elt.localName === 'style') {
var fakeLoad = false;
// If there's not @import in the textContent, assume it has loaded
if (elt.textContent.indexOf('@import') == -1) {
fakeLoad = true;
// if we have a sheet, we have been parsed
} else if (elt.sheet) {
fakeLoad = true;
var csr = elt.sheet.cssRules;
var len = csr ? csr.length : 0;
// search the rules for @import's
for (var i = 0, r; (i < len) && (r = csr[i]); i++) {
if (r.type === CSSRule.IMPORT_RULE) {
// if every @import has resolved, fake the load
fakeLoad = fakeLoad && Boolean(r.styleSheet);
}
}
}
// dispatch a fake load event and continue parsing
if (fakeLoad) {
// Fire async, to prevent reentrancy
setTimeout(function() {
elt.dispatchEvent(new CustomEvent('load', {bubbles: false}));
});
}
}
},
// NOTE: execute scripts by injecting them and watching for the load/error
// event. Inline scripts are handled via dataURL's because browsers tend to
// provide correct parsing errors in this case. If this has any compatibility
// issues, we can switch to injecting the inline script with textContent.
parseScript: function(scriptElt) {
var script = document.createElement('script');
script.__importElement = scriptElt;
script.src = scriptElt.src ? scriptElt.src :
generateScriptDataUrl(scriptElt);
// keep track of executing script to help polyfill `document.currentScript`
scope.currentScript = scriptElt;
this.trackElement(script, function(e) {
if (script.parentNode) {
script.parentNode.removeChild(script);
}
scope.currentScript = null;
});
this.addElementToDocument(script);
},
// determine the next element in the tree which should be parsed
// crawl the document tree to find the next unparsed element
// then process any dynamically added elements (these should process in 'add'
// order.
nextToParse: function() {
this._mayParse = [];
return !this.parsingElement && (this.nextToParseInDoc(rootDocument) ||
this.nextToParseDynamic());
},
nextToParseInDoc: function(doc, link) {
// use `marParse` list to avoid looping into the same document again
// since it could cause an iloop.
if (doc && this._mayParse.indexOf(doc) < 0) {
this._mayParse.push(doc);
var nodes = doc.querySelectorAll(this.parseSelectorsForNode(doc));
for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) {
if (!this.isParsed(n)) {
if (this.hasResource(n)) {
return nodeIsImport(n) ? this.nextToParseInDoc(n.__doc, n) : n;
} else {
return;
}
}
}
}
// all nodes have been parsed, ready to parse import, if any
return link;
},
// note dynamically added elements are stored in a separate queue
nextToParseDynamic: function() {
return this.dynamicElements[0];
},
// return the set of parse selectors relevant for this node.
parseSelectorsForNode: function(node) {
var doc = node.ownerDocument || node;
return doc === rootDocument ? this.documentSelectors :
this.importsSelectors;
},
isParsed: function(node) {
return node.__importParsed;
},
needsDynamicParsing: function(elt) {
return (this.dynamicElements.indexOf(elt) >= 0);
},
hasResource: function(node) {
if (nodeIsImport(node) && (node.__doc === undefined)) {
return false;
}
return true;
}
};
function nodeIsImport(elt) {
return (elt.localName === 'link') && (elt.rel === IMPORT_LINK_TYPE);
}
function generateScriptDataUrl(script) {
var scriptContent = generateScriptContent(script);
return 'data:text/javascript;charset=utf-8,' + encodeURIComponent(scriptContent);
}
function generateScriptContent(script) {
return script.textContent + generateSourceMapHint(script);
}
// calculate source map hint
function generateSourceMapHint(script) {
var owner = script.ownerDocument;
owner.__importedScripts = owner.__importedScripts || 0;
var moniker = script.ownerDocument.baseURI;
var num = owner.__importedScripts ? '-' + owner.__importedScripts : '';
owner.__importedScripts++;
return '\n//# sourceURL=' + moniker + num + '.js\n';
}
// style/stylesheet handling
// clone style with proper path resolution for main document
// NOTE: styles are the only elements that require direct path fixup.
function cloneStyle(style) {
var clone = style.ownerDocument.createElement('style');
clone.textContent = style.textContent;
path.resolveUrlsInStyle(clone);
return clone;
}
// exports
scope.parser = importParser;
scope.IMPORT_SELECTOR = IMPORT_SELECTOR;
});

View File

@@ -1,49 +0,0 @@
/**
* @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
*/
window.HTMLImports.addModule(function(scope) {
var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g;
var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g;
// path fixup: style elements in imports must be made relative to the main
// document. We fixup url's in url() and @import.
var path = {
resolveUrlsInStyle: function(style, linkUrl) {
var doc = style.ownerDocument;
var resolver = doc.createElement('a');
style.textContent = this.resolveUrlsInCssText(style.textContent, linkUrl, resolver);
return style;
},
resolveUrlsInCssText: function(cssText, linkUrl, urlObj) {
var r = this.replaceUrls(cssText, urlObj, linkUrl, CSS_URL_REGEXP);
r = this.replaceUrls(r, urlObj, linkUrl, CSS_IMPORT_REGEXP);
return r;
},
replaceUrls: function(text, urlObj, linkUrl, regexp) {
return text.replace(regexp, function(m, pre, url, post) {
var urlPath = url.replace(/["']/g, '');
if (linkUrl) {
urlPath = (new URL(urlPath, linkUrl)).href;
}
urlObj.href = urlPath;
urlPath = urlObj.href;
return pre + '\'' + urlPath + '\'' + post;
});
}
};
// exports
scope.path = path;
});

View File

@@ -1,62 +0,0 @@
/**
* @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
*/
window.HTMLImports.addModule(function(scope) {
/*
xhr processor.
*/
var xhr = {
async: true,
ok: function(request) {
return (request.status >= 200 && request.status < 300)
|| (request.status === 304)
|| (request.status === 0);
},
load: function(url, next, nextContext) {
var request = new XMLHttpRequest();
if (scope.flags.debug || scope.flags.bust) {
url += '?' + Math.random();
}
request.open('GET', url, xhr.async);
request.addEventListener('readystatechange', function(e) {
if (request.readyState === 4) {
// Servers redirecting an import can add a Location header to help us
// polyfill correctly.
var redirectedUrl = null;
try {
var locationHeader = request.getResponseHeader("Location");
if (locationHeader) {
redirectedUrl = (locationHeader.substr( 0, 1 ) === "/")
? location.origin + locationHeader // Location is a relative path
: locationHeader; // Full path
}
} catch ( e ) {
console.error( e.message );
}
next.call(nextContext, !xhr.ok(request) && request,
request.response || request.responseText, redirectedUrl);
}
});
request.send();
return request;
},
loadDocument: function(url, next, nextContext) {
this.load(url, next, nextContext).responseType = 'document';
}
};
// exports
scope.xhr = xhr;
});

View File

@@ -1,575 +0,0 @@
/**
* @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(global) {
// Don't allow this object to be redefined.
if (global.JsMutationObserver) {
return;
}
var registrationsTable = new WeakMap();
var setImmediate;
// As much as we would like to use the native implementation, IE
// (all versions) suffers a rather annoying bug where it will drop or defer
// callbacks when heavy DOM operations are being performed concurrently.
//
// For a thorough discussion on this, see:
// http://codeforhire.com/2013/09/21/setimmediate-and-messagechannel-broken-on-internet-explorer-10/
if (/Trident|Edge/.test(navigator.userAgent)) {
// Sadly, this bug also affects postMessage and MessageQueues.
//
// We would like to use the onreadystatechange hack for IE <= 10, but it is
// dangerous in the polyfilled environment due to requiring that the
// observed script element be in the document.
setImmediate = setTimeout;
// If some other browser ever implements it, let's prefer their native
// implementation:
} else if (window.setImmediate) {
setImmediate = window.setImmediate;
// Otherwise, we fall back to postMessage as a means of emulating the next
// task semantics of setImmediate.
} else {
var setImmediateQueue = [];
var sentinel = String(Math.random());
window.addEventListener('message', function(e) {
if (e.data === sentinel) {
var queue = setImmediateQueue;
setImmediateQueue = [];
queue.forEach(function(func) {
func();
});
}
});
setImmediate = function(func) {
setImmediateQueue.push(func);
window.postMessage(sentinel, '*');
};
}
// This is used to ensure that we never schedule 2 callas to setImmediate
var isScheduled = false;
// Keep track of observers that needs to be notified next time.
var scheduledObservers = [];
/**
* Schedules |dispatchCallback| to be called in the future.
* @param {MutationObserver} observer
*/
function scheduleCallback(observer) {
scheduledObservers.push(observer);
if (!isScheduled) {
isScheduled = true;
setImmediate(dispatchCallbacks);
}
}
function wrapIfNeeded(node) {
return window.ShadowDOMPolyfill &&
window.ShadowDOMPolyfill.wrapIfNeeded(node) ||
node;
}
function dispatchCallbacks() {
// http://dom.spec.whatwg.org/#mutation-observers
isScheduled = false; // Used to allow a new setImmediate call above.
var observers = scheduledObservers;
scheduledObservers = [];
// Sort observers based on their creation UID (incremental).
observers.sort(function(o1, o2) {
return o1.uid_ - o2.uid_;
});
var anyNonEmpty = false;
observers.forEach(function(observer) {
// 2.1, 2.2
var queue = observer.takeRecords();
// 2.3. Remove all transient registered observers whose observer is mo.
removeTransientObserversFor(observer);
// 2.4
if (queue.length) {
observer.callback_(queue, observer);
anyNonEmpty = true;
}
});
// 3.
if (anyNonEmpty)
dispatchCallbacks();
}
function removeTransientObserversFor(observer) {
observer.nodes_.forEach(function(node) {
var registrations = registrationsTable.get(node);
if (!registrations)
return;
registrations.forEach(function(registration) {
if (registration.observer === observer)
registration.removeTransientObservers();
});
});
}
/**
* This function is used for the "For each registered observer observer (with
* observer's options as options) in target's list of registered observers,
* run these substeps:" and the "For each ancestor ancestor of target, and for
* each registered observer observer (with options options) in ancestor's list
* of registered observers, run these substeps:" part of the algorithms. The
* |options.subtree| is checked to ensure that the callback is called
* correctly.
*
* @param {Node} target
* @param {function(MutationObserverInit):MutationRecord} callback
*/
function forEachAncestorAndObserverEnqueueRecord(target, callback) {
for (var node = target; node; node = node.parentNode) {
var registrations = registrationsTable.get(node);
if (registrations) {
for (var j = 0; j < registrations.length; j++) {
var registration = registrations[j];
var options = registration.options;
// Only target ignores subtree.
if (node !== target && !options.subtree)
continue;
var record = callback(options);
if (record)
registration.enqueue(record);
}
}
}
}
var uidCounter = 0;
/**
* The class that maps to the DOM MutationObserver interface.
* @param {Function} callback.
* @constructor
*/
function JsMutationObserver(callback) {
this.callback_ = callback;
this.nodes_ = [];
this.records_ = [];
this.uid_ = ++uidCounter;
}
JsMutationObserver.prototype = {
observe: function(target, options) {
target = wrapIfNeeded(target);
// 1.1
if (!options.childList && !options.attributes && !options.characterData ||
// 1.2
options.attributeOldValue && !options.attributes ||
// 1.3
options.attributeFilter && options.attributeFilter.length &&
!options.attributes ||
// 1.4
options.characterDataOldValue && !options.characterData) {
throw new SyntaxError();
}
var registrations = registrationsTable.get(target);
if (!registrations)
registrationsTable.set(target, registrations = []);
// 2
// If target's list of registered observers already includes a registered
// observer associated with the context object, replace that registered
// observer's options with options.
var registration;
for (var i = 0; i < registrations.length; i++) {
if (registrations[i].observer === this) {
registration = registrations[i];
registration.removeListeners();
registration.options = options;
break;
}
}
// 3.
// Otherwise, add a new registered observer to target's list of registered
// observers with the context object as the observer and options as the
// options, and add target to context object's list of nodes on which it
// is registered.
if (!registration) {
registration = new Registration(this, target, options);
registrations.push(registration);
this.nodes_.push(target);
}
registration.addListeners();
},
disconnect: function() {
this.nodes_.forEach(function(node) {
var registrations = registrationsTable.get(node);
for (var i = 0; i < registrations.length; i++) {
var registration = registrations[i];
if (registration.observer === this) {
registration.removeListeners();
registrations.splice(i, 1);
// Each node can only have one registered observer associated with
// this observer.
break;
}
}
}, this);
this.records_ = [];
},
takeRecords: function() {
var copyOfRecords = this.records_;
this.records_ = [];
return copyOfRecords;
}
};
/**
* @param {string} type
* @param {Node} target
* @constructor
*/
function MutationRecord(type, target) {
this.type = type;
this.target = target;
this.addedNodes = [];
this.removedNodes = [];
this.previousSibling = null;
this.nextSibling = null;
this.attributeName = null;
this.attributeNamespace = null;
this.oldValue = null;
}
function copyMutationRecord(original) {
var record = new MutationRecord(original.type, original.target);
record.addedNodes = original.addedNodes.slice();
record.removedNodes = original.removedNodes.slice();
record.previousSibling = original.previousSibling;
record.nextSibling = original.nextSibling;
record.attributeName = original.attributeName;
record.attributeNamespace = original.attributeNamespace;
record.oldValue = original.oldValue;
return record;
};
// We keep track of the two (possibly one) records used in a single mutation.
var currentRecord, recordWithOldValue;
/**
* Creates a record without |oldValue| and caches it as |currentRecord| for
* later use.
* @param {string} oldValue
* @return {MutationRecord}
*/
function getRecord(type, target) {
return currentRecord = new MutationRecord(type, target);
}
/**
* Gets or creates a record with |oldValue| based in the |currentRecord|
* @param {string} oldValue
* @return {MutationRecord}
*/
function getRecordWithOldValue(oldValue) {
if (recordWithOldValue)
return recordWithOldValue;
recordWithOldValue = copyMutationRecord(currentRecord);
recordWithOldValue.oldValue = oldValue;
return recordWithOldValue;
}
function clearRecords() {
currentRecord = recordWithOldValue = undefined;
}
/**
* @param {MutationRecord} record
* @return {boolean} Whether the record represents a record from the current
* mutation event.
*/
function recordRepresentsCurrentMutation(record) {
return record === recordWithOldValue || record === currentRecord;
}
/**
* Selects which record, if any, to replace the last record in the queue.
* This returns |null| if no record should be replaced.
*
* @param {MutationRecord} lastRecord
* @param {MutationRecord} newRecord
* @param {MutationRecord}
*/
function selectRecord(lastRecord, newRecord) {
if (lastRecord === newRecord)
return lastRecord;
// Check if the the record we are adding represents the same record. If
// so, we keep the one with the oldValue in it.
if (recordWithOldValue && recordRepresentsCurrentMutation(lastRecord))
return recordWithOldValue;
return null;
}
/**
* Class used to represent a registered observer.
* @param {MutationObserver} observer
* @param {Node} target
* @param {MutationObserverInit} options
* @constructor
*/
function Registration(observer, target, options) {
this.observer = observer;
this.target = target;
this.options = options;
this.transientObservedNodes = [];
}
Registration.prototype = {
enqueue: function(record) {
var records = this.observer.records_;
var length = records.length;
// There are cases where we replace the last record with the new record.
// For example if the record represents the same mutation we need to use
// the one with the oldValue. If we get same record (this can happen as we
// walk up the tree) we ignore the new record.
if (records.length > 0) {
var lastRecord = records[length - 1];
var recordToReplaceLast = selectRecord(lastRecord, record);
if (recordToReplaceLast) {
records[length - 1] = recordToReplaceLast;
return;
}
} else {
scheduleCallback(this.observer);
}
records[length] = record;
},
addListeners: function() {
this.addListeners_(this.target);
},
addListeners_: function(node) {
var options = this.options;
if (options.attributes)
node.addEventListener('DOMAttrModified', this, true);
if (options.characterData)
node.addEventListener('DOMCharacterDataModified', this, true);
if (options.childList)
node.addEventListener('DOMNodeInserted', this, true);
if (options.childList || options.subtree)
node.addEventListener('DOMNodeRemoved', this, true);
},
removeListeners: function() {
this.removeListeners_(this.target);
},
removeListeners_: function(node) {
var options = this.options;
if (options.attributes)
node.removeEventListener('DOMAttrModified', this, true);
if (options.characterData)
node.removeEventListener('DOMCharacterDataModified', this, true);
if (options.childList)
node.removeEventListener('DOMNodeInserted', this, true);
if (options.childList || options.subtree)
node.removeEventListener('DOMNodeRemoved', this, true);
},
/**
* Adds a transient observer on node. The transient observer gets removed
* next time we deliver the change records.
* @param {Node} node
*/
addTransientObserver: function(node) {
// Don't add transient observers on the target itself. We already have all
// the required listeners set up on the target.
if (node === this.target)
return;
this.addListeners_(node);
this.transientObservedNodes.push(node);
var registrations = registrationsTable.get(node);
if (!registrations)
registrationsTable.set(node, registrations = []);
// We know that registrations does not contain this because we already
// checked if node === this.target.
registrations.push(this);
},
removeTransientObservers: function() {
var transientObservedNodes = this.transientObservedNodes;
this.transientObservedNodes = [];
transientObservedNodes.forEach(function(node) {
// Transient observers are never added to the target.
this.removeListeners_(node);
var registrations = registrationsTable.get(node);
for (var i = 0; i < registrations.length; i++) {
if (registrations[i] === this) {
registrations.splice(i, 1);
// Each node can only have one registered observer associated with
// this observer.
break;
}
}
}, this);
},
handleEvent: function(e) {
// Stop propagation since we are managing the propagation manually.
// This means that other mutation events on the page will not work
// correctly but that is by design.
e.stopImmediatePropagation();
switch (e.type) {
case 'DOMAttrModified':
// http://dom.spec.whatwg.org/#concept-mo-queue-attributes
var name = e.attrName;
var namespace = e.relatedNode.namespaceURI;
var target = e.target;
// 1.
var record = new getRecord('attributes', target);
record.attributeName = name;
record.attributeNamespace = namespace;
// 2.
var oldValue =
e.attrChange === MutationEvent.ADDITION ? null : e.prevValue;
forEachAncestorAndObserverEnqueueRecord(target, function(options) {
// 3.1, 4.2
if (!options.attributes)
return;
// 3.2, 4.3
if (options.attributeFilter && options.attributeFilter.length &&
options.attributeFilter.indexOf(name) === -1 &&
options.attributeFilter.indexOf(namespace) === -1) {
return;
}
// 3.3, 4.4
if (options.attributeOldValue)
return getRecordWithOldValue(oldValue);
// 3.4, 4.5
return record;
});
break;
case 'DOMCharacterDataModified':
// http://dom.spec.whatwg.org/#concept-mo-queue-characterdata
var target = e.target;
// 1.
var record = getRecord('characterData', target);
// 2.
var oldValue = e.prevValue;
forEachAncestorAndObserverEnqueueRecord(target, function(options) {
// 3.1, 4.2
if (!options.characterData)
return;
// 3.2, 4.3
if (options.characterDataOldValue)
return getRecordWithOldValue(oldValue);
// 3.3, 4.4
return record;
});
break;
case 'DOMNodeRemoved':
this.addTransientObserver(e.target);
// Fall through.
case 'DOMNodeInserted':
// http://dom.spec.whatwg.org/#concept-mo-queue-childlist
var changedNode = e.target;
var addedNodes, removedNodes;
if (e.type === 'DOMNodeInserted') {
addedNodes = [changedNode];
removedNodes = [];
} else {
addedNodes = [];
removedNodes = [changedNode];
}
var previousSibling = changedNode.previousSibling;
var nextSibling = changedNode.nextSibling;
// 1.
var record = getRecord('childList', e.target.parentNode);
record.addedNodes = addedNodes;
record.removedNodes = removedNodes;
record.previousSibling = previousSibling;
record.nextSibling = nextSibling;
forEachAncestorAndObserverEnqueueRecord(e.relatedNode, function(options) {
// 2.1, 3.2
if (!options.childList)
return;
// 2.2, 3.3
return record;
});
}
clearRecords();
}
};
global.JsMutationObserver = JsMutationObserver;
if (!global.MutationObserver) {
global.MutationObserver = JsMutationObserver;
// Explicltly mark MO as polyfilled for user reference.
JsMutationObserver._isPolyfilled = true;
}
})(self);

View File

@@ -1,4 +0,0 @@
[
"../WeakMap/WeakMap.js",
"MutationObserver.js"
]

View File

@@ -1,783 +0,0 @@
/**
* @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
*/
/*
This is a limited shim for ShadowDOM css styling.
https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#styles
The intention here is to support only the styling features which can be
relatively simply implemented. The goal is to allow users to avoid the
most obvious pitfalls and do so without compromising performance significantly.
For ShadowDOM styling that's not covered here, a set of best practices
can be provided that should allow users to accomplish more complex styling.
The following is a list of specific ShadowDOM styling features and a brief
discussion of the approach used to shim.
Shimmed features:
* :host, :host-context: ShadowDOM allows styling of the shadowRoot's host
element using the :host rule. To shim this feature, the :host styles are
reformatted and prefixed with a given scope name and promoted to a
document level stylesheet.
For example, given a scope name of .foo, a rule like this:
:host {
background: red;
}
}
becomes:
.foo {
background: red;
}
* encapsultion: Styles defined within ShadowDOM, apply only to
dom inside the ShadowDOM. Polymer uses one of two techniques to imlement
this feature.
By default, rules are prefixed with the host element tag name
as a descendant selector. This ensures styling does not leak out of the 'top'
of the element's ShadowDOM. For example,
div {
font-weight: bold;
}
becomes:
x-foo div {
font-weight: bold;
}
becomes:
Alternatively, if WebComponents.ShadowCSS.strictStyling is set to true then
selectors are scoped by adding an attribute selector suffix to each
simple selector that contains the host element tag name. Each element
in the element's ShadowDOM template is also given the scope attribute.
Thus, these rules match only elements that have the scope attribute.
For example, given a scope name of x-foo, a rule like this:
div {
font-weight: bold;
}
becomes:
div[x-foo] {
font-weight: bold;
}
Note that elements that are dynamically added to a scope must have the scope
selector added to them manually.
* upper/lower bound encapsulation: Styles which are defined outside a
shadowRoot should not cross the ShadowDOM boundary and should not apply
inside a shadowRoot.
This styling behavior is not emulated. Some possible ways to do this that
were rejected due to complexity and/or performance concerns include: (1) reset
every possible property for every possible selector for a given scope name;
(2) re-implement css in javascript.
As an alternative, users should make sure to use selectors
specific to the scope in which they are working.
* ::distributed: This behavior is not emulated. It's often not necessary
to style the contents of a specific insertion point and instead, descendants
of the host element can be styled selectively. Users can also create an
extra node around an insertion point and style that node's contents
via descendent selectors. For example, with a shadowRoot like this:
<style>
::content(div) {
background: red;
}
</style>
<content></content>
could become:
<style>
/ *@polyfill .content-container div * /
::content(div) {
background: red;
}
</style>
<div class="content-container">
<content></content>
</div>
Note the use of @polyfill in the comment above a ShadowDOM specific style
declaration. This is a directive to the styling shim to use the selector
in comments in lieu of the next selector when running under polyfill.
*/
(function(scope) {
var ShadowCSS = {
strictStyling: false,
registry: {},
// Shim styles for a given root associated with a name and extendsName
// 1. cache root styles by name
// 2. optionally tag root nodes with scope name
// 3. shim polyfill directives /* @polyfill */ and /* @polyfill-rule */
// 4. shim :host and scoping
shimStyling: function(root, name, extendsName) {
var scopeStyles = this.prepareRoot(root, name, extendsName);
var typeExtension = this.isTypeExtension(extendsName);
var scopeSelector = this.makeScopeSelector(name, typeExtension);
// use caching to make working with styles nodes easier and to facilitate
// lookup of extendee
var cssText = stylesToCssText(scopeStyles, true);
cssText = this.scopeCssText(cssText, scopeSelector);
// cache shimmed css on root for user extensibility
if (root) {
root.shimmedStyle = cssText;
}
// add style to document
this.addCssToDocument(cssText, name);
},
/*
* Shim a style element with the given selector. Returns cssText that can
* be included in the document via WebComponents.ShadowCSS.addCssToDocument(css).
*/
shimStyle: function(style, selector) {
return this.shimCssText(style.textContent, selector);
},
/*
* Shim some cssText with the given selector. Returns cssText that can
* be included in the document via WebComponents.ShadowCSS.addCssToDocument(css).
*/
shimCssText: function(cssText, selector) {
cssText = this.insertDirectives(cssText);
return this.scopeCssText(cssText, selector);
},
makeScopeSelector: function(name, typeExtension) {
if (name) {
return typeExtension ? '[is=' + name + ']' : name;
}
return '';
},
isTypeExtension: function(extendsName) {
return extendsName && extendsName.indexOf('-') < 0;
},
prepareRoot: function(root, name, extendsName) {
var def = this.registerRoot(root, name, extendsName);
this.replaceTextInStyles(def.rootStyles, this.insertDirectives);
// remove existing style elements
this.removeStyles(root, def.rootStyles);
// apply strict attr
if (this.strictStyling) {
this.applyScopeToContent(root, name);
}
return def.scopeStyles;
},
removeStyles: function(root, styles) {
for (var i=0, l=styles.length, s; (i<l) && (s=styles[i]); i++) {
s.parentNode.removeChild(s);
}
},
registerRoot: function(root, name, extendsName) {
var def = this.registry[name] = {
root: root,
name: name,
extendsName: extendsName
}
var styles = this.findStyles(root);
def.rootStyles = styles;
def.scopeStyles = def.rootStyles;
var extendee = this.registry[def.extendsName];
if (extendee) {
def.scopeStyles = extendee.scopeStyles.concat(def.scopeStyles);
}
return def;
},
findStyles: function(root) {
if (!root) {
return [];
}
var styles = root.querySelectorAll('style');
return Array.prototype.filter.call(styles, function(s) {
return !s.hasAttribute(NO_SHIM_ATTRIBUTE);
});
},
applyScopeToContent: function(root, name) {
if (root) {
// add the name attribute to each node in root.
Array.prototype.forEach.call(root.querySelectorAll('*'),
function(node) {
node.setAttribute(name, '');
});
// and template contents too
Array.prototype.forEach.call(root.querySelectorAll('template'),
function(template) {
this.applyScopeToContent(template.content, name);
},
this);
}
},
insertDirectives: function(cssText) {
cssText = this.insertPolyfillDirectivesInCssText(cssText);
return this.insertPolyfillRulesInCssText(cssText);
},
/*
* Process styles to convert native ShadowDOM rules that will trip
* up the css parser; we rely on decorating the stylesheet with inert rules.
*
* For example, we convert this rule:
*
* polyfill-next-selector { content: ':host menu-item'; }
* ::content menu-item {
*
* to this:
*
* scopeName menu-item {
*
**/
insertPolyfillDirectivesInCssText: function(cssText) {
// TODO(sorvell): remove either content or comment
cssText = cssText.replace(cssCommentNextSelectorRe, function(match, p1) {
// remove end comment delimiter and add block start
return p1.slice(0, -2) + '{';
});
return cssText.replace(cssContentNextSelectorRe, function(match, p1) {
return p1 + ' {';
});
},
/*
* Process styles to add rules which will only apply under the polyfill
*
* For example, we convert this rule:
*
* polyfill-rule {
* content: ':host menu-item';
* ...
* }
*
* to this:
*
* scopeName menu-item {...}
*
**/
insertPolyfillRulesInCssText: function(cssText) {
// TODO(sorvell): remove either content or comment
cssText = cssText.replace(cssCommentRuleRe, function(match, p1) {
// remove end comment delimiter
return p1.slice(0, -1);
});
return cssText.replace(cssContentRuleRe, function(match, p1, p2, p3) {
var rule = match.replace(p1, '').replace(p2, '');
return p3 + rule;
});
},
/* Ensure styles are scoped. Pseudo-scoping takes a rule like:
*
* .foo {... }
*
* and converts this to
*
* scopeName .foo { ... }
*/
scopeCssText: function(cssText, scopeSelector) {
var unscoped = this.extractUnscopedRulesFromCssText(cssText);
cssText = this.insertPolyfillHostInCssText(cssText);
cssText = this.convertColonHost(cssText);
cssText = this.convertColonHostContext(cssText);
cssText = this.convertShadowDOMSelectors(cssText);
if (scopeSelector) {
var self = this, cssText;
withCssRules(cssText, function(rules) {
cssText = self.scopeRules(rules, scopeSelector);
});
}
cssText = cssText + '\n' + unscoped;
return cssText.trim();
},
/*
* Process styles to add rules which will only apply under the polyfill
* and do not process via CSSOM. (CSSOM is destructive to rules on rare
* occasions, e.g. -webkit-calc on Safari.)
* For example, we convert this rule:
*
* (comment start) @polyfill-unscoped-rule menu-item {
* ... } (comment end)
*
* to this:
*
* menu-item {...}
*
**/
extractUnscopedRulesFromCssText: function(cssText) {
// TODO(sorvell): remove either content or comment
var r = '', m;
while (m = cssCommentUnscopedRuleRe.exec(cssText)) {
r += m[1].slice(0, -1) + '\n\n';
}
while (m = cssContentUnscopedRuleRe.exec(cssText)) {
r += m[0].replace(m[2], '').replace(m[1], m[3]) + '\n\n';
}
return r;
},
/*
* convert a rule like :host(.foo) > .bar { }
*
* to
*
* scopeName.foo > .bar
*/
convertColonHost: function(cssText) {
return this.convertColonRule(cssText, cssColonHostRe,
this.colonHostPartReplacer);
},
/*
* convert a rule like :host-context(.foo) > .bar { }
*
* to
*
* scopeName.foo > .bar, .foo scopeName > .bar { }
*
* and
*
* :host-context(.foo:host) .bar { ... }
*
* to
*
* scopeName.foo .bar { ... }
*/
convertColonHostContext: function(cssText) {
return this.convertColonRule(cssText, cssColonHostContextRe,
this.colonHostContextPartReplacer);
},
convertColonRule: function(cssText, regExp, partReplacer) {
// p1 = :host, p2 = contents of (), p3 rest of rule
return cssText.replace(regExp, function(m, p1, p2, p3) {
p1 = polyfillHostNoCombinator;
if (p2) {
var parts = p2.split(','), r = [];
for (var i=0, l=parts.length, p; (i<l) && (p=parts[i]); i++) {
p = p.trim();
r.push(partReplacer(p1, p, p3));
}
return r.join(',');
} else {
return p1 + p3;
}
});
},
colonHostContextPartReplacer: function(host, part, suffix) {
if (part.match(polyfillHost)) {
return this.colonHostPartReplacer(host, part, suffix);
} else {
return host + part + suffix + ', ' + part + ' ' + host + suffix;
}
},
colonHostPartReplacer: function(host, part, suffix) {
return host + part.replace(polyfillHost, '') + suffix;
},
/*
* Convert combinators like ::shadow and pseudo-elements like ::content
* by replacing with space.
*/
convertShadowDOMSelectors: function(cssText) {
for (var i=0; i < shadowDOMSelectorsRe.length; i++) {
cssText = cssText.replace(shadowDOMSelectorsRe[i], ' ');
}
return cssText;
},
// change a selector like 'div' to 'name div'
scopeRules: function(cssRules, scopeSelector) {
var cssText = '';
if (cssRules) {
Array.prototype.forEach.call(cssRules, function(rule) {
if (rule.selectorText && (rule.style && rule.style.cssText !== undefined)) {
cssText += this.scopeSelector(rule.selectorText, scopeSelector,
this.strictStyling) + ' {\n\t';
cssText += this.propertiesFromRule(rule) + '\n}\n\n';
} else if (rule.type === CSSRule.MEDIA_RULE) {
cssText += '@media ' + rule.media.mediaText + ' {\n';
cssText += this.scopeRules(rule.cssRules, scopeSelector);
cssText += '\n}\n\n';
} else {
// KEYFRAMES_RULE in IE throws when we query cssText
// when it contains a -webkit- property.
// if this happens, we fallback to constructing the rule
// from the CSSRuleSet
// https://connect.microsoft.com/IE/feedbackdetail/view/955703/accessing-csstext-of-a-keyframe-rule-that-contains-a-webkit-property-via-cssom-generates-exception
try {
if (rule.cssText) {
cssText += rule.cssText + '\n\n';
}
} catch(x) {
if (rule.type === CSSRule.KEYFRAMES_RULE && rule.cssRules) {
cssText += this.ieSafeCssTextFromKeyFrameRule(rule);
}
}
}
}, this);
}
return cssText;
},
ieSafeCssTextFromKeyFrameRule: function(rule) {
var cssText = '@keyframes ' + rule.name + ' {';
Array.prototype.forEach.call(rule.cssRules, function(rule) {
cssText += ' ' + rule.keyText + ' {' + rule.style.cssText + '}';
});
cssText += ' }';
return cssText;
},
scopeSelector: function(selector, scopeSelector, strict) {
var r = [], parts = selector.split(',');
parts.forEach(function(p) {
p = p.trim();
if (this.selectorNeedsScoping(p, scopeSelector)) {
p = (strict && !p.match(polyfillHostNoCombinator)) ?
this.applyStrictSelectorScope(p, scopeSelector) :
this.applySelectorScope(p, scopeSelector);
}
r.push(p);
}, this);
return r.join(', ');
},
selectorNeedsScoping: function(selector, scopeSelector) {
if (Array.isArray(scopeSelector)) {
return true;
}
var re = this.makeScopeMatcher(scopeSelector);
return !selector.match(re);
},
makeScopeMatcher: function(scopeSelector) {
scopeSelector = scopeSelector.replace(/\[/g, '\\[').replace(/\]/g, '\\]');
return new RegExp('^(' + scopeSelector + ')' + selectorReSuffix, 'm');
},
applySelectorScope: function(selector, selectorScope) {
return Array.isArray(selectorScope) ?
this.applySelectorScopeList(selector, selectorScope) :
this.applySimpleSelectorScope(selector, selectorScope);
},
// apply an array of selectors
applySelectorScopeList: function(selector, scopeSelectorList) {
var r = [];
for (var i=0, s; (s=scopeSelectorList[i]); i++) {
r.push(this.applySimpleSelectorScope(selector, s));
}
return r.join(', ');
},
// scope via name and [is=name]
applySimpleSelectorScope: function(selector, scopeSelector) {
if (selector.match(polyfillHostRe)) {
selector = selector.replace(polyfillHostNoCombinator, scopeSelector);
return selector.replace(polyfillHostRe, scopeSelector + ' ');
} else {
return scopeSelector + ' ' + selector;
}
},
// return a selector with [name] suffix on each simple selector
// e.g. .foo.bar > .zot becomes .foo[name].bar[name] > .zot[name]
applyStrictSelectorScope: function(selector, scopeSelector) {
scopeSelector = scopeSelector.replace(/\[is=([^\]]*)\]/g, '$1');
var splits = [' ', '>', '+', '~'],
scoped = selector,
attrName = '[' + scopeSelector + ']';
splits.forEach(function(sep) {
var parts = scoped.split(sep);
scoped = parts.map(function(p) {
// remove :host since it should be unnecessary
var t = p.trim().replace(polyfillHostRe, '');
if (t && (splits.indexOf(t) < 0) && (t.indexOf(attrName) < 0)) {
p = t.replace(/([^:]*)(:*)(.*)/, '$1' + attrName + '$2$3');
}
return p;
}).join(sep);
});
return scoped;
},
insertPolyfillHostInCssText: function(selector) {
return selector.replace(colonHostContextRe, polyfillHostContext).replace(
colonHostRe, polyfillHost);
},
propertiesFromRule: function(rule) {
var cssText = rule.style.cssText;
// TODO(sorvell): Safari cssom incorrectly removes quotes from the content
// property. (https://bugs.webkit.org/show_bug.cgi?id=118045)
// don't replace attr rules
if (rule.style.content && !rule.style.content.match(/['"]+|attr/)) {
cssText = cssText.replace(/content:[^;]*;/g, 'content: \'' +
rule.style.content + '\';');
}
// TODO(sorvell): we can workaround this issue here, but we need a list
// of troublesome properties to fix https://github.com/Polymer/platform/issues/53
//
// inherit rules can be omitted from cssText
// TODO(sorvell): remove when Blink bug is fixed:
// https://code.google.com/p/chromium/issues/detail?id=358273
var style = rule.style;
for (var i in style) {
if (style[i] === 'initial') {
cssText += i + ': initial; ';
}
}
return cssText;
},
replaceTextInStyles: function(styles, action) {
if (styles && action) {
if (!(styles instanceof Array)) {
styles = [styles];
}
Array.prototype.forEach.call(styles, function(s) {
s.textContent = action.call(this, s.textContent);
}, this);
}
},
addCssToDocument: function(cssText, name) {
if (cssText.match('@import')) {
addOwnSheet(cssText, name);
} else {
addCssToDocument(cssText);
}
}
};
var selectorRe = /([^{]*)({[\s\S]*?})/gim,
cssCommentRe = /\/\*[^*]*\*+([^/*][^*]*\*+)*\//gim,
// TODO(sorvell): remove either content or comment
cssCommentNextSelectorRe = /\/\*\s*@polyfill ([^*]*\*+([^/*][^*]*\*+)*\/)([^{]*?){/gim,
cssContentNextSelectorRe = /polyfill-next-selector[^}]*content\:[\s]*?['"](.*?)['"][;\s]*}([^{]*?){/gim,
// TODO(sorvell): remove either content or comment
cssCommentRuleRe = /\/\*\s@polyfill-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,
cssContentRuleRe = /(polyfill-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim,
// TODO(sorvell): remove either content or comment
cssCommentUnscopedRuleRe = /\/\*\s@polyfill-unscoped-rule([^*]*\*+([^/*][^*]*\*+)*)\//gim,
cssContentUnscopedRuleRe = /(polyfill-unscoped-rule)[^}]*(content\:[\s]*['"](.*?)['"])[;\s]*[^}]*}/gim,
cssPseudoRe = /::(x-[^\s{,(]*)/gim,
cssPartRe = /::part\(([^)]*)\)/gim,
// note: :host pre-processed to -shadowcsshost.
polyfillHost = '-shadowcsshost',
// note: :host-context pre-processed to -shadowcsshostcontext.
polyfillHostContext = '-shadowcsscontext',
parenSuffix = ')(?:\\((' +
'(?:\\([^)(]*\\)|[^)(]*)+?' +
')\\))?([^,{]*)';
var cssColonHostRe = new RegExp('(' + polyfillHost + parenSuffix, 'gim'),
cssColonHostContextRe = new RegExp('(' + polyfillHostContext + parenSuffix, 'gim'),
selectorReSuffix = '([>\\s~+\[.,{:][\\s\\S]*)?$',
colonHostRe = /\:host/gim,
colonHostContextRe = /\:host-context/gim,
/* host name without combinator */
polyfillHostNoCombinator = polyfillHost + '-no-combinator',
polyfillHostRe = new RegExp(polyfillHost, 'gim'),
polyfillHostContextRe = new RegExp(polyfillHostContext, 'gim'),
shadowDOMSelectorsRe = [
/>>>/g,
/::shadow/g,
/::content/g,
// Deprecated selectors
/\/deep\//g, // former >>>
/\/shadow\//g, // former ::shadow
/\/shadow-deep\//g, // former /deep/
/\^\^/g, // former /shadow/
/\^(?!=)/g // former /shadow-deep/
];
function stylesToCssText(styles, preserveComments) {
var cssText = '';
Array.prototype.forEach.call(styles, function(s) {
cssText += s.textContent + '\n\n';
});
// strip comments for easier processing
if (!preserveComments) {
cssText = cssText.replace(cssCommentRe, '');
}
return cssText;
}
function cssTextToStyle(cssText) {
var style = document.createElement('style');
style.textContent = cssText;
return style;
}
function cssToRules(cssText) {
var style = cssTextToStyle(cssText);
document.head.appendChild(style);
var rules = [];
if (style.sheet) {
// TODO(sorvell): Firefox throws when accessing the rules of a stylesheet
// with an @import
// https://bugzilla.mozilla.org/show_bug.cgi?id=625013
try {
rules = style.sheet.cssRules;
} catch(e) {
//
}
} else {
console.warn('sheet not found', style);
}
style.parentNode.removeChild(style);
return rules;
}
var frame = document.createElement('iframe');
frame.style.display = 'none';
function initFrame() {
frame.initialized = true;
document.body.appendChild(frame);
var doc = frame.contentDocument;
var base = doc.createElement('base');
base.href = document.baseURI;
doc.head.appendChild(base);
}
function inFrame(fn) {
if (!frame.initialized) {
initFrame();
}
document.body.appendChild(frame);
fn(frame.contentDocument);
document.body.removeChild(frame);
}
// TODO(sorvell): use an iframe if the cssText contains an @import to workaround
// https://code.google.com/p/chromium/issues/detail?id=345114
var isChrome = navigator.userAgent.match('Chrome');
function withCssRules(cssText, callback) {
if (!callback) {
return;
}
var rules;
if (cssText.match('@import') && isChrome) {
var style = cssTextToStyle(cssText);
inFrame(function(doc) {
doc.head.appendChild(style.impl);
rules = Array.prototype.slice.call(style.sheet.cssRules, 0);
callback(rules);
});
} else {
rules = cssToRules(cssText);
callback(rules);
}
}
function rulesToCss(cssRules) {
for (var i=0, css=[]; i < cssRules.length; i++) {
css.push(cssRules[i].cssText);
}
return css.join('\n\n');
}
function addCssToDocument(cssText) {
if (cssText) {
getSheet().appendChild(document.createTextNode(cssText));
}
}
function addOwnSheet(cssText, name) {
var style = cssTextToStyle(cssText);
style.setAttribute(name, '');
style.setAttribute(SHIMMED_ATTRIBUTE, '');
document.head.appendChild(style);
}
var SHIM_ATTRIBUTE = 'shim-shadowdom';
var SHIMMED_ATTRIBUTE = 'shim-shadowdom-css';
var NO_SHIM_ATTRIBUTE = 'no-shim';
var sheet;
function getSheet() {
if (!sheet) {
sheet = document.createElement("style");
sheet.setAttribute(SHIMMED_ATTRIBUTE, '');
sheet[SHIMMED_ATTRIBUTE] = true;
}
return sheet;
}
// add polyfill stylesheet to document
if (window.ShadowDOMPolyfill) {
addCssToDocument('style { display: none !important; }\n');
var doc = ShadowDOMPolyfill.wrap(document);
var head = doc.querySelector('head');
head.insertBefore(getSheet(), head.childNodes[0]);
// TODO(sorvell): monkey-patching HTMLImports is abusive;
// consider a better solution.
document.addEventListener('DOMContentLoaded', function() {
var urlResolver = scope.urlResolver;
if (window.HTMLImports && !HTMLImports.useNative) {
var SHIM_SHEET_SELECTOR = 'link[rel=stylesheet]' +
'[' + SHIM_ATTRIBUTE + ']';
var SHIM_STYLE_SELECTOR = 'style[' + SHIM_ATTRIBUTE + ']';
HTMLImports.importer.documentPreloadSelectors += ',' + SHIM_SHEET_SELECTOR;
HTMLImports.importer.importsPreloadSelectors += ',' + SHIM_SHEET_SELECTOR;
HTMLImports.parser.documentSelectors = [
HTMLImports.parser.documentSelectors,
SHIM_SHEET_SELECTOR,
SHIM_STYLE_SELECTOR
].join(',');
var originalParseGeneric = HTMLImports.parser.parseGeneric;
HTMLImports.parser.parseGeneric = function(elt) {
if (elt[SHIMMED_ATTRIBUTE]) {
return;
}
var style = elt.__importElement || elt;
if (!style.hasAttribute(SHIM_ATTRIBUTE)) {
originalParseGeneric.call(this, elt);
return;
}
if (elt.__resource) {
style = elt.ownerDocument.createElement('style');
style.textContent = elt.__resource;
}
// relay on HTMLImports for path fixup
HTMLImports.path.resolveUrlsInStyle(style, elt.href);
style.textContent = ShadowCSS.shimStyle(style);
style.removeAttribute(SHIM_ATTRIBUTE, '');
style.setAttribute(SHIMMED_ATTRIBUTE, '');
style[SHIMMED_ATTRIBUTE] = true;
// place in document
if (style.parentNode !== head) {
// replace links in head
if (elt.parentNode === head) {
head.replaceChild(style, elt);
} else {
this.addElementToDocument(style);
}
}
style.__importParsed = true;
this.markParsingComplete(elt);
this.parseNext();
}
var hasResource = HTMLImports.parser.hasResource;
HTMLImports.parser.hasResource = function(node) {
if (node.localName === 'link' && node.rel === 'stylesheet' &&
node.hasAttribute(SHIM_ATTRIBUTE)) {
return (node.__resource);
} else {
return hasResource.call(this, node);
}
}
}
});
}
// exports
scope.ShadowCSS = ShadowCSS;
})(window.WebComponents);

View File

@@ -1,262 +0,0 @@
/**
* @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(scope) {
'use strict';
function newSplice(index, removed, addedCount) {
return {
index: index,
removed: removed,
addedCount: addedCount
};
}
var EDIT_LEAVE = 0;
var EDIT_UPDATE = 1;
var EDIT_ADD = 2;
var EDIT_DELETE = 3;
function ArraySplice() {}
ArraySplice.prototype = {
// Note: This function is *based* on the computation of the Levenshtein
// "edit" distance. The one change is that "updates" are treated as two
// edits - not one. With Array splices, an update is really a delete
// followed by an add. By retaining this, we optimize for "keeping" the
// maximum array items in the original array. For example:
//
// 'xxxx123' -> '123yyyy'
//
// With 1-edit updates, the shortest path would be just to update all seven
// characters. With 2-edit updates, we delete 4, leave 3, and add 4. This
// leaves the substring '123' intact.
calcEditDistances: function(current, currentStart, currentEnd,
old, oldStart, oldEnd) {
// "Deletion" columns
var rowCount = oldEnd - oldStart + 1;
var columnCount = currentEnd - currentStart + 1;
var distances = new Array(rowCount);
// "Addition" rows. Initialize null column.
for (var i = 0; i < rowCount; i++) {
distances[i] = new Array(columnCount);
distances[i][0] = i;
}
// Initialize null row
for (var j = 0; j < columnCount; j++)
distances[0][j] = j;
for (var i = 1; i < rowCount; i++) {
for (var j = 1; j < columnCount; j++) {
if (this.equals(current[currentStart + j - 1], old[oldStart + i - 1]))
distances[i][j] = distances[i - 1][j - 1];
else {
var north = distances[i - 1][j] + 1;
var west = distances[i][j - 1] + 1;
distances[i][j] = north < west ? north : west;
}
}
}
return distances;
},
// This starts at the final weight, and walks "backward" by finding
// the minimum previous weight recursively until the origin of the weight
// matrix.
spliceOperationsFromEditDistances: function(distances) {
var i = distances.length - 1;
var j = distances[0].length - 1;
var current = distances[i][j];
var edits = [];
while (i > 0 || j > 0) {
if (i == 0) {
edits.push(EDIT_ADD);
j--;
continue;
}
if (j == 0) {
edits.push(EDIT_DELETE);
i--;
continue;
}
var northWest = distances[i - 1][j - 1];
var west = distances[i - 1][j];
var north = distances[i][j - 1];
var min;
if (west < north)
min = west < northWest ? west : northWest;
else
min = north < northWest ? north : northWest;
if (min == northWest) {
if (northWest == current) {
edits.push(EDIT_LEAVE);
} else {
edits.push(EDIT_UPDATE);
current = northWest;
}
i--;
j--;
} else if (min == west) {
edits.push(EDIT_DELETE);
i--;
current = west;
} else {
edits.push(EDIT_ADD);
j--;
current = north;
}
}
edits.reverse();
return edits;
},
/**
* Splice Projection functions:
*
* A splice map is a representation of how a previous array of items
* was transformed into a new array of items. Conceptually it is a list of
* tuples of
*
* <index, removed, addedCount>
*
* which are kept in ascending index order of. The tuple represents that at
* the |index|, |removed| sequence of items were removed, and counting forward
* from |index|, |addedCount| items were added.
*/
/**
* Lacking individual splice mutation information, the minimal set of
* splices can be synthesized given the previous state and final state of an
* array. The basic approach is to calculate the edit distance matrix and
* choose the shortest path through it.
*
* Complexity: O(l * p)
* l: The length of the current array
* p: The length of the old array
*/
calcSplices: function(current, currentStart, currentEnd,
old, oldStart, oldEnd) {
var prefixCount = 0;
var suffixCount = 0;
var minLength = Math.min(currentEnd - currentStart, oldEnd - oldStart);
if (currentStart == 0 && oldStart == 0)
prefixCount = this.sharedPrefix(current, old, minLength);
if (currentEnd == current.length && oldEnd == old.length)
suffixCount = this.sharedSuffix(current, old, minLength - prefixCount);
currentStart += prefixCount;
oldStart += prefixCount;
currentEnd -= suffixCount;
oldEnd -= suffixCount;
if (currentEnd - currentStart == 0 && oldEnd - oldStart == 0)
return [];
if (currentStart == currentEnd) {
var splice = newSplice(currentStart, [], 0);
while (oldStart < oldEnd)
splice.removed.push(old[oldStart++]);
return [ splice ];
} else if (oldStart == oldEnd)
return [ newSplice(currentStart, [], currentEnd - currentStart) ];
var ops = this.spliceOperationsFromEditDistances(
this.calcEditDistances(current, currentStart, currentEnd,
old, oldStart, oldEnd));
var splice = undefined;
var splices = [];
var index = currentStart;
var oldIndex = oldStart;
for (var i = 0; i < ops.length; i++) {
switch(ops[i]) {
case EDIT_LEAVE:
if (splice) {
splices.push(splice);
splice = undefined;
}
index++;
oldIndex++;
break;
case EDIT_UPDATE:
if (!splice)
splice = newSplice(index, [], 0);
splice.addedCount++;
index++;
splice.removed.push(old[oldIndex]);
oldIndex++;
break;
case EDIT_ADD:
if (!splice)
splice = newSplice(index, [], 0);
splice.addedCount++;
index++;
break;
case EDIT_DELETE:
if (!splice)
splice = newSplice(index, [], 0);
splice.removed.push(old[oldIndex]);
oldIndex++;
break;
}
}
if (splice) {
splices.push(splice);
}
return splices;
},
sharedPrefix: function(current, old, searchLength) {
for (var i = 0; i < searchLength; i++)
if (!this.equals(current[i], old[i]))
return i;
return searchLength;
},
sharedSuffix: function(current, old, searchLength) {
var index1 = current.length;
var index2 = old.length;
var count = 0;
while (count < searchLength && this.equals(current[--index1], old[--index2]))
count++;
return count;
},
calculateSplices: function(current, previous) {
return this.calcSplices(current, 0, current.length, previous, 0,
previous.length);
},
equals: function(currentValue, previousValue) {
return currentValue === previousValue;
}
};
// exports
scope.ArraySplice = ArraySplice;
})(window.ShadowDOMPolyfill);

View File

@@ -1,385 +0,0 @@
/**
* @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(scope) {
'use strict';
var setEndOfMicrotask = scope.setEndOfMicrotask
var wrapIfNeeded = scope.wrapIfNeeded
var wrappers = scope.wrappers;
var registrationsTable = new WeakMap();
var globalMutationObservers = [];
var isScheduled = false;
function scheduleCallback(observer) {
if (observer.scheduled_)
return;
observer.scheduled_ = true;
globalMutationObservers.push(observer);
if (isScheduled)
return;
setEndOfMicrotask(notifyObservers);
isScheduled = true;
}
// http://dom.spec.whatwg.org/#mutation-observers
function notifyObservers() {
isScheduled = false;
while (globalMutationObservers.length) {
var notifyList = globalMutationObservers;
globalMutationObservers = [];
// Deliver changes in birth order of the MutationObservers.
notifyList.sort(function(x, y) { return x.uid_ - y.uid_; });
for (var i = 0; i < notifyList.length; i++) {
var mo = notifyList[i];
mo.scheduled_ = false;
var queue = mo.takeRecords();
removeTransientObserversFor(mo);
if (queue.length) {
mo.callback_(queue, mo);
}
}
}
}
/**
* @param {string} type
* @param {Node} target
* @constructor
*/
function MutationRecord(type, target) {
this.type = type;
this.target = target;
this.addedNodes = new wrappers.NodeList();
this.removedNodes = new wrappers.NodeList();
this.previousSibling = null;
this.nextSibling = null;
this.attributeName = null;
this.attributeNamespace = null;
this.oldValue = null;
}
/**
* Registers transient observers to ancestor and its ancesors for the node
* which was removed.
* @param {!Node} ancestor
* @param {!Node} node
*/
function registerTransientObservers(ancestor, node) {
for (; ancestor; ancestor = ancestor.parentNode) {
var registrations = registrationsTable.get(ancestor);
if (!registrations)
continue;
for (var i = 0; i < registrations.length; i++) {
var registration = registrations[i];
if (registration.options.subtree)
registration.addTransientObserver(node);
}
}
}
function removeTransientObserversFor(observer) {
for (var i = 0; i < observer.nodes_.length; i++) {
var node = observer.nodes_[i];
var registrations = registrationsTable.get(node);
if (!registrations)
return;
for (var j = 0; j < registrations.length; j++) {
var registration = registrations[j];
if (registration.observer === observer)
registration.removeTransientObservers();
}
}
}
// http://dom.spec.whatwg.org/#queue-a-mutation-record
function enqueueMutation(target, type, data) {
// 1.
var interestedObservers = Object.create(null);
var associatedStrings = Object.create(null);
// 2.
for (var node = target; node; node = node.parentNode) {
// 3.
var registrations = registrationsTable.get(node);
if (!registrations)
continue;
for (var j = 0; j < registrations.length; j++) {
var registration = registrations[j];
var options = registration.options;
// 1.
if (node !== target && !options.subtree)
continue;
// 2.
if (type === 'attributes' && !options.attributes)
continue;
// 3. If type is "attributes", options's attributeFilter is present, and
// either options's attributeFilter does not contain name or namespace
// is non-null, continue.
if (type === 'attributes' && options.attributeFilter &&
(data.namespace !== null ||
options.attributeFilter.indexOf(data.name) === -1)) {
continue;
}
// 4.
if (type === 'characterData' && !options.characterData)
continue;
// 5.
if (type === 'childList' && !options.childList)
continue;
// 6.
var observer = registration.observer;
interestedObservers[observer.uid_] = observer;
// 7. If either type is "attributes" and options's attributeOldValue is
// true, or type is "characterData" and options's characterDataOldValue
// is true, set the paired string of registered observer's observer in
// interested observers to oldValue.
if (type === 'attributes' && options.attributeOldValue ||
type === 'characterData' && options.characterDataOldValue) {
associatedStrings[observer.uid_] = data.oldValue;
}
}
}
// 4.
for (var uid in interestedObservers) {
var observer = interestedObservers[uid];
var record = new MutationRecord(type, target);
// 2.
if ('name' in data && 'namespace' in data) {
record.attributeName = data.name;
record.attributeNamespace = data.namespace;
}
// 3.
if (data.addedNodes)
record.addedNodes = data.addedNodes;
// 4.
if (data.removedNodes)
record.removedNodes = data.removedNodes;
// 5.
if (data.previousSibling)
record.previousSibling = data.previousSibling;
// 6.
if (data.nextSibling)
record.nextSibling = data.nextSibling;
// 7.
if (associatedStrings[uid] !== undefined)
record.oldValue = associatedStrings[uid];
// 8.
scheduleCallback(observer);
observer.records_.push(record);
}
}
var slice = Array.prototype.slice;
/**
* @param {!Object} options
* @constructor
*/
function MutationObserverOptions(options) {
this.childList = !!options.childList;
this.subtree = !!options.subtree;
// 1. If either options' attributeOldValue or attributeFilter is present
// and options' attributes is omitted, set options' attributes to true.
if (!('attributes' in options) &&
('attributeOldValue' in options || 'attributeFilter' in options)) {
this.attributes = true;
} else {
this.attributes = !!options.attributes;
}
// 2. If options' characterDataOldValue is present and options'
// characterData is omitted, set options' characterData to true.
if ('characterDataOldValue' in options && !('characterData' in options))
this.characterData = true;
else
this.characterData = !!options.characterData;
// 3. & 4.
if (!this.attributes &&
(options.attributeOldValue || 'attributeFilter' in options) ||
// 5.
!this.characterData && options.characterDataOldValue) {
throw new TypeError();
}
this.characterData = !!options.characterData;
this.attributeOldValue = !!options.attributeOldValue;
this.characterDataOldValue = !!options.characterDataOldValue;
if ('attributeFilter' in options) {
if (options.attributeFilter == null ||
typeof options.attributeFilter !== 'object') {
throw new TypeError();
}
this.attributeFilter = slice.call(options.attributeFilter);
} else {
this.attributeFilter = null;
}
}
var uidCounter = 0;
/**
* The class that maps to the DOM MutationObserver interface.
* @param {Function} callback.
* @constructor
*/
function MutationObserver(callback) {
this.callback_ = callback;
this.nodes_ = [];
this.records_ = [];
this.uid_ = ++uidCounter;
this.scheduled_ = false;
}
MutationObserver.prototype = {
constructor: MutationObserver,
// http://dom.spec.whatwg.org/#dom-mutationobserver-observe
observe: function(target, options) {
target = wrapIfNeeded(target);
var newOptions = new MutationObserverOptions(options);
// 6.
var registration;
var registrations = registrationsTable.get(target);
if (!registrations)
registrationsTable.set(target, registrations = []);
for (var i = 0; i < registrations.length; i++) {
if (registrations[i].observer === this) {
registration = registrations[i];
// 6.1.
registration.removeTransientObservers();
// 6.2.
registration.options = newOptions;
}
}
// 7.
if (!registration) {
registration = new Registration(this, target, newOptions);
registrations.push(registration);
this.nodes_.push(target);
}
},
// http://dom.spec.whatwg.org/#dom-mutationobserver-disconnect
disconnect: function() {
this.nodes_.forEach(function(node) {
var registrations = registrationsTable.get(node);
for (var i = 0; i < registrations.length; i++) {
var registration = registrations[i];
if (registration.observer === this) {
registrations.splice(i, 1);
// Each node can only have one registered observer associated with
// this observer.
break;
}
}
}, this);
this.records_ = [];
},
takeRecords: function() {
var copyOfRecords = this.records_;
this.records_ = [];
return copyOfRecords;
}
};
/**
* Class used to represent a registered observer.
* @param {MutationObserver} observer
* @param {Node} target
* @param {MutationObserverOptions} options
* @constructor
*/
function Registration(observer, target, options) {
this.observer = observer;
this.target = target;
this.options = options;
this.transientObservedNodes = [];
}
Registration.prototype = {
/**
* Adds a transient observer on node. The transient observer gets removed
* next time we deliver the change records.
* @param {Node} node
*/
addTransientObserver: function(node) {
// Don't add transient observers on the target itself. We already have all
// the required listeners set up on the target.
if (node === this.target)
return;
// Make sure we remove transient observers at the end of microtask, even
// if we didn't get any change records.
scheduleCallback(this.observer);
this.transientObservedNodes.push(node);
var registrations = registrationsTable.get(node);
if (!registrations)
registrationsTable.set(node, registrations = []);
// We know that registrations does not contain this because we already
// checked if node === this.target.
registrations.push(this);
},
removeTransientObservers: function() {
var transientObservedNodes = this.transientObservedNodes;
this.transientObservedNodes = [];
for (var i = 0; i < transientObservedNodes.length; i++) {
var node = transientObservedNodes[i];
var registrations = registrationsTable.get(node);
for (var j = 0; j < registrations.length; j++) {
if (registrations[j] === this) {
registrations.splice(j, 1);
// Each node can only have one registered observer associated with
// this observer.
break;
}
}
}
}
};
scope.enqueueMutation = enqueueMutation;
scope.registerTransientObservers = registerTransientObservers;
scope.wrappers.MutationObserver = MutationObserver;
scope.wrappers.MutationRecord = MutationRecord;
})(window.ShadowDOMPolyfill);

View File

@@ -1,79 +0,0 @@
/**
* @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() {
var thisFile = 'ShadowDOM.js';
var base = '';
Array.prototype.forEach.call(document.querySelectorAll('script[src]'), function(s) {
var src = s.getAttribute('src');
var re = new RegExp(thisFile + '[^\\\\]*');
var match = src.match(re);
if (match) {
base = src.slice(0, -match[0].length);
}
});
[
'../WeakMap/WeakMap.js',
'wrappers.js',
'ArraySplice.js',
'microtask.js',
'MutationObserver.js',
'TreeScope.js',
'wrappers/events.js',
'wrappers/TouchEvent.js',
'wrappers/NodeList.js',
'wrappers/HTMLCollection.js',
'wrappers/Node.js',
'querySelector.js',
'wrappers/node-interfaces.js',
'wrappers/CharacterData.js',
'wrappers/Text.js',
'wrappers/DOMTokenList.js',
'wrappers/Element.js',
'wrappers/HTMLElement.js',
'wrappers/HTMLCanvasElement.js',
'wrappers/HTMLContentElement.js',
'wrappers/HTMLFormElement.js',
'wrappers/HTMLImageElement.js',
'wrappers/HTMLShadowElement.js',
'wrappers/HTMLTemplateElement.js',
'wrappers/HTMLMediaElement.js',
'wrappers/HTMLAudioElement.js',
'wrappers/HTMLOptionElement.js',
'wrappers/HTMLSelectElement.js',
'wrappers/HTMLTableElement.js',
'wrappers/HTMLTableSectionElement.js',
'wrappers/HTMLTableRowElement.js',
'wrappers/HTMLUnknownElement.js',
'wrappers/SVGElement.js',
'wrappers/SVGUseElement.js',
'wrappers/SVGElementInstance.js',
'wrappers/CanvasRenderingContext2D.js',
'wrappers/WebGLRenderingContext.js',
'wrappers/generic.js',
'wrappers/ShadowRoot.js',
'wrappers/Range.js',
'ShadowRenderer.js',
'wrappers/elements-with-form-property.js',
'wrappers/Selection.js',
'wrappers/TreeWalker.js',
'wrappers/Document.js',
'wrappers/Window.js',
'wrappers/DataTransfer.js',
'wrappers/FormData.js',
'wrappers/XMLHttpRequest.js',
'wrappers/override-constructors.js'
].forEach(function(src) {
document.write('<script src="' + base + src + '"></script>');
});
})();

View File

@@ -1,671 +0,0 @@
/**
* @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(scope) {
'use strict';
var Element = scope.wrappers.Element;
var HTMLContentElement = scope.wrappers.HTMLContentElement;
var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
var Node = scope.wrappers.Node;
var ShadowRoot = scope.wrappers.ShadowRoot;
var assert = scope.assert;
var getTreeScope = scope.getTreeScope;
var mixin = scope.mixin;
var oneOf = scope.oneOf;
var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var ArraySplice = scope.ArraySplice;
/**
* Updates the fields of a wrapper to a snapshot of the logical DOM as needed.
* Up means parentNode
* Sideways means previous and next sibling.
* @param {!Node} wrapper
*/
function updateWrapperUpAndSideways(wrapper) {
wrapper.previousSibling_ = wrapper.previousSibling;
wrapper.nextSibling_ = wrapper.nextSibling;
wrapper.parentNode_ = wrapper.parentNode;
}
/**
* Updates the fields of a wrapper to a snapshot of the logical DOM as needed.
* Down means first and last child
* @param {!Node} wrapper
*/
function updateWrapperDown(wrapper) {
wrapper.firstChild_ = wrapper.firstChild;
wrapper.lastChild_ = wrapper.lastChild;
}
function updateAllChildNodes(parentNodeWrapper) {
assert(parentNodeWrapper instanceof Node);
for (var childWrapper = parentNodeWrapper.firstChild;
childWrapper;
childWrapper = childWrapper.nextSibling) {
updateWrapperUpAndSideways(childWrapper);
}
updateWrapperDown(parentNodeWrapper);
}
function insertBefore(parentNodeWrapper, newChildWrapper, refChildWrapper) {
var parentNode = unwrap(parentNodeWrapper);
var newChild = unwrap(newChildWrapper);
var refChild = refChildWrapper ? unwrap(refChildWrapper) : null;
remove(newChildWrapper);
updateWrapperUpAndSideways(newChildWrapper);
if (!refChildWrapper) {
parentNodeWrapper.lastChild_ = parentNodeWrapper.lastChild;
if (parentNodeWrapper.lastChild === parentNodeWrapper.firstChild)
parentNodeWrapper.firstChild_ = parentNodeWrapper.firstChild;
var lastChildWrapper = wrap(parentNode.lastChild);
if (lastChildWrapper)
lastChildWrapper.nextSibling_ = lastChildWrapper.nextSibling;
} else {
if (parentNodeWrapper.firstChild === refChildWrapper)
parentNodeWrapper.firstChild_ = refChildWrapper;
refChildWrapper.previousSibling_ = refChildWrapper.previousSibling;
}
scope.originalInsertBefore.call(parentNode, newChild, refChild);
}
function remove(nodeWrapper) {
var node = unwrap(nodeWrapper)
var parentNode = node.parentNode;
if (!parentNode)
return;
var parentNodeWrapper = wrap(parentNode);
updateWrapperUpAndSideways(nodeWrapper);
if (nodeWrapper.previousSibling)
nodeWrapper.previousSibling.nextSibling_ = nodeWrapper;
if (nodeWrapper.nextSibling)
nodeWrapper.nextSibling.previousSibling_ = nodeWrapper;
if (parentNodeWrapper.lastChild === nodeWrapper)
parentNodeWrapper.lastChild_ = nodeWrapper;
if (parentNodeWrapper.firstChild === nodeWrapper)
parentNodeWrapper.firstChild_ = nodeWrapper;
scope.originalRemoveChild.call(parentNode, node);
}
var distributedNodesTable = new WeakMap();
var destinationInsertionPointsTable = new WeakMap();
var rendererForHostTable = new WeakMap();
function resetDistributedNodes(insertionPoint) {
distributedNodesTable.set(insertionPoint, []);
}
function getDistributedNodes(insertionPoint) {
var rv = distributedNodesTable.get(insertionPoint);
if (!rv)
distributedNodesTable.set(insertionPoint, rv = []);
return rv;
}
function getChildNodesSnapshot(node) {
var result = [], i = 0;
for (var child = node.firstChild; child; child = child.nextSibling) {
result[i++] = child;
}
return result;
}
var request = oneOf(window, [
'requestAnimationFrame',
'mozRequestAnimationFrame',
'webkitRequestAnimationFrame',
'setTimeout'
]);
var pendingDirtyRenderers = [];
var renderTimer;
function renderAllPending() {
// TODO(arv): Order these in document order. That way we do not have to
// render something twice.
for (var i = 0; i < pendingDirtyRenderers.length; i++) {
var renderer = pendingDirtyRenderers[i];
var parentRenderer = renderer.parentRenderer;
if (parentRenderer && parentRenderer.dirty)
continue;
renderer.render();
}
pendingDirtyRenderers = [];
}
function handleRequestAnimationFrame() {
renderTimer = null;
renderAllPending();
}
/**
* Returns existing shadow renderer for a host or creates it if it is needed.
* @params {!Element} host
* @return {!ShadowRenderer}
*/
function getRendererForHost(host) {
var renderer = rendererForHostTable.get(host);
if (!renderer) {
renderer = new ShadowRenderer(host);
rendererForHostTable.set(host, renderer);
}
return renderer;
}
function getShadowRootAncestor(node) {
var root = getTreeScope(node).root;
if (root instanceof ShadowRoot)
return root;
return null;
}
function getRendererForShadowRoot(shadowRoot) {
return getRendererForHost(shadowRoot.host);
}
var spliceDiff = new ArraySplice();
spliceDiff.equals = function(renderNode, rawNode) {
return unwrap(renderNode.node) === rawNode;
};
/**
* RenderNode is used as an in memory "render tree". When we render the
* composed tree we create a tree of RenderNodes, then we diff this against
* the real DOM tree and make minimal changes as needed.
*/
function RenderNode(node) {
this.skip = false;
this.node = node;
this.childNodes = [];
}
RenderNode.prototype = {
append: function(node) {
var rv = new RenderNode(node);
this.childNodes.push(rv);
return rv;
},
sync: function(opt_added) {
if (this.skip)
return;
var nodeWrapper = this.node;
// plain array of RenderNodes
var newChildren = this.childNodes;
// plain array of real nodes.
var oldChildren = getChildNodesSnapshot(unwrap(nodeWrapper));
var added = opt_added || new WeakMap();
var splices = spliceDiff.calculateSplices(newChildren, oldChildren);
var newIndex = 0, oldIndex = 0;
var lastIndex = 0;
for (var i = 0; i < splices.length; i++) {
var splice = splices[i];
for (; lastIndex < splice.index; lastIndex++) {
oldIndex++;
newChildren[newIndex++].sync(added);
}
var removedCount = splice.removed.length;
for (var j = 0; j < removedCount; j++) {
var wrapper = wrap(oldChildren[oldIndex++]);
if (!added.get(wrapper))
remove(wrapper);
}
var addedCount = splice.addedCount;
var refNode = oldChildren[oldIndex] && wrap(oldChildren[oldIndex]);
for (var j = 0; j < addedCount; j++) {
var newChildRenderNode = newChildren[newIndex++];
var newChildWrapper = newChildRenderNode.node;
insertBefore(nodeWrapper, newChildWrapper, refNode);
// Keep track of added so that we do not remove the node after it
// has been added.
added.set(newChildWrapper, true);
newChildRenderNode.sync(added);
}
lastIndex += addedCount;
}
for (var i = lastIndex; i < newChildren.length; i++) {
newChildren[i].sync(added);
}
}
};
function ShadowRenderer(host) {
this.host = host;
this.dirty = false;
this.invalidateAttributes();
this.associateNode(host);
}
ShadowRenderer.prototype = {
// http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#rendering-shadow-trees
render: function(opt_renderNode) {
if (!this.dirty)
return;
this.invalidateAttributes();
var host = this.host;
this.distribution(host);
var renderNode = opt_renderNode || new RenderNode(host);
this.buildRenderTree(renderNode, host);
var topMostRenderer = !opt_renderNode;
if (topMostRenderer)
renderNode.sync();
this.dirty = false;
},
get parentRenderer() {
return getTreeScope(this.host).renderer;
},
invalidate: function() {
if (!this.dirty) {
this.dirty = true;
var parentRenderer = this.parentRenderer;
if (parentRenderer)
parentRenderer.invalidate();
pendingDirtyRenderers.push(this);
if (renderTimer)
return;
renderTimer = window[request](handleRequestAnimationFrame, 0);
}
},
// http://w3c.github.io/webcomponents/spec/shadow/#distribution-algorithms
distribution: function(root) {
this.resetAllSubtrees(root);
this.distributionResolution(root);
},
resetAll: function(node) {
if (isInsertionPoint(node))
resetDistributedNodes(node);
else
resetDestinationInsertionPoints(node);
this.resetAllSubtrees(node);
},
resetAllSubtrees: function(node) {
for (var child = node.firstChild; child; child = child.nextSibling) {
this.resetAll(child);
}
if (node.shadowRoot)
this.resetAll(node.shadowRoot);
if (node.olderShadowRoot)
this.resetAll(node.olderShadowRoot);
},
// http://w3c.github.io/webcomponents/spec/shadow/#distribution-results
distributionResolution: function(node) {
if (isShadowHost(node)) {
var shadowHost = node;
// 1.1
var pool = poolPopulation(shadowHost);
var shadowTrees = getShadowTrees(shadowHost);
// 1.2
for (var i = 0; i < shadowTrees.length; i++) {
// 1.2.1
this.poolDistribution(shadowTrees[i], pool);
}
// 1.3
for (var i = shadowTrees.length - 1; i >= 0; i--) {
var shadowTree = shadowTrees[i];
// 1.3.1
// TODO(arv): We should keep the shadow insertion points on the
// shadow root (or renderer) so we don't have to search the tree
// every time.
var shadow = getShadowInsertionPoint(shadowTree);
// 1.3.2
if (shadow) {
// 1.3.2.1
var olderShadowRoot = shadowTree.olderShadowRoot;
if (olderShadowRoot) {
// 1.3.2.1.1
pool = poolPopulation(olderShadowRoot);
}
// 1.3.2.2
for (var j = 0; j < pool.length; j++) {
// 1.3.2.2.1
destributeNodeInto(pool[j], shadow);
}
}
// 1.3.3
this.distributionResolution(shadowTree);
}
}
for (var child = node.firstChild; child; child = child.nextSibling) {
this.distributionResolution(child);
}
},
// http://w3c.github.io/webcomponents/spec/shadow/#dfn-pool-distribution-algorithm
poolDistribution: function (node, pool) {
if (node instanceof HTMLShadowElement)
return;
if (node instanceof HTMLContentElement) {
var content = node;
this.updateDependentAttributes(content.getAttribute('select'));
var anyDistributed = false;
// 1.1
for (var i = 0; i < pool.length; i++) {
var node = pool[i];
if (!node)
continue;
if (matches(node, content)) {
destributeNodeInto(node, content);
pool[i] = undefined;
anyDistributed = true;
}
}
// 1.2
// Fallback content
if (!anyDistributed) {
for (var child = content.firstChild;
child;
child = child.nextSibling) {
destributeNodeInto(child, content);
}
}
return;
}
for (var child = node.firstChild; child; child = child.nextSibling) {
this.poolDistribution(child, pool);
}
},
buildRenderTree: function(renderNode, node) {
var children = this.compose(node);
for (var i = 0; i < children.length; i++) {
var child = children[i];
var childRenderNode = renderNode.append(child);
this.buildRenderTree(childRenderNode, child);
}
if (isShadowHost(node)) {
var renderer = getRendererForHost(node);
renderer.dirty = false;
}
},
compose: function(node) {
var children = [];
var p = node.shadowRoot || node;
for (var child = p.firstChild; child; child = child.nextSibling) {
if (isInsertionPoint(child)) {
this.associateNode(p);
var distributedNodes = getDistributedNodes(child);
for (var j = 0; j < distributedNodes.length; j++) {
var distributedNode = distributedNodes[j];
if (isFinalDestination(child, distributedNode))
children.push(distributedNode);
}
} else {
children.push(child);
}
}
return children;
},
/**
* Invalidates the attributes used to keep track of which attributes may
* cause the renderer to be invalidated.
*/
invalidateAttributes: function() {
this.attributes = Object.create(null);
},
/**
* Parses the selector and makes this renderer dependent on the attribute
* being used in the selector.
* @param {string} selector
*/
updateDependentAttributes: function(selector) {
if (!selector)
return;
var attributes = this.attributes;
// .class
if (/\.\w+/.test(selector))
attributes['class'] = true;
// #id
if (/#\w+/.test(selector))
attributes['id'] = true;
selector.replace(/\[\s*([^\s=\|~\]]+)/g, function(_, name) {
attributes[name] = true;
});
// Pseudo selectors have been removed from the spec.
},
dependsOnAttribute: function(name) {
return this.attributes[name];
},
associateNode: function(node) {
unsafeUnwrap(node).polymerShadowRenderer_ = this;
}
};
// http://w3c.github.io/webcomponents/spec/shadow/#dfn-pool-population-algorithm
function poolPopulation(node) {
var pool = [];
for (var child = node.firstChild; child; child = child.nextSibling) {
if (isInsertionPoint(child)) {
pool.push.apply(pool, getDistributedNodes(child));
} else {
pool.push(child);
}
}
return pool;
}
function getShadowInsertionPoint(node) {
if (node instanceof HTMLShadowElement)
return node;
if (node instanceof HTMLContentElement)
return null;
for (var child = node.firstChild; child; child = child.nextSibling) {
var res = getShadowInsertionPoint(child);
if (res)
return res;
}
return null;
}
function destributeNodeInto(child, insertionPoint) {
getDistributedNodes(insertionPoint).push(child);
var points = destinationInsertionPointsTable.get(child);
if (!points)
destinationInsertionPointsTable.set(child, [insertionPoint]);
else
points.push(insertionPoint);
}
function getDestinationInsertionPoints(node) {
return destinationInsertionPointsTable.get(node);
}
function resetDestinationInsertionPoints(node) {
// IE11 crashes when delete is used.
destinationInsertionPointsTable.set(node, undefined);
}
// AllowedSelectors :
// TypeSelector
// *
// ClassSelector
// IDSelector
// AttributeSelector
// negation
var selectorStartCharRe = /^(:not\()?[*.#[a-zA-Z_|]/;
function matches(node, contentElement) {
var select = contentElement.getAttribute('select');
if (!select)
return true;
// Here we know the select attribute is a non empty string.
select = select.trim();
if (!select)
return true;
if (!(node instanceof Element))
return false;
if (!selectorStartCharRe.test(select))
return false;
try {
return node.matches(select);
} catch (ex) {
// Invalid selector.
return false;
}
}
function isFinalDestination(insertionPoint, node) {
var points = getDestinationInsertionPoints(node);
return points && points[points.length - 1] === insertionPoint;
}
function isInsertionPoint(node) {
return node instanceof HTMLContentElement ||
node instanceof HTMLShadowElement;
}
function isShadowHost(shadowHost) {
return shadowHost.shadowRoot;
}
// Returns the shadow trees as an array, with the youngest tree at the
// beginning of the array.
function getShadowTrees(host) {
var trees = [];
for (var tree = host.shadowRoot; tree; tree = tree.olderShadowRoot) {
trees.push(tree);
}
return trees;
}
function render(host) {
new ShadowRenderer(host).render();
};
// Need to rerender shadow host when:
//
// - a direct child to the ShadowRoot is added or removed
// - a direct child to the host is added or removed
// - a new shadow root is created
// - a direct child to a content/shadow element is added or removed
// - a sibling to a content/shadow element is added or removed
// - content[select] is changed
// - an attribute in a direct child to a host is modified
/**
* This gets called when a node was added or removed to it.
*/
Node.prototype.invalidateShadowRenderer = function(force) {
var renderer = unsafeUnwrap(this).polymerShadowRenderer_;
if (renderer) {
renderer.invalidate();
return true;
}
return false;
};
HTMLContentElement.prototype.getDistributedNodes =
HTMLShadowElement.prototype.getDistributedNodes = function() {
// TODO(arv): We should only rerender the dirty ancestor renderers (from
// the root and down).
renderAllPending();
return getDistributedNodes(this);
};
Element.prototype.getDestinationInsertionPoints = function() {
renderAllPending();
return getDestinationInsertionPoints(this) || [];
};
HTMLContentElement.prototype.nodeIsInserted_ =
HTMLShadowElement.prototype.nodeIsInserted_ = function() {
// Invalidate old renderer if any.
this.invalidateShadowRenderer();
var shadowRoot = getShadowRootAncestor(this);
var renderer;
if (shadowRoot)
renderer = getRendererForShadowRoot(shadowRoot);
unsafeUnwrap(this).polymerShadowRenderer_ = renderer;
if (renderer)
renderer.invalidate();
};
scope.getRendererForHost = getRendererForHost;
scope.getShadowTrees = getShadowTrees;
scope.renderAllPending = renderAllPending;
scope.getDestinationInsertionPoints = getDestinationInsertionPoints;
// Exposed for testing
scope.visual = {
insertBefore: insertBefore,
remove: remove,
};
})(window.ShadowDOMPolyfill);

View File

@@ -1,85 +0,0 @@
/**
* @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(scope) {
'use strict';
/**
* A tree scope represents the root of a tree. All nodes in a tree point to
* the same TreeScope object. The tree scope of a node get set the first time
* it is accessed or when a node is added or remove to a tree.
*
* The root is a Node that has no parent.
*
* The parent is another TreeScope. For ShadowRoots, it is the TreeScope of
* the host of the ShadowRoot.
*
* @param {!Node} root
* @param {TreeScope} parent
* @constructor
*/
function TreeScope(root, parent) {
/** @type {!Node} */
this.root = root;
/** @type {TreeScope} */
this.parent = parent;
}
TreeScope.prototype = {
get renderer() {
if (this.root instanceof scope.wrappers.ShadowRoot) {
return scope.getRendererForHost(this.root.host);
}
return null;
},
contains: function(treeScope) {
for (; treeScope; treeScope = treeScope.parent) {
if (treeScope === this)
return true;
}
return false;
}
};
function setTreeScope(node, treeScope) {
if (node.treeScope_ !== treeScope) {
node.treeScope_ = treeScope;
for (var sr = node.shadowRoot; sr; sr = sr.olderShadowRoot) {
sr.treeScope_.parent = treeScope;
}
for (var child = node.firstChild; child; child = child.nextSibling) {
setTreeScope(child, treeScope);
}
}
}
function getTreeScope(node) {
if (node instanceof scope.wrappers.Window) {
debugger;
}
if (node.treeScope_)
return node.treeScope_;
var parent = node.parentNode;
var treeScope;
if (parent)
treeScope = getTreeScope(parent);
else
treeScope = new TreeScope(node, null);
return node.treeScope_ = treeScope;
}
scope.TreeScope = TreeScope;
scope.getTreeScope = getTreeScope;
scope.setTreeScope = setTreeScope;
})(window.ShadowDOMPolyfill);

View File

@@ -1,52 +0,0 @@
[
"../WeakMap/WeakMap.js",
"wrappers.js",
"ArraySplice.js",
"microtask.js",
"MutationObserver.js",
"TreeScope.js",
"wrappers/events.js",
"wrappers/TouchEvent.js",
"wrappers/NodeList.js",
"wrappers/HTMLCollection.js",
"wrappers/Node.js",
"querySelector.js",
"wrappers/node-interfaces.js",
"wrappers/CharacterData.js",
"wrappers/Text.js",
"wrappers/DOMTokenList.js",
"wrappers/Element.js",
"wrappers/HTMLElement.js",
"wrappers/HTMLCanvasElement.js",
"wrappers/HTMLContentElement.js",
"wrappers/HTMLFormElement.js",
"wrappers/HTMLImageElement.js",
"wrappers/HTMLShadowElement.js",
"wrappers/HTMLTemplateElement.js",
"wrappers/HTMLMediaElement.js",
"wrappers/HTMLAudioElement.js",
"wrappers/HTMLOptionElement.js",
"wrappers/HTMLSelectElement.js",
"wrappers/HTMLTableElement.js",
"wrappers/HTMLTableSectionElement.js",
"wrappers/HTMLTableRowElement.js",
"wrappers/HTMLUnknownElement.js",
"wrappers/SVGElement.js",
"wrappers/SVGUseElement.js",
"wrappers/SVGElementInstance.js",
"wrappers/CanvasRenderingContext2D.js",
"wrappers/WebGLRenderingContext.js",
"wrappers/generic.js",
"wrappers/ShadowRoot.js",
"wrappers/Range.js",
"ShadowRenderer.js",
"wrappers/elements-with-form-property.js",
"wrappers/Selection.js",
"wrappers/TreeWalker.js",
"wrappers/Document.js",
"wrappers/Window.js",
"wrappers/DataTransfer.js",
"wrappers/FormData.js",
"wrappers/XMLHttpRequest.js",
"wrappers/override-constructors.js"
]

View File

@@ -1,53 +0,0 @@
/**
* @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(context) {
'use strict';
var OriginalMutationObserver = window.MutationObserver;
var callbacks = [];
var pending = false;
var timerFunc;
function handle() {
pending = false;
var copies = callbacks.slice(0);
callbacks = [];
for (var i = 0; i < copies.length; i++) {
(0, copies[i])();
}
}
if (OriginalMutationObserver) {
var counter = 1;
var observer = new OriginalMutationObserver(handle);
var textNode = document.createTextNode(counter);
observer.observe(textNode, {characterData: true});
timerFunc = function() {
counter = (counter + 1) % 2;
textNode.data = counter;
};
} else {
timerFunc = window.setTimeout;
}
function setEndOfMicrotask(func) {
callbacks.push(func);
if (pending)
return;
pending = true;
timerFunc(handle, 0);
}
context.setEndOfMicrotask = setEndOfMicrotask;
})(window.ShadowDOMPolyfill);

View File

@@ -1,308 +0,0 @@
/**
* @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(scope) {
'use strict';
var HTMLCollection = scope.wrappers.HTMLCollection;
var NodeList = scope.wrappers.NodeList;
var getTreeScope = scope.getTreeScope;
var unsafeUnwrap = scope.unsafeUnwrap;
var wrap = scope.wrap;
var originalDocumentQuerySelector = document.querySelector;
var originalElementQuerySelector = document.documentElement.querySelector;
var originalDocumentQuerySelectorAll = document.querySelectorAll;
var originalElementQuerySelectorAll = document.documentElement.querySelectorAll;
var originalDocumentGetElementsByTagName = document.getElementsByTagName;
var originalElementGetElementsByTagName = document.documentElement.getElementsByTagName;
var originalDocumentGetElementsByTagNameNS = document.getElementsByTagNameNS;
var originalElementGetElementsByTagNameNS = document.documentElement.getElementsByTagNameNS;
var OriginalElement = window.Element;
var OriginalDocument = window.HTMLDocument || window.Document;
function filterNodeList(list, index, result, deep) {
var wrappedItem = null;
var root = null;
for (var i = 0, length = list.length; i < length; i++) {
wrappedItem = wrap(list[i]);
if (!deep && (root = getTreeScope(wrappedItem).root)) {
if (root instanceof scope.wrappers.ShadowRoot) {
continue;
}
}
result[index++] = wrappedItem;
}
return index;
}
function shimSelector(selector) {
return String(selector).replace(/\/deep\/|::shadow|>>>/g, ' ');
}
function shimMatchesSelector(selector) {
return String(selector)
// Transform `:host(selector)` to `selector`
.replace(
/:host\(([^\s]+)\)/g,
'$1'
)
// Transform `selector:host` to `selector`
.replace(
/([^\s]):host/g,
'$1'
)
// Transform `:host` to `*`
.replace(
':host',
'*'
)
// From ShadowCSS, will be replaced by space
.replace(
/\^|\/shadow\/|\/shadow-deep\/|::shadow|\/deep\/|::content|>>>/g,
' '
);
}
function findOne(node, selector) {
var m, el = node.firstElementChild;
while (el) {
if (el.matches(selector))
return el;
m = findOne(el, selector);
if (m)
return m;
el = el.nextElementSibling;
}
return null;
}
function matchesSelector(el, selector) {
return el.matches(selector);
}
var XHTML_NS = 'http://www.w3.org/1999/xhtml';
function matchesTagName(el, localName, localNameLowerCase) {
var ln = el.localName;
return ln === localName ||
ln === localNameLowerCase && el.namespaceURI === XHTML_NS;
}
function matchesEveryThing() {
return true;
}
function matchesLocalNameOnly(el, ns, localName) {
return el.localName === localName;
}
function matchesNameSpace(el, ns) {
return el.namespaceURI === ns;
}
function matchesLocalNameNS(el, ns, localName) {
return el.namespaceURI === ns && el.localName === localName;
}
function findElements(node, index, result, p, arg0, arg1) {
var el = node.firstElementChild;
while (el) {
if (p(el, arg0, arg1))
result[index++] = el;
index = findElements(el, index, result, p, arg0, arg1);
el = el.nextElementSibling;
}
return index;
}
// find and findAll will only match Simple Selectors,
// Structural Pseudo Classes are not guaranteed to be correct
// http://www.w3.org/TR/css3-selectors/#simple-selectors
function querySelectorAllFiltered(p, index, result, selector, deep) {
var target = unsafeUnwrap(this);
var list;
var root = getTreeScope(this).root;
if (root instanceof scope.wrappers.ShadowRoot) {
// We are in the shadow tree and the logical tree is
// going to be disconnected so we do a manual tree traversal
return findElements(this, index, result, p, selector, null);
} else if (target instanceof OriginalElement) {
list = originalElementQuerySelectorAll.call(target, selector);
} else if (target instanceof OriginalDocument) {
list = originalDocumentQuerySelectorAll.call(target, selector);
} else {
// When we get a ShadowRoot the logical tree is going to be disconnected
// so we do a manual tree traversal
return findElements(this, index, result, p, selector, null);
}
return filterNodeList(list, index, result, deep);
}
var SelectorsInterface = {
querySelector: function(selector) {
var shimmed = shimSelector(selector);
var deep = shimmed !== selector;
selector = shimmed;
var target = unsafeUnwrap(this);
var wrappedItem;
var root = getTreeScope(this).root;
if (root instanceof scope.wrappers.ShadowRoot) {
// We are in the shadow tree and the logical tree is
// going to be disconnected so we do a manual tree traversal
return findOne(this, selector);
} else if (target instanceof OriginalElement) {
wrappedItem = wrap(originalElementQuerySelector.call(target, selector));
} else if (target instanceof OriginalDocument) {
wrappedItem = wrap(originalDocumentQuerySelector.call(target, selector));
} else {
// When we get a ShadowRoot the logical tree is going to be disconnected
// so we do a manual tree traversal
return findOne(this, selector);
}
if (!wrappedItem) {
// When the original query returns nothing
// we return nothing (to be consistent with the other wrapped calls)
return wrappedItem;
} else if (!deep && (root = getTreeScope(wrappedItem).root)) {
if (root instanceof scope.wrappers.ShadowRoot) {
// When the original query returns an element in the ShadowDOM
// we must do a manual tree traversal
return findOne(this, selector);
}
}
return wrappedItem;
},
querySelectorAll: function(selector) {
var shimmed = shimSelector(selector);
var deep = shimmed !== selector;
selector = shimmed;
var result = new NodeList();
result.length = querySelectorAllFiltered.call(this,
matchesSelector,
0,
result,
selector,
deep);
return result;
}
};
var MatchesInterface = {
matches: function(selector) {
selector = shimMatchesSelector(selector);
return scope.originalMatches.call(unsafeUnwrap(this), selector);
}
};
function getElementsByTagNameFiltered(p, index, result, localName,
lowercase) {
var target = unsafeUnwrap(this);
var list;
var root = getTreeScope(this).root;
if (root instanceof scope.wrappers.ShadowRoot) {
// We are in the shadow tree and the logical tree is
// going to be disconnected so we do a manual tree traversal
return findElements(this, index, result, p, localName, lowercase);
} else if (target instanceof OriginalElement) {
list = originalElementGetElementsByTagName.call(target, localName,
lowercase);
} else if (target instanceof OriginalDocument) {
list = originalDocumentGetElementsByTagName.call(target, localName,
lowercase);
} else {
// When we get a ShadowRoot the logical tree is going to be disconnected
// so we do a manual tree traversal
return findElements(this, index, result, p, localName, lowercase);
}
return filterNodeList(list, index, result, false);
}
function getElementsByTagNameNSFiltered(p, index, result, ns, localName) {
var target = unsafeUnwrap(this);
var list;
var root = getTreeScope(this).root;
if (root instanceof scope.wrappers.ShadowRoot) {
// We are in the shadow tree and the logical tree is
// going to be disconnected so we do a manual tree traversal
return findElements(this, index, result, p, ns, localName);
} else if (target instanceof OriginalElement) {
list = originalElementGetElementsByTagNameNS.call(target, ns, localName);
} else if (target instanceof OriginalDocument) {
list = originalDocumentGetElementsByTagNameNS.call(target, ns, localName);
} else {
// When we get a ShadowRoot the logical tree is going to be disconnected
// so we do a manual tree traversal
return findElements(this, index, result, p, ns, localName);
}
return filterNodeList(list, index, result, false);
}
var GetElementsByInterface = {
getElementsByTagName: function(localName) {
var result = new HTMLCollection();
var match = localName === '*' ? matchesEveryThing : matchesTagName;
result.length = getElementsByTagNameFiltered.call(this,
match,
0,
result,
localName,
localName.toLowerCase());
return result;
},
getElementsByClassName: function(className) {
// TODO(arv): Check className?
return this.querySelectorAll('.' + className);
},
getElementsByTagNameNS: function(ns, localName) {
var result = new HTMLCollection();
var match = null;
if (ns === '*') {
match = localName === '*' ? matchesEveryThing : matchesLocalNameOnly;
} else {
match = localName === '*' ? matchesNameSpace : matchesLocalNameNS;
}
result.length = getElementsByTagNameNSFiltered.call(this,
match,
0,
result,
ns || null,
localName);
return result;
}
};
scope.GetElementsByInterface = GetElementsByInterface;
scope.SelectorsInterface = SelectorsInterface;
scope.MatchesInterface = MatchesInterface;
})(window.ShadowDOMPolyfill);

View File

@@ -1,457 +0,0 @@
/**
* @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
*/
window.ShadowDOMPolyfill = {};
(function(scope) {
'use strict';
var constructorTable = new WeakMap();
var nativePrototypeTable = new WeakMap();
var wrappers = Object.create(null);
function detectEval() {
// Don't test for eval if we're running in a Chrome App environment.
// We check for APIs set that only exist in a Chrome App context.
if (typeof chrome !== 'undefined' && chrome.app && chrome.app.runtime) {
return false;
}
// Firefox OS Apps do not allow eval. This feature detection is very hacky
// but even if some other platform adds support for this function this code
// will continue to work.
if (navigator.getDeviceStorage) {
return false;
}
try {
var f = new Function('return true;');
return f();
} catch (ex) {
return false;
}
}
var hasEval = detectEval();
function assert(b) {
if (!b)
throw new Error('Assertion failed');
};
var defineProperty = Object.defineProperty;
var getOwnPropertyNames = Object.getOwnPropertyNames;
var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
function mixin(to, from) {
var names = getOwnPropertyNames(from);
for (var i = 0; i < names.length; i++) {
var name = names[i];
defineProperty(to, name, getOwnPropertyDescriptor(from, name));
}
return to;
};
function mixinStatics(to, from) {
var names = getOwnPropertyNames(from);
for (var i = 0; i < names.length; i++) {
var name = names[i];
switch (name) {
case 'arguments':
case 'caller':
case 'length':
case 'name':
case 'prototype':
case 'toString':
continue;
}
defineProperty(to, name, getOwnPropertyDescriptor(from, name));
}
return to;
};
function oneOf(object, propertyNames) {
for (var i = 0; i < propertyNames.length; i++) {
if (propertyNames[i] in object)
return propertyNames[i];
}
}
var nonEnumerableDataDescriptor = {
value: undefined,
configurable: true,
enumerable: false,
writable: true
};
function defineNonEnumerableDataProperty(object, name, value) {
nonEnumerableDataDescriptor.value = value;
defineProperty(object, name, nonEnumerableDataDescriptor);
}
// Mozilla's old DOM bindings are bretty busted:
// https://bugzilla.mozilla.org/show_bug.cgi?id=855844
// Make sure they are create before we start modifying things.
getOwnPropertyNames(window);
function getWrapperConstructor(node, opt_instance) {
var nativePrototype = node.__proto__ || Object.getPrototypeOf(node);
if (isFirefox) {
// HTMLEmbedElements will sometimes be [NS Object wrapper class]
// which throws an error when getOwnPropertyNames is called on it.
// Mozilla handily includes a second HTMLEmbedElementPrototype in
// the chain, so we use that one if available.
try {
getOwnPropertyNames(nativePrototype);
} catch (error) {
nativePrototype = nativePrototype.__proto__;
}
}
var wrapperConstructor = constructorTable.get(nativePrototype);
if (wrapperConstructor)
return wrapperConstructor;
var parentWrapperConstructor = getWrapperConstructor(nativePrototype);
var GeneratedWrapper = createWrapperConstructor(parentWrapperConstructor);
registerInternal(nativePrototype, GeneratedWrapper, opt_instance);
return GeneratedWrapper;
}
function addForwardingProperties(nativePrototype, wrapperPrototype) {
installProperty(nativePrototype, wrapperPrototype, true);
}
function registerInstanceProperties(wrapperPrototype, instanceObject) {
installProperty(instanceObject, wrapperPrototype, false);
}
var isFirefox = /Firefox/.test(navigator.userAgent);
// This is used as a fallback when getting the descriptor fails in
// installProperty.
var dummyDescriptor = {
get: function() {},
set: function(v) {},
configurable: true,
enumerable: true
};
function isEventHandlerName(name) {
return /^on[a-z]+$/.test(name);
}
function isIdentifierName(name) {
return /^[a-zA-Z_$][a-zA-Z_$0-9]*$/.test(name);
}
// The name of the implementation property is intentionally hard to
// remember. Unfortunately, browsers are slower doing obj[expr] than
// obj.foo so we resort to repeat this ugly name. This ugly name is never
// used outside of this file though.
function getGetter(name) {
return hasEval && isIdentifierName(name) ?
new Function('return this.__impl4cf1e782hg__.' + name) :
function() { return this.__impl4cf1e782hg__[name]; };
}
function getSetter(name) {
return hasEval && isIdentifierName(name) ?
new Function('v', 'this.__impl4cf1e782hg__.' + name + ' = v') :
function(v) { this.__impl4cf1e782hg__[name] = v; };
}
function getMethod(name) {
return hasEval && isIdentifierName(name) ?
new Function('return this.__impl4cf1e782hg__.' + name +
'.apply(this.__impl4cf1e782hg__, arguments)') :
function() {
return this.__impl4cf1e782hg__[name].apply(
this.__impl4cf1e782hg__, arguments);
};
}
function getDescriptor(source, name) {
try {
return Object.getOwnPropertyDescriptor(source, name);
} catch (ex) {
// JSC and V8 both use data properties instead of accessors which can
// cause getting the property desciptor to throw an exception.
// https://bugs.webkit.org/show_bug.cgi?id=49739
return dummyDescriptor;
}
}
// Safari 8 exposes WebIDL attributes as an invalid accessor property. Its
// descriptor has {get: undefined, set: undefined}. We therefore ignore the
// shape of the descriptor and make all properties read-write.
// https://bugs.webkit.org/show_bug.cgi?id=49739
var isBrokenSafari = function() {
var descr = Object.getOwnPropertyDescriptor(Node.prototype, 'nodeType');
return descr && !descr.get && !descr.set;
}();
function installProperty(source, target, allowMethod, opt_blacklist) {
var names = getOwnPropertyNames(source);
for (var i = 0; i < names.length; i++) {
var name = names[i];
if (name === 'polymerBlackList_')
continue;
if (name in target)
continue;
if (source.polymerBlackList_ && source.polymerBlackList_[name])
continue;
if (isFirefox) {
// Tickle Firefox's old bindings.
source.__lookupGetter__(name);
}
var descriptor = getDescriptor(source, name);
var getter, setter;
if(typeof descriptor.value === 'function') {
if (allowMethod) {
target[name] = getMethod(name);
}
continue;
}
var isEvent = isEventHandlerName(name);
if (isEvent)
getter = scope.getEventHandlerGetter(name);
else
getter = getGetter(name);
if (descriptor.writable || descriptor.set || isBrokenSafari) {
if (isEvent)
setter = scope.getEventHandlerSetter(name);
else
setter = getSetter(name);
}
// make all descriptors configurable on broken safari
var configurable = isBrokenSafari || descriptor.configurable;
defineProperty(target, name, {
get: getter,
set: setter,
configurable: configurable,
enumerable: descriptor.enumerable
});
}
}
/**
* @param {Function} nativeConstructor
* @param {Function} wrapperConstructor
* @param {Object=} opt_instance If present, this is used to extract
* properties from an instance object.
*/
function register(nativeConstructor, wrapperConstructor, opt_instance) {
if (nativeConstructor == null) {
return;
}
var nativePrototype = nativeConstructor.prototype;
registerInternal(nativePrototype, wrapperConstructor, opt_instance);
mixinStatics(wrapperConstructor, nativeConstructor);
}
function registerInternal(nativePrototype, wrapperConstructor, opt_instance) {
var wrapperPrototype = wrapperConstructor.prototype;
assert(constructorTable.get(nativePrototype) === undefined);
constructorTable.set(nativePrototype, wrapperConstructor);
nativePrototypeTable.set(wrapperPrototype, nativePrototype);
addForwardingProperties(nativePrototype, wrapperPrototype);
if (opt_instance)
registerInstanceProperties(wrapperPrototype, opt_instance);
defineNonEnumerableDataProperty(
wrapperPrototype, 'constructor', wrapperConstructor);
// Set it again. Some VMs optimizes objects that are used as prototypes.
wrapperConstructor.prototype = wrapperPrototype;
}
function isWrapperFor(wrapperConstructor, nativeConstructor) {
return constructorTable.get(nativeConstructor.prototype) ===
wrapperConstructor;
}
/**
* Creates a generic wrapper constructor based on |object| and its
* constructor.
* @param {Node} object
* @return {Function} The generated constructor.
*/
function registerObject(object) {
var nativePrototype = Object.getPrototypeOf(object);
var superWrapperConstructor = getWrapperConstructor(nativePrototype);
var GeneratedWrapper = createWrapperConstructor(superWrapperConstructor);
registerInternal(nativePrototype, GeneratedWrapper, object);
return GeneratedWrapper;
}
function createWrapperConstructor(superWrapperConstructor) {
function GeneratedWrapper(node) {
superWrapperConstructor.call(this, node);
}
var p = Object.create(superWrapperConstructor.prototype);
p.constructor = GeneratedWrapper;
GeneratedWrapper.prototype = p;
return GeneratedWrapper;
}
function isWrapper(object) {
return object && object.__impl4cf1e782hg__;
}
function isNative(object) {
return !isWrapper(object);
}
/**
* Wraps a node in a WrapperNode. If there already exists a wrapper for the
* |node| that wrapper is returned instead.
* @param {Node} node
* @return {WrapperNode}
*/
function wrap(impl) {
if (impl === null)
return null;
assert(isNative(impl));
var wrapper = impl.__wrapper8e3dd93a60__;
if (wrapper != null) {
return wrapper;
}
return impl.__wrapper8e3dd93a60__ =
new (getWrapperConstructor(impl, impl))(impl);
}
/**
* Unwraps a wrapper and returns the node it is wrapping.
* @param {WrapperNode} wrapper
* @return {Node}
*/
function unwrap(wrapper) {
if (wrapper === null)
return null;
assert(isWrapper(wrapper));
return wrapper.__impl4cf1e782hg__;
}
function unsafeUnwrap(wrapper) {
return wrapper.__impl4cf1e782hg__;
}
function setWrapper(impl, wrapper) {
wrapper.__impl4cf1e782hg__ = impl;
impl.__wrapper8e3dd93a60__ = wrapper;
}
/**
* Unwraps object if it is a wrapper.
* @param {Object} object
* @return {Object} The native implementation object.
*/
function unwrapIfNeeded(object) {
return object && isWrapper(object) ? unwrap(object) : object;
}
/**
* Wraps object if it is not a wrapper.
* @param {Object} object
* @return {Object} The wrapper for object.
*/
function wrapIfNeeded(object) {
return object && !isWrapper(object) ? wrap(object) : object;
}
/**
* Overrides the current wrapper (if any) for node.
* @param {Node} node
* @param {WrapperNode=} wrapper If left out the wrapper will be created as
* needed next time someone wraps the node.
*/
function rewrap(node, wrapper) {
if (wrapper === null)
return;
assert(isNative(node));
assert(wrapper === undefined || isWrapper(wrapper));
node.__wrapper8e3dd93a60__ = wrapper;
}
var getterDescriptor = {
get: undefined,
configurable: true,
enumerable: true
};
function defineGetter(constructor, name, getter) {
getterDescriptor.get = getter;
defineProperty(constructor.prototype, name, getterDescriptor);
}
function defineWrapGetter(constructor, name) {
defineGetter(constructor, name, function() {
return wrap(this.__impl4cf1e782hg__[name]);
});
}
/**
* Forwards existing methods on the native object to the wrapper methods.
* This does not wrap any of the arguments or the return value since the
* wrapper implementation already takes care of that.
* @param {Array.<Function>} constructors
* @parem {Array.<string>} names
*/
function forwardMethodsToWrapper(constructors, names) {
constructors.forEach(function(constructor) {
names.forEach(function(name) {
constructor.prototype[name] = function() {
var w = wrapIfNeeded(this);
return w[name].apply(w, arguments);
};
});
});
}
scope.addForwardingProperties = addForwardingProperties;
scope.assert = assert;
scope.constructorTable = constructorTable;
scope.defineGetter = defineGetter;
scope.defineWrapGetter = defineWrapGetter;
scope.forwardMethodsToWrapper = forwardMethodsToWrapper;
scope.isIdentifierName = isIdentifierName;
scope.isWrapper = isWrapper;
scope.isWrapperFor = isWrapperFor;
scope.mixin = mixin;
scope.nativePrototypeTable = nativePrototypeTable;
scope.oneOf = oneOf;
scope.registerObject = registerObject;
scope.registerWrapper = register;
scope.rewrap = rewrap;
scope.setWrapper = setWrapper;
scope.unsafeUnwrap = unsafeUnwrap;
scope.unwrap = unwrap;
scope.unwrapIfNeeded = unwrapIfNeeded;
scope.wrap = wrap;
scope.wrapIfNeeded = wrapIfNeeded;
scope.wrappers = wrappers;
})(window.ShadowDOMPolyfill);

View File

@@ -1,48 +0,0 @@
/**
* @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(scope) {
'use strict';
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var setWrapper = scope.setWrapper;
var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;
var OriginalCanvasRenderingContext2D = window.CanvasRenderingContext2D;
function CanvasRenderingContext2D(impl) {
setWrapper(impl, this);
}
mixin(CanvasRenderingContext2D.prototype, {
get canvas() {
return wrap(unsafeUnwrap(this).canvas);
},
drawImage: function() {
arguments[0] = unwrapIfNeeded(arguments[0]);
unsafeUnwrap(this).drawImage.apply(unsafeUnwrap(this), arguments);
},
createPattern: function() {
arguments[0] = unwrap(arguments[0]);
return unsafeUnwrap(this).createPattern.apply(unsafeUnwrap(this), arguments);
}
});
registerWrapper(OriginalCanvasRenderingContext2D, CanvasRenderingContext2D,
document.createElement('canvas').getContext('2d'));
scope.wrappers.CanvasRenderingContext2D = CanvasRenderingContext2D;
})(window.ShadowDOMPolyfill);

View File

@@ -1,58 +0,0 @@
/**
* @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(scope) {
'use strict';
var ChildNodeInterface = scope.ChildNodeInterface;
var Node = scope.wrappers.Node;
var enqueueMutation = scope.enqueueMutation;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var unsafeUnwrap = scope.unsafeUnwrap;
var OriginalCharacterData = window.CharacterData;
function CharacterData(node) {
Node.call(this, node);
}
CharacterData.prototype = Object.create(Node.prototype);
mixin(CharacterData.prototype, {
get nodeValue() {
return this.data;
},
set nodeValue(data) {
this.data = data;
},
get textContent() {
return this.data;
},
set textContent(value) {
this.data = value;
},
get data() {
return unsafeUnwrap(this).data;
},
set data(value) {
var oldValue = unsafeUnwrap(this).data;
enqueueMutation(this, 'characterData', {
oldValue: oldValue
});
unsafeUnwrap(this).data = value;
}
});
mixin(CharacterData.prototype, ChildNodeInterface);
registerWrapper(OriginalCharacterData, CharacterData,
document.createTextNode(''));
scope.wrappers.CharacterData = CharacterData;
})(window.ShadowDOMPolyfill);

View File

@@ -1,73 +0,0 @@
/**
* @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
*/
// NOTE: Set the 'ownerElement_' property on a DOMTokenList to make invalidation
// happen. This is pretty hacky but we only have to do it in one place
// (Element.js) currently so it seems like the least bad option.
(function(scope) {
'use strict';
if (!window.DOMTokenList) {
console.warn('Missing DOMTokenList prototype, please include a ' +
'compatible classList polyfill such as http://goo.gl/uTcepH.');
return;
}
var unsafeUnwrap = scope.unsafeUnwrap;
var enqueueMutation = scope.enqueueMutation;
function getClass (el) {
return unsafeUnwrap(el).getAttribute('class');
}
function enqueueClassAttributeChange(el, oldValue) {
enqueueMutation(el, 'attributes', {
name: 'class',
namespace: null,
oldValue: oldValue
});
}
function invalidateClass(el) {
scope.invalidateRendererBasedOnAttribute(el, 'class');
}
function changeClass(tokenList, method, args) {
var ownerElement = tokenList.ownerElement_;
if (ownerElement == null) {
return method.apply(tokenList, args);
}
var oldValue = getClass(ownerElement);
var retv = method.apply(tokenList, args);
if (getClass(ownerElement) !== oldValue) {
enqueueClassAttributeChange(ownerElement, oldValue);
invalidateClass(ownerElement);
}
return retv;
}
var oldAdd = DOMTokenList.prototype.add;
DOMTokenList.prototype.add = function() {
changeClass(this, oldAdd, arguments);
};
var oldRemove = DOMTokenList.prototype.remove;
DOMTokenList.prototype.remove = function() {
changeClass(this, oldRemove, arguments);
};
var oldToggle = DOMTokenList.prototype.toggle;
DOMTokenList.prototype.toggle = function() {
return changeClass(this, oldToggle, arguments);
};
})(window.ShadowDOMPolyfill);

View File

@@ -1,30 +0,0 @@
/**
* @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(scope) {
'use strict';
var unwrap = scope.unwrap;
// DataTransfer (Clipboard in old Blink/WebKit) has a single method that
// requires wrapping. Since it is only a method we do not need a real wrapper,
// we can just override the method.
var OriginalDataTransfer = window.DataTransfer || window.Clipboard;
var OriginalDataTransferSetDragImage =
OriginalDataTransfer.prototype.setDragImage;
if (OriginalDataTransferSetDragImage) {
OriginalDataTransfer.prototype.setDragImage = function(image, x, y) {
OriginalDataTransferSetDragImage.call(this, unwrap(image), x, y);
};
}
})(window.ShadowDOMPolyfill);

View File

@@ -1,408 +0,0 @@
/**
* @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(scope) {
'use strict';
var GetElementsByInterface = scope.GetElementsByInterface;
var Node = scope.wrappers.Node;
var ParentNodeInterface = scope.ParentNodeInterface;
var NonElementParentNodeInterface = scope.NonElementParentNodeInterface;
var Selection = scope.wrappers.Selection;
var SelectorsInterface = scope.SelectorsInterface;
var ShadowRoot = scope.wrappers.ShadowRoot;
var TreeScope = scope.TreeScope;
var cloneNode = scope.cloneNode;
var defineGetter = scope.defineGetter;
var defineWrapGetter = scope.defineWrapGetter;
var elementFromPoint = scope.elementFromPoint;
var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
var matchesNames = scope.matchesNames;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var renderAllPending = scope.renderAllPending;
var rewrap = scope.rewrap;
var setWrapper = scope.setWrapper;
var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var wrapEventTargetMethods = scope.wrapEventTargetMethods;
var wrapNodeList = scope.wrapNodeList;
var implementationTable = new WeakMap();
function Document(node) {
Node.call(this, node);
this.treeScope_ = new TreeScope(this, null);
}
Document.prototype = Object.create(Node.prototype);
defineWrapGetter(Document, 'documentElement');
// Conceptually both body and head can be in a shadow but supporting that seems
// overkill at this point.
defineWrapGetter(Document, 'body');
defineWrapGetter(Document, 'head');
defineGetter(Document, 'activeElement', function() {
var unwrappedActiveElement = unwrap(this).activeElement;
if (!unwrappedActiveElement || !unwrappedActiveElement.nodeType) return null;
var activeElement = wrap(unwrappedActiveElement);
// Loop while activeElement is not a shallow child of this document.
while (!this.contains(activeElement)) {
// Iterate until we hit activeElement's containing ShadowRoot (which
// isn't this one) or document.
while (activeElement.parentNode) {
activeElement = activeElement.parentNode;
}
// If we've reached a ShadowRoot, move to its host.
if (activeElement.host) {
activeElement = activeElement.host;
// Otherwise, we've reached a different document - this document is
// not an ancestor of the active element.
} else {
return null;
}
}
return activeElement;
});
// document cannot be overridden so we override a bunch of its methods
// directly on the instance.
function wrapMethod(name) {
var original = document[name];
Document.prototype[name] = function() {
return wrap(original.apply(unsafeUnwrap(this), arguments));
};
}
[
'createComment',
'createDocumentFragment',
'createElement',
'createElementNS',
'createEvent',
'createEventNS',
'createRange',
'createTextNode',
].forEach(wrapMethod);
var originalAdoptNode = document.adoptNode;
function adoptNodeNoRemove(node, doc) {
originalAdoptNode.call(unsafeUnwrap(doc), unwrap(node));
adoptSubtree(node, doc);
}
function adoptSubtree(node, doc) {
if (node.shadowRoot)
doc.adoptNode(node.shadowRoot);
if (node instanceof ShadowRoot)
adoptOlderShadowRoots(node, doc);
for (var child = node.firstChild; child; child = child.nextSibling) {
adoptSubtree(child, doc);
}
}
function adoptOlderShadowRoots(shadowRoot, doc) {
var oldShadowRoot = shadowRoot.olderShadowRoot;
if (oldShadowRoot)
doc.adoptNode(oldShadowRoot);
}
var originalGetSelection = document.getSelection;
mixin(Document.prototype, {
adoptNode: function(node) {
if (node.parentNode)
node.parentNode.removeChild(node);
adoptNodeNoRemove(node, this);
return node;
},
elementFromPoint: function(x, y) {
return elementFromPoint(this, this, x, y);
},
importNode: function(node, deep) {
return cloneNode(node, deep, unsafeUnwrap(this));
},
getSelection: function() {
renderAllPending();
return new Selection(originalGetSelection.call(unwrap(this)));
},
getElementsByName: function(name) {
return SelectorsInterface.querySelectorAll.call(this,
'[name=' + JSON.stringify(String(name)) + ']');
}
});
var originalCreateTreeWalker = document.createTreeWalker;
var TreeWalkerWrapper = scope.wrappers.TreeWalker;
Document.prototype.createTreeWalker = function(root, whatToShow,
filter, expandEntityReferences) {
var newFilter = null; // IE does not like undefined.
// Support filter as a function or object with function defined as
// acceptNode. IE supports filter as a function only.
// Chrome and FF support both formats.
if (filter) {
if (filter.acceptNode && typeof filter.acceptNode === 'function') {
newFilter = {
acceptNode: function(node) {
return filter.acceptNode(wrap(node));
}
};
} else if (typeof filter === 'function') {
newFilter = function(node) {
return filter(wrap(node));
}
}
}
return new TreeWalkerWrapper(
originalCreateTreeWalker.call(unwrap(this), unwrap(root),
whatToShow, newFilter, expandEntityReferences));
};
if (document.registerElement) {
var originalRegisterElement = document.registerElement;
Document.prototype.registerElement = function(tagName, object) {
var prototype, extendsOption;
if (object !== undefined) {
prototype = object.prototype;
extendsOption = object.extends;
}
if (!prototype)
prototype = Object.create(HTMLElement.prototype);
// If we already used the object as a prototype for another custom
// element.
if (scope.nativePrototypeTable.get(prototype)) {
// TODO(arv): DOMException
throw new Error('NotSupportedError');
}
// Find first object on the prototype chain that already have a native
// prototype. Keep track of all the objects before that so we can create
// a similar structure for the native case.
var proto = Object.getPrototypeOf(prototype);
var nativePrototype;
var prototypes = [];
while (proto) {
nativePrototype = scope.nativePrototypeTable.get(proto);
if (nativePrototype)
break;
prototypes.push(proto);
proto = Object.getPrototypeOf(proto);
}
if (!nativePrototype) {
// TODO(arv): DOMException
throw new Error('NotSupportedError');
}
// This works by creating a new prototype object that is empty, but has
// the native prototype as its proto. The original prototype object
// passed into register is used as the wrapper prototype.
var newPrototype = Object.create(nativePrototype);
for (var i = prototypes.length - 1; i >= 0; i--) {
newPrototype = Object.create(newPrototype);
}
// Add callbacks if present.
// Names are taken from:
// https://code.google.com/p/chromium/codesearch#chromium/src/third_party/WebKit/Source/bindings/v8/CustomElementConstructorBuilder.cpp&sq=package:chromium&type=cs&l=156
// and not from the spec since the spec is out of date.
[
'createdCallback',
'attachedCallback',
'detachedCallback',
'attributeChangedCallback',
].forEach(function(name) {
var f = prototype[name];
if (!f)
return;
newPrototype[name] = function() {
// if this element has been wrapped prior to registration,
// the wrapper is stale; in this case rewrap
if (!(wrap(this) instanceof CustomElementConstructor)) {
rewrap(this);
}
f.apply(wrap(this), arguments);
};
});
var p = {prototype: newPrototype};
if (extendsOption)
p.extends = extendsOption;
function CustomElementConstructor(node) {
if (!node) {
if (extendsOption) {
return document.createElement(extendsOption, tagName);
} else {
return document.createElement(tagName);
}
}
setWrapper(node, this);
}
CustomElementConstructor.prototype = prototype;
CustomElementConstructor.prototype.constructor = CustomElementConstructor;
scope.constructorTable.set(newPrototype, CustomElementConstructor);
scope.nativePrototypeTable.set(prototype, newPrototype);
// registration is synchronous so do it last
var nativeConstructor = originalRegisterElement.call(unwrap(this),
tagName, p);
return CustomElementConstructor;
};
forwardMethodsToWrapper([
window.HTMLDocument || window.Document, // Gecko adds these to HTMLDocument
], [
'registerElement',
]);
}
// We also override some of the methods on document.body and document.head
// for convenience.
forwardMethodsToWrapper([
window.HTMLBodyElement,
window.HTMLDocument || window.Document, // Gecko adds these to HTMLDocument
window.HTMLHeadElement,
window.HTMLHtmlElement,
], [
'appendChild',
'compareDocumentPosition',
'contains',
'getElementsByClassName',
'getElementsByTagName',
'getElementsByTagNameNS',
'insertBefore',
'querySelector',
'querySelectorAll',
'removeChild',
'replaceChild',
]);
forwardMethodsToWrapper([
window.HTMLBodyElement,
window.HTMLHeadElement,
window.HTMLHtmlElement,
], matchesNames);
forwardMethodsToWrapper([
window.HTMLDocument || window.Document, // Gecko adds these to HTMLDocument
], [
'adoptNode',
'importNode',
'contains',
'createComment',
'createDocumentFragment',
'createElement',
'createElementNS',
'createEvent',
'createEventNS',
'createRange',
'createTextNode',
'createTreeWalker',
'elementFromPoint',
'getElementById',
'getElementsByName',
'getSelection',
]);
mixin(Document.prototype, GetElementsByInterface);
mixin(Document.prototype, ParentNodeInterface);
mixin(Document.prototype, SelectorsInterface);
mixin(Document.prototype, NonElementParentNodeInterface);
mixin(Document.prototype, {
get implementation() {
var implementation = implementationTable.get(this);
if (implementation)
return implementation;
implementation =
new DOMImplementation(unwrap(this).implementation);
implementationTable.set(this, implementation);
return implementation;
},
get defaultView() {
return wrap(unwrap(this).defaultView);
}
});
registerWrapper(window.Document, Document,
document.implementation.createHTMLDocument(''));
// Both WebKit and Gecko uses HTMLDocument for document. HTML5/DOM only has
// one Document interface and IE implements the standard correctly.
if (window.HTMLDocument)
registerWrapper(window.HTMLDocument, Document);
wrapEventTargetMethods([
window.HTMLBodyElement,
window.HTMLDocument || window.Document, // Gecko adds these to HTMLDocument
window.HTMLHeadElement,
]);
function DOMImplementation(impl) {
setWrapper(impl, this);
}
var originalCreateDocument = document.implementation.createDocument;
DOMImplementation.prototype.createDocument = function() {
arguments[2] = unwrap(arguments[2]);
return wrap(originalCreateDocument.apply(unsafeUnwrap(this), arguments));
};
function wrapImplMethod(constructor, name) {
var original = document.implementation[name];
constructor.prototype[name] = function() {
return wrap(original.apply(unsafeUnwrap(this), arguments));
};
}
function forwardImplMethod(constructor, name) {
var original = document.implementation[name];
constructor.prototype[name] = function() {
return original.apply(unsafeUnwrap(this), arguments);
};
}
wrapImplMethod(DOMImplementation, 'createDocumentType');
wrapImplMethod(DOMImplementation, 'createHTMLDocument');
forwardImplMethod(DOMImplementation, 'hasFeature');
registerWrapper(window.DOMImplementation, DOMImplementation);
forwardMethodsToWrapper([
window.DOMImplementation,
], [
'createDocument',
'createDocumentType',
'createHTMLDocument',
'hasFeature',
]);
scope.adoptNodeNoRemove = adoptNodeNoRemove;
scope.wrappers.DOMImplementation = DOMImplementation;
scope.wrappers.Document = Document;
})(window.ShadowDOMPolyfill);

View File

@@ -1,156 +0,0 @@
/**
* @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(scope) {
'use strict';
var ChildNodeInterface = scope.ChildNodeInterface;
var GetElementsByInterface = scope.GetElementsByInterface;
var Node = scope.wrappers.Node;
var ParentNodeInterface = scope.ParentNodeInterface;
var SelectorsInterface = scope.SelectorsInterface;
var MatchesInterface = scope.MatchesInterface;
var addWrapNodeListMethod = scope.addWrapNodeListMethod;
var enqueueMutation = scope.enqueueMutation;
var mixin = scope.mixin;
var oneOf = scope.oneOf;
var registerWrapper = scope.registerWrapper;
var unsafeUnwrap = scope.unsafeUnwrap;
var wrappers = scope.wrappers;
var OriginalElement = window.Element;
var matchesNames = [
'matches', // needs to come first.
'mozMatchesSelector',
'msMatchesSelector',
'webkitMatchesSelector',
].filter(function(name) {
return OriginalElement.prototype[name];
});
var matchesName = matchesNames[0];
var originalMatches = OriginalElement.prototype[matchesName];
function invalidateRendererBasedOnAttribute(element, name) {
// Only invalidate if parent node is a shadow host.
var p = element.parentNode;
if (!p || !p.shadowRoot)
return;
var renderer = scope.getRendererForHost(p);
if (renderer.dependsOnAttribute(name))
renderer.invalidate();
}
function enqueAttributeChange(element, name, oldValue) {
// This is not fully spec compliant. We should use localName (which might
// have a different case than name) and the namespace (which requires us
// to get the Attr object).
enqueueMutation(element, 'attributes', {
name: name,
namespace: null,
oldValue: oldValue
});
}
var classListTable = new WeakMap();
function Element(node) {
Node.call(this, node);
}
Element.prototype = Object.create(Node.prototype);
mixin(Element.prototype, {
createShadowRoot: function() {
var newShadowRoot = new wrappers.ShadowRoot(this);
unsafeUnwrap(this).polymerShadowRoot_ = newShadowRoot;
var renderer = scope.getRendererForHost(this);
renderer.invalidate();
return newShadowRoot;
},
get shadowRoot() {
return unsafeUnwrap(this).polymerShadowRoot_ || null;
},
// getDestinationInsertionPoints added in ShadowRenderer.js
setAttribute: function(name, value) {
var oldValue = unsafeUnwrap(this).getAttribute(name);
unsafeUnwrap(this).setAttribute(name, value);
enqueAttributeChange(this, name, oldValue);
invalidateRendererBasedOnAttribute(this, name);
},
removeAttribute: function(name) {
var oldValue = unsafeUnwrap(this).getAttribute(name);
unsafeUnwrap(this).removeAttribute(name);
enqueAttributeChange(this, name, oldValue);
invalidateRendererBasedOnAttribute(this, name);
},
get classList() {
var list = classListTable.get(this);
if (!list) {
list = unsafeUnwrap(this).classList;
if (!list) return;
list.ownerElement_ = this;
classListTable.set(this, list);
}
return list;
},
get className() {
return unsafeUnwrap(this).className;
},
set className(v) {
this.setAttribute('class', v);
},
get id() {
return unsafeUnwrap(this).id;
},
set id(v) {
this.setAttribute('id', v);
}
});
matchesNames.forEach(function(name) {
if (name !== 'matches') {
Element.prototype[name] = function(selector) {
return this.matches(selector);
};
}
});
if (OriginalElement.prototype.webkitCreateShadowRoot) {
Element.prototype.webkitCreateShadowRoot =
Element.prototype.createShadowRoot;
}
mixin(Element.prototype, ChildNodeInterface);
mixin(Element.prototype, GetElementsByInterface);
mixin(Element.prototype, ParentNodeInterface);
mixin(Element.prototype, SelectorsInterface);
mixin(Element.prototype, MatchesInterface);
registerWrapper(OriginalElement, Element,
document.createElementNS(null, 'x'));
scope.invalidateRendererBasedOnAttribute = invalidateRendererBasedOnAttribute;
scope.matchesNames = matchesNames;
scope.originalMatches = originalMatches;
scope.wrappers.Element = Element;
})(window.ShadowDOMPolyfill);

View File

@@ -1,35 +0,0 @@
/**
* @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(scope) {
'use strict';
var registerWrapper = scope.registerWrapper;
var setWrapper = scope.setWrapper;
var unwrap = scope.unwrap;
var OriginalFormData = window.FormData;
if (!OriginalFormData) return;
function FormData(formElement) {
var impl;
if (formElement instanceof OriginalFormData) {
impl = formElement;
} else {
impl = new OriginalFormData(formElement && unwrap(formElement));
}
setWrapper(impl, this);
}
registerWrapper(OriginalFormData, FormData, new OriginalFormData());
scope.wrappers.FormData = FormData;
})(window.ShadowDOMPolyfill);

View File

@@ -1,50 +0,0 @@
/**
* @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(scope) {
'use strict';
var HTMLMediaElement = scope.wrappers.HTMLMediaElement;
var registerWrapper = scope.registerWrapper;
var unwrap = scope.unwrap;
var rewrap = scope.rewrap;
var OriginalHTMLAudioElement = window.HTMLAudioElement;
if (!OriginalHTMLAudioElement) return;
function HTMLAudioElement(node) {
HTMLMediaElement.call(this, node);
}
HTMLAudioElement.prototype = Object.create(HTMLMediaElement.prototype);
registerWrapper(OriginalHTMLAudioElement, HTMLAudioElement,
document.createElement('audio'));
function Audio(src) {
if (!(this instanceof Audio)) {
throw new TypeError(
'DOM object constructor cannot be called as a function.');
}
var node = unwrap(document.createElement('audio'));
HTMLMediaElement.call(this, node);
rewrap(node, this);
node.setAttribute('preload', 'auto');
if (src !== undefined)
node.setAttribute('src', src);
}
Audio.prototype = HTMLAudioElement.prototype;
scope.wrappers.HTMLAudioElement = HTMLAudioElement;
scope.wrappers.Audio = Audio;
})(window.ShadowDOMPolyfill);

View File

@@ -1,38 +0,0 @@
/**
* @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(scope) {
'use strict';
var HTMLElement = scope.wrappers.HTMLElement;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var unsafeUnwrap = scope.unsafeUnwrap;
var wrap = scope.wrap;
var OriginalHTMLCanvasElement = window.HTMLCanvasElement;
function HTMLCanvasElement(node) {
HTMLElement.call(this, node);
}
HTMLCanvasElement.prototype = Object.create(HTMLElement.prototype);
mixin(HTMLCanvasElement.prototype, {
getContext: function() {
var context = unsafeUnwrap(this).getContext.apply(unsafeUnwrap(this), arguments);
return context && wrap(context);
}
});
registerWrapper(OriginalHTMLCanvasElement, HTMLCanvasElement,
document.createElement('canvas'));
scope.wrappers.HTMLCanvasElement = HTMLCanvasElement;
})(window.ShadowDOMPolyfill);

View File

@@ -1,19 +0,0 @@
/**
* @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(scope) {
'use strict';
// TODO(arv): Implement.
scope.wrapHTMLCollection = scope.wrapNodeList;
scope.wrappers.HTMLCollection = scope.wrappers.NodeList;
})(window.ShadowDOMPolyfill);

View File

@@ -1,47 +0,0 @@
/**
* @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(scope) {
'use strict';
var HTMLElement = scope.wrappers.HTMLElement;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var OriginalHTMLContentElement = window.HTMLContentElement;
function HTMLContentElement(node) {
HTMLElement.call(this, node);
}
HTMLContentElement.prototype = Object.create(HTMLElement.prototype);
mixin(HTMLContentElement.prototype, {
constructor: HTMLContentElement,
get select() {
return this.getAttribute('select');
},
set select(value) {
this.setAttribute('select', value);
},
setAttribute: function(n, v) {
HTMLElement.prototype.setAttribute.call(this, n, v);
if (String(n).toLowerCase() === 'select')
this.invalidateShadowRenderer(true);
}
// getDistributedNodes is added in ShadowRenderer
});
if (OriginalHTMLContentElement)
registerWrapper(OriginalHTMLContentElement, HTMLContentElement);
scope.wrappers.HTMLContentElement = HTMLContentElement;
})(window.ShadowDOMPolyfill);

View File

@@ -1,351 +0,0 @@
/**
* @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(scope) {
'use strict';
var Element = scope.wrappers.Element;
var defineGetter = scope.defineGetter;
var enqueueMutation = scope.enqueueMutation;
var mixin = scope.mixin;
var nodesWereAdded = scope.nodesWereAdded;
var nodesWereRemoved = scope.nodesWereRemoved;
var registerWrapper = scope.registerWrapper;
var snapshotNodeList = scope.snapshotNodeList;
var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var wrappers = scope.wrappers;
/////////////////////////////////////////////////////////////////////////////
// innerHTML and outerHTML
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#escapingString
var escapeAttrRegExp = /[&\u00A0"]/g;
var escapeDataRegExp = /[&\u00A0<>]/g;
function escapeReplace(c) {
switch (c) {
case '&':
return '&amp;';
case '<':
return '&lt;';
case '>':
return '&gt;';
case '"':
return '&quot;'
case '\u00A0':
return '&nbsp;';
}
}
function escapeAttr(s) {
return s.replace(escapeAttrRegExp, escapeReplace);
}
function escapeData(s) {
return s.replace(escapeDataRegExp, escapeReplace);
}
function makeSet(arr) {
var set = {};
for (var i = 0; i < arr.length; i++) {
set[arr[i]] = true;
}
return set;
}
// http://www.whatwg.org/specs/web-apps/current-work/#void-elements
var voidElements = makeSet([
'area',
'base',
'br',
'col',
'command',
'embed',
'hr',
'img',
'input',
'keygen',
'link',
'meta',
'param',
'source',
'track',
'wbr'
]);
var plaintextParents = makeSet([
'style',
'script',
'xmp',
'iframe',
'noembed',
'noframes',
'plaintext',
'noscript'
]);
var XHTML_NS = 'http://www.w3.org/1999/xhtml';
function needsSelfClosingSlash(node) {
// if the namespace is not XHTML_NS, this is probably an XML or SVG Document
// and will need a closing slash on void elements
if (node.namespaceURI !== XHTML_NS)
return true;
var doctype = node.ownerDocument.doctype;
// doctype is null for quirksmode documents
// publicId and systemId are required for XHTML, and are null for HTML5
return doctype && doctype.publicId && doctype.systemId;
}
function getOuterHTML(node, parentNode) {
switch (node.nodeType) {
case Node.ELEMENT_NODE:
var tagName = node.tagName.toLowerCase();
var s = '<' + tagName;
var attrs = node.attributes;
for (var i = 0, attr; attr = attrs[i]; i++) {
s += ' ' + attr.name + '="' + escapeAttr(attr.value) + '"';
}
if (voidElements[tagName]) {
if (needsSelfClosingSlash(node))
s += '/';
return s + '>';
}
return s + '>' + getInnerHTML(node) + '</' + tagName + '>';
case Node.TEXT_NODE:
var data = node.data;
if (parentNode && plaintextParents[parentNode.localName])
return data;
return escapeData(data);
case Node.COMMENT_NODE:
return '<!--' + node.data + '-->';
default:
console.error(node);
throw new Error('not implemented');
}
}
function getInnerHTML(node) {
if (node instanceof wrappers.HTMLTemplateElement)
node = node.content;
var s = '';
for (var child = node.firstChild; child; child = child.nextSibling) {
s += getOuterHTML(child, node);
}
return s;
}
function setInnerHTML(node, value, opt_tagName) {
var tagName = opt_tagName || 'div';
node.textContent = '';
var tempElement = unwrap(node.ownerDocument.createElement(tagName));
tempElement.innerHTML = value;
var firstChild;
while (firstChild = tempElement.firstChild) {
node.appendChild(wrap(firstChild));
}
}
// IE11 does not have MSIE in the user agent string.
var oldIe = /MSIE/.test(navigator.userAgent);
var OriginalHTMLElement = window.HTMLElement;
var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
function HTMLElement(node) {
Element.call(this, node);
}
HTMLElement.prototype = Object.create(Element.prototype);
mixin(HTMLElement.prototype, {
get innerHTML() {
return getInnerHTML(this);
},
set innerHTML(value) {
// IE9 does not handle set innerHTML correctly on plaintextParents. It
// creates element children. For example
//
// scriptElement.innerHTML = '<a>test</a>'
//
// Creates a single HTMLAnchorElement child.
if (oldIe && plaintextParents[this.localName]) {
this.textContent = value;
return;
}
var removedNodes = snapshotNodeList(this.childNodes);
if (this.invalidateShadowRenderer()) {
if (this instanceof wrappers.HTMLTemplateElement)
setInnerHTML(this.content, value);
else
setInnerHTML(this, value, this.tagName);
// If we have a non native template element we need to handle this
// manually since setting impl.innerHTML would add the html as direct
// children and not be moved over to the content fragment.
} else if (!OriginalHTMLTemplateElement &&
this instanceof wrappers.HTMLTemplateElement) {
setInnerHTML(this.content, value);
} else {
unsafeUnwrap(this).innerHTML = value;
}
var addedNodes = snapshotNodeList(this.childNodes);
enqueueMutation(this, 'childList', {
addedNodes: addedNodes,
removedNodes: removedNodes
});
nodesWereRemoved(removedNodes);
nodesWereAdded(addedNodes, this);
},
get outerHTML() {
return getOuterHTML(this, this.parentNode);
},
set outerHTML(value) {
var p = this.parentNode;
if (p) {
p.invalidateShadowRenderer();
var df = frag(p, value);
p.replaceChild(df, this);
}
},
insertAdjacentHTML: function(position, text) {
var contextElement, refNode;
switch (String(position).toLowerCase()) {
case 'beforebegin':
contextElement = this.parentNode;
refNode = this;
break;
case 'afterend':
contextElement = this.parentNode;
refNode = this.nextSibling;
break;
case 'afterbegin':
contextElement = this;
refNode = this.firstChild;
break;
case 'beforeend':
contextElement = this;
refNode = null;
break;
default:
return;
}
var df = frag(contextElement, text);
contextElement.insertBefore(df, refNode);
},
get hidden() {
return this.hasAttribute('hidden');
},
set hidden(v) {
if (v) {
this.setAttribute('hidden', '');
} else {
this.removeAttribute('hidden');
}
}
});
function frag(contextElement, html) {
// TODO(arv): This does not work with SVG and other non HTML elements.
var p = unwrap(contextElement.cloneNode(false));
p.innerHTML = html;
var df = unwrap(document.createDocumentFragment());
var c;
while (c = p.firstChild) {
df.appendChild(c);
}
return wrap(df);
}
function getter(name) {
return function() {
scope.renderAllPending();
return unsafeUnwrap(this)[name];
};
}
function getterRequiresRendering(name) {
defineGetter(HTMLElement, name, getter(name));
}
[
'clientHeight',
'clientLeft',
'clientTop',
'clientWidth',
'offsetHeight',
'offsetLeft',
'offsetTop',
'offsetWidth',
'scrollHeight',
'scrollWidth',
].forEach(getterRequiresRendering);
function getterAndSetterRequiresRendering(name) {
Object.defineProperty(HTMLElement.prototype, name, {
get: getter(name),
set: function(v) {
scope.renderAllPending();
unsafeUnwrap(this)[name] = v;
},
configurable: true,
enumerable: true
});
}
[
'scrollLeft',
'scrollTop',
].forEach(getterAndSetterRequiresRendering);
function methodRequiresRendering(name) {
Object.defineProperty(HTMLElement.prototype, name, {
value: function() {
scope.renderAllPending();
return unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments);
},
configurable: true,
enumerable: true
});
}
[
'focus',
'getBoundingClientRect',
'getClientRects',
'scrollIntoView'
].forEach(methodRequiresRendering);
// HTMLElement is abstract so we use a subclass that has no members.
registerWrapper(OriginalHTMLElement, HTMLElement,
document.createElement('b'));
scope.wrappers.HTMLElement = HTMLElement;
// TODO: Find a better way to share these two with WrapperShadowRoot.
scope.getInnerHTML = getInnerHTML;
scope.setInnerHTML = setInnerHTML
})(window.ShadowDOMPolyfill);

View File

@@ -1,39 +0,0 @@
/**
* @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(scope) {
'use strict';
var HTMLElement = scope.wrappers.HTMLElement;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var wrapHTMLCollection = scope.wrapHTMLCollection;
var unwrap = scope.unwrap;
var OriginalHTMLFormElement = window.HTMLFormElement;
function HTMLFormElement(node) {
HTMLElement.call(this, node);
}
HTMLFormElement.prototype = Object.create(HTMLElement.prototype);
mixin(HTMLFormElement.prototype, {
get elements() {
// Note: technically this should be an HTMLFormControlsCollection, but
// that inherits from HTMLCollection, so should be good enough. Spec:
// http://www.whatwg.org/specs/web-apps/current-work/multipage/common-dom-interfaces.html#htmlformcontrolscollection
return wrapHTMLCollection(unwrap(this).elements);
}
});
registerWrapper(OriginalHTMLFormElement, HTMLFormElement,
document.createElement('form'));
scope.wrappers.HTMLFormElement = HTMLFormElement;
})(window.ShadowDOMPolyfill);

View File

@@ -1,49 +0,0 @@
/**
* @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(scope) {
'use strict';
var HTMLElement = scope.wrappers.HTMLElement;
var registerWrapper = scope.registerWrapper;
var unwrap = scope.unwrap;
var rewrap = scope.rewrap;
var OriginalHTMLImageElement = window.HTMLImageElement;
function HTMLImageElement(node) {
HTMLElement.call(this, node);
}
HTMLImageElement.prototype = Object.create(HTMLElement.prototype);
registerWrapper(OriginalHTMLImageElement, HTMLImageElement,
document.createElement('img'));
function Image(width, height) {
if (!(this instanceof Image)) {
throw new TypeError(
'DOM object constructor cannot be called as a function.');
}
var node = unwrap(document.createElement('img'));
HTMLElement.call(this, node);
rewrap(node, this);
if (width !== undefined)
node.width = width;
if (height !== undefined)
node.height = height;
}
Image.prototype = HTMLImageElement.prototype;
scope.wrappers.HTMLImageElement = HTMLImageElement;
scope.wrappers.Image = Image;
})(window.ShadowDOMPolyfill);

View File

@@ -1,30 +0,0 @@
/**
* @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(scope) {
'use strict';
var HTMLElement = scope.wrappers.HTMLElement;
var registerWrapper = scope.registerWrapper;
var OriginalHTMLMediaElement = window.HTMLMediaElement;
if (!OriginalHTMLMediaElement) return;
function HTMLMediaElement(node) {
HTMLElement.call(this, node);
}
HTMLMediaElement.prototype = Object.create(HTMLElement.prototype);
registerWrapper(OriginalHTMLMediaElement, HTMLMediaElement,
document.createElement('audio'));
scope.wrappers.HTMLMediaElement = HTMLMediaElement;
})(window.ShadowDOMPolyfill);

View File

@@ -1,69 +0,0 @@
/**
* @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(scope) {
'use strict';
var HTMLElement = scope.wrappers.HTMLElement;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var rewrap = scope.rewrap;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var OriginalHTMLOptionElement = window.HTMLOptionElement;
function trimText(s) {
return s.replace(/\s+/g, ' ').trim();
}
function HTMLOptionElement(node) {
HTMLElement.call(this, node);
}
HTMLOptionElement.prototype = Object.create(HTMLElement.prototype);
mixin(HTMLOptionElement.prototype, {
get text() {
return trimText(this.textContent);
},
set text(value) {
this.textContent = trimText(String(value));
},
get form() {
return wrap(unwrap(this).form);
}
});
registerWrapper(OriginalHTMLOptionElement, HTMLOptionElement,
document.createElement('option'));
function Option(text, value, defaultSelected, selected) {
if (!(this instanceof Option)) {
throw new TypeError(
'DOM object constructor cannot be called as a function.');
}
var node = unwrap(document.createElement('option'));
HTMLElement.call(this, node);
rewrap(node, this);
if (text !== undefined)
node.text = text;
if (value !== undefined)
node.setAttribute('value', value);
if (defaultSelected === true)
node.setAttribute('selected', '');
node.selected = selected === true;
}
Option.prototype = HTMLOptionElement.prototype;
scope.wrappers.HTMLOptionElement = HTMLOptionElement;
scope.wrappers.Option = Option;
})(window.ShadowDOMPolyfill);

View File

@@ -1,56 +0,0 @@
/**
* @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(scope) {
'use strict';
var HTMLElement = scope.wrappers.HTMLElement;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var OriginalHTMLSelectElement = window.HTMLSelectElement;
function HTMLSelectElement(node) {
HTMLElement.call(this, node);
}
HTMLSelectElement.prototype = Object.create(HTMLElement.prototype);
mixin(HTMLSelectElement.prototype, {
add: function(element, before) {
if (typeof before === 'object') // also includes null
before = unwrap(before);
unwrap(this).add(unwrap(element), before);
},
remove: function(indexOrNode) {
// Spec only allows index but implementations allow index or node.
// remove() is also allowed which is same as remove(undefined)
if (indexOrNode === undefined) {
HTMLElement.prototype.remove.call(this);
return;
}
if (typeof indexOrNode === 'object')
indexOrNode = unwrap(indexOrNode);
unwrap(this).remove(indexOrNode);
},
get form() {
return wrap(unwrap(this).form);
}
});
registerWrapper(OriginalHTMLSelectElement, HTMLSelectElement,
document.createElement('select'));
scope.wrappers.HTMLSelectElement = HTMLSelectElement;
})(window.ShadowDOMPolyfill);

View File

@@ -1,33 +0,0 @@
/**
* @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(scope) {
'use strict';
var HTMLElement = scope.wrappers.HTMLElement;
var mixin = scope.mixin;
var NodeList = scope.wrappers.NodeList;
var registerWrapper = scope.registerWrapper;
var OriginalHTMLShadowElement = window.HTMLShadowElement;
function HTMLShadowElement(node) {
HTMLElement.call(this, node);
}
HTMLShadowElement.prototype = Object.create(HTMLElement.prototype);
HTMLShadowElement.prototype.constructor = HTMLShadowElement;
// getDistributedNodes is added in ShadowRenderer
if (OriginalHTMLShadowElement)
registerWrapper(OriginalHTMLShadowElement, HTMLShadowElement);
scope.wrappers.HTMLShadowElement = HTMLShadowElement;
})(window.ShadowDOMPolyfill);

View File

@@ -1,68 +0,0 @@
/**
* @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(scope) {
'use strict';
var HTMLElement = scope.wrappers.HTMLElement;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var wrapHTMLCollection = scope.wrapHTMLCollection;
var OriginalHTMLTableElement = window.HTMLTableElement;
function HTMLTableElement(node) {
HTMLElement.call(this, node);
}
HTMLTableElement.prototype = Object.create(HTMLElement.prototype);
mixin(HTMLTableElement.prototype, {
get caption() {
return wrap(unwrap(this).caption);
},
createCaption: function() {
return wrap(unwrap(this).createCaption());
},
get tHead() {
return wrap(unwrap(this).tHead);
},
createTHead: function() {
return wrap(unwrap(this).createTHead());
},
createTFoot: function() {
return wrap(unwrap(this).createTFoot());
},
get tFoot() {
return wrap(unwrap(this).tFoot);
},
get tBodies() {
return wrapHTMLCollection(unwrap(this).tBodies);
},
createTBody: function() {
return wrap(unwrap(this).createTBody());
},
get rows() {
return wrapHTMLCollection(unwrap(this).rows);
},
insertRow: function(index) {
return wrap(unwrap(this).insertRow(index));
}
});
registerWrapper(OriginalHTMLTableElement, HTMLTableElement,
document.createElement('table'));
scope.wrappers.HTMLTableElement = HTMLTableElement;
})(window.ShadowDOMPolyfill);

View File

@@ -1,41 +0,0 @@
/**
* @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(scope) {
'use strict';
var HTMLElement = scope.wrappers.HTMLElement;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var wrapHTMLCollection = scope.wrapHTMLCollection;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var OriginalHTMLTableRowElement = window.HTMLTableRowElement;
function HTMLTableRowElement(node) {
HTMLElement.call(this, node);
}
HTMLTableRowElement.prototype = Object.create(HTMLElement.prototype);
mixin(HTMLTableRowElement.prototype, {
get cells() {
return wrapHTMLCollection(unwrap(this).cells);
},
insertCell: function(index) {
return wrap(unwrap(this).insertCell(index));
}
});
registerWrapper(OriginalHTMLTableRowElement, HTMLTableRowElement,
document.createElement('tr'));
scope.wrappers.HTMLTableRowElement = HTMLTableRowElement;
})(window.ShadowDOMPolyfill);

View File

@@ -1,41 +0,0 @@
/**
* @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(scope) {
'use strict';
var HTMLElement = scope.wrappers.HTMLElement;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var wrapHTMLCollection = scope.wrapHTMLCollection;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var OriginalHTMLTableSectionElement = window.HTMLTableSectionElement;
function HTMLTableSectionElement(node) {
HTMLElement.call(this, node);
}
HTMLTableSectionElement.prototype = Object.create(HTMLElement.prototype);
mixin(HTMLTableSectionElement.prototype, {
constructor: HTMLTableSectionElement,
get rows() {
return wrapHTMLCollection(unwrap(this).rows);
},
insertRow: function(index) {
return wrap(unwrap(this).insertRow(index));
}
});
registerWrapper(OriginalHTMLTableSectionElement, HTMLTableSectionElement,
document.createElement('thead'));
scope.wrappers.HTMLTableSectionElement = HTMLTableSectionElement;
})(window.ShadowDOMPolyfill);

View File

@@ -1,79 +0,0 @@
/**
* @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(scope) {
'use strict';
var HTMLElement = scope.wrappers.HTMLElement;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var contentTable = new WeakMap();
var templateContentsOwnerTable = new WeakMap();
// http://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/templates/index.html#dfn-template-contents-owner
function getTemplateContentsOwner(doc) {
if (!doc.defaultView)
return doc;
var d = templateContentsOwnerTable.get(doc);
if (!d) {
// TODO(arv): This should either be a Document or HTMLDocument depending
// on doc.
d = doc.implementation.createHTMLDocument('');
while (d.lastChild) {
d.removeChild(d.lastChild);
}
templateContentsOwnerTable.set(doc, d);
}
return d;
}
function extractContent(templateElement) {
// templateElement is not a wrapper here.
var doc = getTemplateContentsOwner(templateElement.ownerDocument);
var df = unwrap(doc.createDocumentFragment());
var child;
while (child = templateElement.firstChild) {
df.appendChild(child);
}
return df;
}
var OriginalHTMLTemplateElement = window.HTMLTemplateElement;
function HTMLTemplateElement(node) {
HTMLElement.call(this, node);
if (!OriginalHTMLTemplateElement) {
var content = extractContent(node);
contentTable.set(this, wrap(content));
}
}
HTMLTemplateElement.prototype = Object.create(HTMLElement.prototype);
mixin(HTMLTemplateElement.prototype, {
constructor: HTMLTemplateElement,
get content() {
if (OriginalHTMLTemplateElement)
return wrap(unsafeUnwrap(this).content);
return contentTable.get(this);
},
// TODO(arv): cloneNode needs to clone content.
});
if (OriginalHTMLTemplateElement)
registerWrapper(OriginalHTMLTemplateElement, HTMLTemplateElement);
scope.wrappers.HTMLTemplateElement = HTMLTemplateElement;
})(window.ShadowDOMPolyfill);

View File

@@ -1,37 +0,0 @@
/**
* @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(scope) {
'use strict';
var HTMLContentElement = scope.wrappers.HTMLContentElement;
var HTMLElement = scope.wrappers.HTMLElement;
var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
var HTMLTemplateElement = scope.wrappers.HTMLTemplateElement;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var OriginalHTMLUnknownElement = window.HTMLUnknownElement;
function HTMLUnknownElement(node) {
switch (node.localName) {
case 'content':
return new HTMLContentElement(node);
case 'shadow':
return new HTMLShadowElement(node);
case 'template':
return new HTMLTemplateElement(node);
}
HTMLElement.call(this, node);
}
HTMLUnknownElement.prototype = Object.create(HTMLElement.prototype);
registerWrapper(OriginalHTMLUnknownElement, HTMLUnknownElement);
scope.wrappers.HTMLUnknownElement = HTMLUnknownElement;
})(window.ShadowDOMPolyfill);

View File

@@ -1,748 +0,0 @@
/**
* @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(scope) {
'use strict';
var EventTarget = scope.wrappers.EventTarget;
var NodeList = scope.wrappers.NodeList;
var TreeScope = scope.TreeScope;
var assert = scope.assert;
var defineWrapGetter = scope.defineWrapGetter;
var enqueueMutation = scope.enqueueMutation;
var getTreeScope = scope.getTreeScope;
var isWrapper = scope.isWrapper;
var mixin = scope.mixin;
var registerTransientObservers = scope.registerTransientObservers;
var registerWrapper = scope.registerWrapper;
var setTreeScope = scope.setTreeScope;
var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;
var wrapIfNeeded = scope.wrapIfNeeded;
var wrappers = scope.wrappers;
function assertIsNodeWrapper(node) {
assert(node instanceof Node);
}
function createOneElementNodeList(node) {
var nodes = new NodeList();
nodes[0] = node;
nodes.length = 1;
return nodes;
}
var surpressMutations = false;
/**
* Called before node is inserted into a node to enqueue its removal from its
* old parent.
* @param {!Node} node The node that is about to be removed.
* @param {!Node} parent The parent node that the node is being removed from.
* @param {!NodeList} nodes The collected nodes.
*/
function enqueueRemovalForInsertedNodes(node, parent, nodes) {
enqueueMutation(parent, 'childList', {
removedNodes: nodes,
previousSibling: node.previousSibling,
nextSibling: node.nextSibling
});
}
function enqueueRemovalForInsertedDocumentFragment(df, nodes) {
enqueueMutation(df, 'childList', {
removedNodes: nodes
});
}
/**
* Collects nodes from a DocumentFragment or a Node for removal followed
* by an insertion.
*
* This updates the internal pointers for node, previousNode and nextNode.
*/
function collectNodes(node, parentNode, previousNode, nextNode) {
if (node instanceof DocumentFragment) {
var nodes = collectNodesForDocumentFragment(node);
// The extra loop is to work around bugs with DocumentFragments in IE.
surpressMutations = true;
for (var i = nodes.length - 1; i >= 0; i--) {
node.removeChild(nodes[i]);
nodes[i].parentNode_ = parentNode;
}
surpressMutations = false;
for (var i = 0; i < nodes.length; i++) {
nodes[i].previousSibling_ = nodes[i - 1] || previousNode;
nodes[i].nextSibling_ = nodes[i + 1] || nextNode;
}
if (previousNode)
previousNode.nextSibling_ = nodes[0];
if (nextNode)
nextNode.previousSibling_ = nodes[nodes.length - 1];
return nodes;
}
var nodes = createOneElementNodeList(node);
var oldParent = node.parentNode;
if (oldParent) {
// This will enqueue the mutation record for the removal as needed.
oldParent.removeChild(node);
}
node.parentNode_ = parentNode;
node.previousSibling_ = previousNode;
node.nextSibling_ = nextNode;
if (previousNode)
previousNode.nextSibling_ = node;
if (nextNode)
nextNode.previousSibling_ = node;
return nodes;
}
function collectNodesNative(node) {
if (node instanceof DocumentFragment)
return collectNodesForDocumentFragment(node);
var nodes = createOneElementNodeList(node);
var oldParent = node.parentNode;
if (oldParent)
enqueueRemovalForInsertedNodes(node, oldParent, nodes);
return nodes;
}
function collectNodesForDocumentFragment(node) {
var nodes = new NodeList();
var i = 0;
for (var child = node.firstChild; child; child = child.nextSibling) {
nodes[i++] = child;
}
nodes.length = i;
enqueueRemovalForInsertedDocumentFragment(node, nodes);
return nodes;
}
function snapshotNodeList(nodeList) {
// NodeLists are not live at the moment so just return the same object.
return nodeList;
}
// http://dom.spec.whatwg.org/#node-is-inserted
function nodeWasAdded(node, treeScope) {
setTreeScope(node, treeScope);
node.nodeIsInserted_();
}
function nodesWereAdded(nodes, parent) {
var treeScope = getTreeScope(parent);
for (var i = 0; i < nodes.length; i++) {
nodeWasAdded(nodes[i], treeScope);
}
}
// http://dom.spec.whatwg.org/#node-is-removed
function nodeWasRemoved(node) {
setTreeScope(node, new TreeScope(node, null));
}
function nodesWereRemoved(nodes) {
for (var i = 0; i < nodes.length; i++) {
nodeWasRemoved(nodes[i]);
}
}
function ensureSameOwnerDocument(parent, child) {
var ownerDoc = parent.nodeType === Node.DOCUMENT_NODE ?
parent : parent.ownerDocument;
if (ownerDoc !== child.ownerDocument)
ownerDoc.adoptNode(child);
}
function adoptNodesIfNeeded(owner, nodes) {
if (!nodes.length)
return;
var ownerDoc = owner.ownerDocument;
// All nodes have the same ownerDocument when we get here.
if (ownerDoc === nodes[0].ownerDocument)
return;
for (var i = 0; i < nodes.length; i++) {
scope.adoptNodeNoRemove(nodes[i], ownerDoc);
}
}
function unwrapNodesForInsertion(owner, nodes) {
adoptNodesIfNeeded(owner, nodes);
var length = nodes.length;
if (length === 1)
return unwrap(nodes[0]);
var df = unwrap(owner.ownerDocument.createDocumentFragment());
for (var i = 0; i < length; i++) {
df.appendChild(unwrap(nodes[i]));
}
return df;
}
function clearChildNodes(wrapper) {
if (wrapper.firstChild_ !== undefined) {
var child = wrapper.firstChild_;
while (child) {
var tmp = child;
child = child.nextSibling_;
tmp.parentNode_ = tmp.previousSibling_ = tmp.nextSibling_ = undefined;
}
}
wrapper.firstChild_ = wrapper.lastChild_ = undefined;
}
function removeAllChildNodes(wrapper) {
if (wrapper.invalidateShadowRenderer()) {
var childWrapper = wrapper.firstChild;
while (childWrapper) {
assert(childWrapper.parentNode === wrapper);
var nextSibling = childWrapper.nextSibling;
var childNode = unwrap(childWrapper);
var parentNode = childNode.parentNode;
if (parentNode)
originalRemoveChild.call(parentNode, childNode);
childWrapper.previousSibling_ = childWrapper.nextSibling_ =
childWrapper.parentNode_ = null;
childWrapper = nextSibling;
}
wrapper.firstChild_ = wrapper.lastChild_ = null;
} else {
var node = unwrap(wrapper);
var child = node.firstChild;
var nextSibling;
while (child) {
nextSibling = child.nextSibling;
originalRemoveChild.call(node, child);
child = nextSibling;
}
}
}
function invalidateParent(node) {
var p = node.parentNode;
return p && p.invalidateShadowRenderer();
}
function cleanupNodes(nodes) {
for (var i = 0, n; i < nodes.length; i++) {
n = nodes[i];
n.parentNode.removeChild(n);
}
}
var originalImportNode = document.importNode;
var originalCloneNode = window.Node.prototype.cloneNode;
function cloneNode(node, deep, opt_doc) {
var clone;
if (opt_doc)
clone = wrap(originalImportNode.call(opt_doc, unsafeUnwrap(node), false));
else
clone = wrap(originalCloneNode.call(unsafeUnwrap(node), false));
if (deep) {
for (var child = node.firstChild; child; child = child.nextSibling) {
clone.appendChild(cloneNode(child, true, opt_doc));
}
if (node instanceof wrappers.HTMLTemplateElement) {
var cloneContent = clone.content;
for (var child = node.content.firstChild;
child;
child = child.nextSibling) {
cloneContent.appendChild(cloneNode(child, true, opt_doc));
}
}
}
// TODO(arv): Some HTML elements also clone other data like value.
return clone;
}
function contains(self, child) {
if (!child || getTreeScope(self) !== getTreeScope(child))
return false;
for (var node = child; node; node = node.parentNode) {
if (node === self)
return true;
}
return false;
}
var OriginalNode = window.Node;
/**
* This represents a wrapper of a native DOM node.
* @param {!Node} original The original DOM node, aka, the visual DOM node.
* @constructor
* @extends {EventTarget}
*/
function Node(original) {
assert(original instanceof OriginalNode);
EventTarget.call(this, original);
// These properties are used to override the visual references with the
// logical ones. If the value is undefined it means that the logical is the
// same as the visual.
/**
* @type {Node|undefined}
* @private
*/
this.parentNode_ = undefined;
/**
* @type {Node|undefined}
* @private
*/
this.firstChild_ = undefined;
/**
* @type {Node|undefined}
* @private
*/
this.lastChild_ = undefined;
/**
* @type {Node|undefined}
* @private
*/
this.nextSibling_ = undefined;
/**
* @type {Node|undefined}
* @private
*/
this.previousSibling_ = undefined;
this.treeScope_ = undefined;
}
var OriginalDocumentFragment = window.DocumentFragment;
var originalAppendChild = OriginalNode.prototype.appendChild;
var originalCompareDocumentPosition =
OriginalNode.prototype.compareDocumentPosition;
var originalIsEqualNode = OriginalNode.prototype.isEqualNode;
var originalInsertBefore = OriginalNode.prototype.insertBefore;
var originalRemoveChild = OriginalNode.prototype.removeChild;
var originalReplaceChild = OriginalNode.prototype.replaceChild;
var isIEOrEdge = /Trident|Edge/.test(navigator.userAgent);
var removeChildOriginalHelper = isIEOrEdge ?
function(parent, child) {
try {
originalRemoveChild.call(parent, child);
} catch (ex) {
if (!(parent instanceof OriginalDocumentFragment))
throw ex;
}
} :
function(parent, child) {
originalRemoveChild.call(parent, child);
};
Node.prototype = Object.create(EventTarget.prototype);
mixin(Node.prototype, {
appendChild: function(childWrapper) {
return this.insertBefore(childWrapper, null);
},
insertBefore: function(childWrapper, refWrapper) {
assertIsNodeWrapper(childWrapper);
var refNode;
if (refWrapper) {
if (isWrapper(refWrapper)) {
refNode = unwrap(refWrapper);
} else {
refNode = refWrapper;
refWrapper = wrap(refNode);
}
} else {
refWrapper = null;
refNode = null;
}
refWrapper && assert(refWrapper.parentNode === this);
var nodes;
var previousNode =
refWrapper ? refWrapper.previousSibling : this.lastChild;
var useNative = !this.invalidateShadowRenderer() &&
!invalidateParent(childWrapper);
if (useNative)
nodes = collectNodesNative(childWrapper);
else
nodes = collectNodes(childWrapper, this, previousNode, refWrapper);
if (useNative) {
ensureSameOwnerDocument(this, childWrapper);
clearChildNodes(this);
originalInsertBefore.call(unsafeUnwrap(this), unwrap(childWrapper), refNode);
} else {
if (!previousNode)
this.firstChild_ = nodes[0];
if (!refWrapper) {
this.lastChild_ = nodes[nodes.length - 1];
if (this.firstChild_ === undefined)
this.firstChild_ = this.firstChild;
}
var parentNode = refNode ? refNode.parentNode : unsafeUnwrap(this);
// insertBefore refWrapper no matter what the parent is?
if (parentNode) {
originalInsertBefore.call(parentNode,
unwrapNodesForInsertion(this, nodes), refNode);
} else {
adoptNodesIfNeeded(this, nodes);
}
}
enqueueMutation(this, 'childList', {
addedNodes: nodes,
nextSibling: refWrapper,
previousSibling: previousNode
});
nodesWereAdded(nodes, this);
return childWrapper;
},
removeChild: function(childWrapper) {
assertIsNodeWrapper(childWrapper);
if (childWrapper.parentNode !== this) {
// IE has invalid DOM trees at times.
var found = false;
var childNodes = this.childNodes;
for (var ieChild = this.firstChild; ieChild;
ieChild = ieChild.nextSibling) {
if (ieChild === childWrapper) {
found = true;
break;
}
}
if (!found) {
// TODO(arv): DOMException
throw new Error('NotFoundError');
}
}
var childNode = unwrap(childWrapper);
var childWrapperNextSibling = childWrapper.nextSibling;
var childWrapperPreviousSibling = childWrapper.previousSibling;
if (this.invalidateShadowRenderer()) {
// We need to remove the real node from the DOM before updating the
// pointers. This is so that that mutation event is dispatched before
// the pointers have changed.
var thisFirstChild = this.firstChild;
var thisLastChild = this.lastChild;
var parentNode = childNode.parentNode;
if (parentNode)
removeChildOriginalHelper(parentNode, childNode);
if (thisFirstChild === childWrapper)
this.firstChild_ = childWrapperNextSibling;
if (thisLastChild === childWrapper)
this.lastChild_ = childWrapperPreviousSibling;
if (childWrapperPreviousSibling)
childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling;
if (childWrapperNextSibling) {
childWrapperNextSibling.previousSibling_ =
childWrapperPreviousSibling;
}
childWrapper.previousSibling_ = childWrapper.nextSibling_ =
childWrapper.parentNode_ = undefined;
} else {
clearChildNodes(this);
removeChildOriginalHelper(unsafeUnwrap(this), childNode);
}
if (!surpressMutations) {
enqueueMutation(this, 'childList', {
removedNodes: createOneElementNodeList(childWrapper),
nextSibling: childWrapperNextSibling,
previousSibling: childWrapperPreviousSibling
});
}
registerTransientObservers(this, childWrapper);
return childWrapper;
},
replaceChild: function(newChildWrapper, oldChildWrapper) {
assertIsNodeWrapper(newChildWrapper);
var oldChildNode;
if (isWrapper(oldChildWrapper)) {
oldChildNode = unwrap(oldChildWrapper);
} else {
oldChildNode = oldChildWrapper;
oldChildWrapper = wrap(oldChildNode);
}
if (oldChildWrapper.parentNode !== this) {
// TODO(arv): DOMException
throw new Error('NotFoundError');
}
var nextNode = oldChildWrapper.nextSibling;
var previousNode = oldChildWrapper.previousSibling;
var nodes;
var useNative = !this.invalidateShadowRenderer() &&
!invalidateParent(newChildWrapper);
if (useNative) {
nodes = collectNodesNative(newChildWrapper);
} else {
if (nextNode === newChildWrapper)
nextNode = newChildWrapper.nextSibling;
nodes = collectNodes(newChildWrapper, this, previousNode, nextNode);
}
if (!useNative) {
if (this.firstChild === oldChildWrapper)
this.firstChild_ = nodes[0];
if (this.lastChild === oldChildWrapper)
this.lastChild_ = nodes[nodes.length - 1];
oldChildWrapper.previousSibling_ = oldChildWrapper.nextSibling_ =
oldChildWrapper.parentNode_ = undefined;
// replaceChild no matter what the parent is?
if (oldChildNode.parentNode) {
originalReplaceChild.call(
oldChildNode.parentNode,
unwrapNodesForInsertion(this, nodes),
oldChildNode);
}
} else {
ensureSameOwnerDocument(this, newChildWrapper);
clearChildNodes(this);
originalReplaceChild.call(unsafeUnwrap(this), unwrap(newChildWrapper),
oldChildNode);
}
enqueueMutation(this, 'childList', {
addedNodes: nodes,
removedNodes: createOneElementNodeList(oldChildWrapper),
nextSibling: nextNode,
previousSibling: previousNode
});
nodeWasRemoved(oldChildWrapper);
nodesWereAdded(nodes, this);
return oldChildWrapper;
},
/**
* Called after a node was inserted. Subclasses override this to invalidate
* the renderer as needed.
* @private
*/
nodeIsInserted_: function() {
for (var child = this.firstChild; child; child = child.nextSibling) {
child.nodeIsInserted_();
}
},
hasChildNodes: function() {
return this.firstChild !== null;
},
/** @type {Node} */
get parentNode() {
// If the parentNode has not been overridden, use the original parentNode.
return this.parentNode_ !== undefined ?
this.parentNode_ : wrap(unsafeUnwrap(this).parentNode);
},
/** @type {Node} */
get firstChild() {
return this.firstChild_ !== undefined ?
this.firstChild_ : wrap(unsafeUnwrap(this).firstChild);
},
/** @type {Node} */
get lastChild() {
return this.lastChild_ !== undefined ?
this.lastChild_ : wrap(unsafeUnwrap(this).lastChild);
},
/** @type {Node} */
get nextSibling() {
return this.nextSibling_ !== undefined ?
this.nextSibling_ : wrap(unsafeUnwrap(this).nextSibling);
},
/** @type {Node} */
get previousSibling() {
return this.previousSibling_ !== undefined ?
this.previousSibling_ : wrap(unsafeUnwrap(this).previousSibling);
},
get parentElement() {
var p = this.parentNode;
while (p && p.nodeType !== Node.ELEMENT_NODE) {
p = p.parentNode;
}
return p;
},
get textContent() {
// TODO(arv): This should fallback to unsafeUnwrap(this).textContent if there
// are no shadow trees below or above the context node.
var s = '';
for (var child = this.firstChild; child; child = child.nextSibling) {
if (child.nodeType != Node.COMMENT_NODE) {
s += child.textContent;
}
}
return s;
},
set textContent(textContent) {
if (textContent == null) textContent = '';
var removedNodes = snapshotNodeList(this.childNodes);
if (this.invalidateShadowRenderer()) {
removeAllChildNodes(this);
if (textContent !== '') {
var textNode = unsafeUnwrap(this).ownerDocument.createTextNode(textContent);
this.appendChild(textNode);
}
} else {
clearChildNodes(this);
unsafeUnwrap(this).textContent = textContent;
}
var addedNodes = snapshotNodeList(this.childNodes);
enqueueMutation(this, 'childList', {
addedNodes: addedNodes,
removedNodes: removedNodes
});
nodesWereRemoved(removedNodes);
nodesWereAdded(addedNodes, this);
},
get childNodes() {
var wrapperList = new NodeList();
var i = 0;
for (var child = this.firstChild; child; child = child.nextSibling) {
wrapperList[i++] = child;
}
wrapperList.length = i;
return wrapperList;
},
cloneNode: function(deep) {
return cloneNode(this, deep);
},
contains: function(child) {
return contains(this, wrapIfNeeded(child));
},
compareDocumentPosition: function(otherNode) {
// This only wraps, it therefore only operates on the composed DOM and not
// the logical DOM.
return originalCompareDocumentPosition.call(unsafeUnwrap(this),
unwrapIfNeeded(otherNode));
},
isEqualNode: function(otherNode){
return originalIsEqualNode.call(unsafeUnwrap(this), unwrapIfNeeded(otherNode));
},
normalize: function() {
var nodes = snapshotNodeList(this.childNodes);
var remNodes = [];
var s = '';
var modNode;
for (var i = 0, n; i < nodes.length; i++) {
n = nodes[i];
if (n.nodeType === Node.TEXT_NODE) {
if (!modNode && !n.data.length)
this.removeChild(n);
else if (!modNode)
modNode = n;
else {
s += n.data;
remNodes.push(n);
}
} else {
if (modNode && remNodes.length) {
modNode.data += s;
cleanupNodes(remNodes);
}
remNodes = [];
s = '';
modNode = null;
if (n.childNodes.length)
n.normalize();
}
}
// handle case where >1 text nodes are the last children
if (modNode && remNodes.length) {
modNode.data += s;
cleanupNodes(remNodes);
}
}
});
defineWrapGetter(Node, 'ownerDocument');
// We use a DocumentFragment as a base and then delete the properties of
// DocumentFragment.prototype from the wrapper Node. Since delete makes
// objects slow in some JS engines we recreate the prototype object.
registerWrapper(OriginalNode, Node, document.createDocumentFragment());
delete Node.prototype.querySelector;
delete Node.prototype.querySelectorAll;
Node.prototype = mixin(Object.create(EventTarget.prototype), Node.prototype);
scope.cloneNode = cloneNode;
scope.nodeWasAdded = nodeWasAdded;
scope.nodeWasRemoved = nodeWasRemoved;
scope.nodesWereAdded = nodesWereAdded;
scope.nodesWereRemoved = nodesWereRemoved;
scope.originalInsertBefore = originalInsertBefore;
scope.originalRemoveChild = originalRemoveChild;
scope.snapshotNodeList = snapshotNodeList;
scope.wrappers.Node = Node;
})(window.ShadowDOMPolyfill);

View File

@@ -1,56 +0,0 @@
/**
* @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(scope) {
'use strict';
var unsafeUnwrap = scope.unsafeUnwrap;
var wrap = scope.wrap;
var nonEnumDescriptor = {enumerable: false};
function nonEnum(obj, prop) {
Object.defineProperty(obj, prop, nonEnumDescriptor);
}
function NodeList() {
this.length = 0;
nonEnum(this, 'length');
}
NodeList.prototype = {
item: function(index) {
return this[index];
}
};
nonEnum(NodeList.prototype, 'item');
function wrapNodeList(list) {
if (list == null)
return list;
var wrapperList = new NodeList();
for (var i = 0, length = list.length; i < length; i++) {
wrapperList[i] = wrap(list[i]);
}
wrapperList.length = length;
return wrapperList;
}
function addWrapNodeListMethod(wrapperConstructor, name) {
wrapperConstructor.prototype[name] = function() {
return wrapNodeList(
unsafeUnwrap(this)[name].apply(unsafeUnwrap(this), arguments));
};
}
scope.wrappers.NodeList = NodeList;
scope.addWrapNodeListMethod = addWrapNodeListMethod;
scope.wrapNodeList = wrapNodeList;
})(window.ShadowDOMPolyfill);

View File

@@ -1,142 +0,0 @@
/**
* @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(scope) {
'use strict';
var registerWrapper = scope.registerWrapper;
var setWrapper = scope.setWrapper;
var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;
var getTreeScope = scope.getTreeScope;
var OriginalRange = window.Range;
var ShadowRoot = scope.wrappers.ShadowRoot;
function getHost(node) {
var root = getTreeScope(node).root;
if (root instanceof ShadowRoot) {
return root.host;
}
return null;
}
function hostNodeToShadowNode(refNode, offset) {
if (refNode.shadowRoot) {
// Note: if the refNode is an element, then selecting a range with and
// offset equal to refNode.childNodes.length+1 is valid. That is why
// calling Math.min is necessary to make sure we select valid children.
offset = Math.min(refNode.childNodes.length - 1, offset);
var child = refNode.childNodes[offset];
if (child) {
var insertionPoint = scope.getDestinationInsertionPoints(child);
if (insertionPoint.length > 0) {
var parentNode = insertionPoint[0].parentNode;
if (parentNode.nodeType == Node.ELEMENT_NODE) {
refNode = parentNode;
}
}
}
}
return refNode;
}
function shadowNodeToHostNode(node) {
node = wrap(node);
return getHost(node) || node;
}
function Range(impl) {
setWrapper(impl, this);
}
Range.prototype = {
get startContainer() {
// Never return a node in the shadow dom.
return shadowNodeToHostNode(unsafeUnwrap(this).startContainer);
},
get endContainer() {
return shadowNodeToHostNode(unsafeUnwrap(this).endContainer);
},
get commonAncestorContainer() {
return shadowNodeToHostNode(unsafeUnwrap(this).commonAncestorContainer);
},
setStart: function(refNode, offset) {
refNode = hostNodeToShadowNode(refNode, offset);
unsafeUnwrap(this).setStart(unwrapIfNeeded(refNode), offset);
},
setEnd: function(refNode, offset) {
refNode = hostNodeToShadowNode(refNode, offset);
unsafeUnwrap(this).setEnd(unwrapIfNeeded(refNode), offset);
},
setStartBefore: function(refNode) {
unsafeUnwrap(this).setStartBefore(unwrapIfNeeded(refNode));
},
setStartAfter: function(refNode) {
unsafeUnwrap(this).setStartAfter(unwrapIfNeeded(refNode));
},
setEndBefore: function(refNode) {
unsafeUnwrap(this).setEndBefore(unwrapIfNeeded(refNode));
},
setEndAfter: function(refNode) {
unsafeUnwrap(this).setEndAfter(unwrapIfNeeded(refNode));
},
selectNode: function(refNode) {
unsafeUnwrap(this).selectNode(unwrapIfNeeded(refNode));
},
selectNodeContents: function(refNode) {
unsafeUnwrap(this).selectNodeContents(unwrapIfNeeded(refNode));
},
compareBoundaryPoints: function(how, sourceRange) {
return unsafeUnwrap(this).compareBoundaryPoints(how, unwrap(sourceRange));
},
extractContents: function() {
return wrap(unsafeUnwrap(this).extractContents());
},
cloneContents: function() {
return wrap(unsafeUnwrap(this).cloneContents());
},
insertNode: function(node) {
unsafeUnwrap(this).insertNode(unwrapIfNeeded(node));
},
surroundContents: function(newParent) {
unsafeUnwrap(this).surroundContents(unwrapIfNeeded(newParent));
},
cloneRange: function() {
return wrap(unsafeUnwrap(this).cloneRange());
},
isPointInRange: function(node, offset) {
return unsafeUnwrap(this).isPointInRange(unwrapIfNeeded(node), offset);
},
comparePoint: function(node, offset) {
return unsafeUnwrap(this).comparePoint(unwrapIfNeeded(node), offset);
},
intersectsNode: function(node) {
return unsafeUnwrap(this).intersectsNode(unwrapIfNeeded(node));
},
toString: function() {
return unsafeUnwrap(this).toString();
}
};
// IE9 does not have createContextualFragment.
if (OriginalRange.prototype.createContextualFragment) {
Range.prototype.createContextualFragment = function(html) {
return wrap(unsafeUnwrap(this).createContextualFragment(html));
};
}
registerWrapper(window.Range, Range, document.createRange());
scope.wrappers.Range = Range;
})(window.ShadowDOMPolyfill);

View File

@@ -1,51 +0,0 @@
/**
* @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(scope) {
'use strict';
var Element = scope.wrappers.Element;
var HTMLElement = scope.wrappers.HTMLElement;
var registerWrapper = scope.registerWrapper;
var defineWrapGetter = scope.defineWrapGetter;
var unsafeUnwrap = scope.unsafeUnwrap;
var wrap = scope.wrap;
var mixin = scope.mixin;
var SVG_NS = 'http://www.w3.org/2000/svg';
var OriginalSVGElement = window.SVGElement;
var svgTitleElement = document.createElementNS(SVG_NS, 'title');
// IE11 does not have classList for SVG elements. The spec says that classList
// is an accessor on Element, but IE11 puts classList on HTMLElement, leaving
// SVGElement without a classList property. We therefore move the accessor for
// IE11.
if (!('classList' in svgTitleElement)) {
var descr = Object.getOwnPropertyDescriptor(Element.prototype, 'classList');
Object.defineProperty(HTMLElement.prototype, 'classList', descr);
delete Element.prototype.classList;
}
function SVGElement(node) {
Element.call(this, node);
}
SVGElement.prototype = Object.create(Element.prototype);
mixin(SVGElement.prototype, {
get ownerSVGElement() {
return wrap(unsafeUnwrap(this).ownerSVGElement);
}
});
registerWrapper(OriginalSVGElement, SVGElement, document.createElementNS(SVG_NS, 'title'));
scope.wrappers.SVGElement = SVGElement;
})(window.ShadowDOMPolyfill);

View File

@@ -1,74 +0,0 @@
/**
* @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(scope) {
'use strict';
var EventTarget = scope.wrappers.EventTarget;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var unsafeUnwrap = scope.unsafeUnwrap;
var wrap = scope.wrap;
var OriginalSVGElementInstance = window.SVGElementInstance;
if (!OriginalSVGElementInstance)
return;
function SVGElementInstance(impl) {
EventTarget.call(this, impl);
}
SVGElementInstance.prototype = Object.create(EventTarget.prototype);
mixin(SVGElementInstance.prototype, {
/** @type {SVGElement} */
get correspondingElement() {
return wrap(unsafeUnwrap(this).correspondingElement);
},
/** @type {SVGUseElement} */
get correspondingUseElement() {
return wrap(unsafeUnwrap(this).correspondingUseElement);
},
/** @type {SVGElementInstance} */
get parentNode() {
return wrap(unsafeUnwrap(this).parentNode);
},
/** @type {SVGElementInstanceList} */
get childNodes() {
throw new Error('Not implemented');
},
/** @type {SVGElementInstance} */
get firstChild() {
return wrap(unsafeUnwrap(this).firstChild);
},
/** @type {SVGElementInstance} */
get lastChild() {
return wrap(unsafeUnwrap(this).lastChild);
},
/** @type {SVGElementInstance} */
get previousSibling() {
return wrap(unsafeUnwrap(this).previousSibling);
},
/** @type {SVGElementInstance} */
get nextSibling() {
return wrap(unsafeUnwrap(this).nextSibling);
}
});
registerWrapper(OriginalSVGElementInstance, SVGElementInstance);
scope.wrappers.SVGElementInstance = SVGElementInstance;
})(window.ShadowDOMPolyfill);

View File

@@ -1,52 +0,0 @@
/**
* @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(scope) {
'use strict';
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var OriginalSVGUseElement = window.SVGUseElement;
// IE uses SVGElement as parent interface, SVG2 (Blink & Gecko) uses
// SVGGraphicsElement. Use the <g> element to get the right prototype.
var SVG_NS = 'http://www.w3.org/2000/svg';
var gWrapper = wrap(document.createElementNS(SVG_NS, 'g'));
var useElement = document.createElementNS(SVG_NS, 'use');
var SVGGElement = gWrapper.constructor;
var parentInterfacePrototype = Object.getPrototypeOf(SVGGElement.prototype);
var parentInterface = parentInterfacePrototype.constructor;
function SVGUseElement(impl) {
parentInterface.call(this, impl);
}
SVGUseElement.prototype = Object.create(parentInterfacePrototype);
// Firefox does not expose instanceRoot.
if ('instanceRoot' in useElement) {
mixin(SVGUseElement.prototype, {
get instanceRoot() {
return wrap(unwrap(this).instanceRoot);
},
get animatedInstanceRoot() {
return wrap(unwrap(this).animatedInstanceRoot);
},
});
}
registerWrapper(OriginalSVGUseElement, SVGUseElement, useElement);
scope.wrappers.SVGUseElement = SVGUseElement;
})(window.ShadowDOMPolyfill);

View File

@@ -1,85 +0,0 @@
/**
* @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(scope) {
'use strict';
var registerWrapper = scope.registerWrapper;
var setWrapper = scope.setWrapper;
var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;
var OriginalSelection = window.Selection;
function Selection(impl) {
setWrapper(impl, this);
}
Selection.prototype = {
get anchorNode() {
return wrap(unsafeUnwrap(this).anchorNode);
},
get focusNode() {
return wrap(unsafeUnwrap(this).focusNode);
},
addRange: function(range) {
unsafeUnwrap(this).addRange(unwrapIfNeeded(range));
},
collapse: function(node, index) {
unsafeUnwrap(this).collapse(unwrapIfNeeded(node), index);
},
containsNode: function(node, allowPartial) {
return unsafeUnwrap(this).containsNode(unwrapIfNeeded(node), allowPartial);
},
getRangeAt: function(index) {
return wrap(unsafeUnwrap(this).getRangeAt(index));
},
removeRange: function(range) {
unsafeUnwrap(this).removeRange(unwrap(range));
},
selectAllChildren: function(node) {
unsafeUnwrap(this).selectAllChildren(
node instanceof ShadowRoot ? unsafeUnwrap(node.host) : unwrapIfNeeded(node)
);
},
toString: function() {
return unsafeUnwrap(this).toString();
}
};
// Not all browsers support Selection.extend. IE does not support extend.
// https://msdn.microsoft.com/en-us/library/ie/ms535869%28v=vs.85%29.aspx
// Code that checks if extend exists in the Selection would
// fail the test if we define extend on the wrapper and it does not exist in
// the browser Selection object.
if (OriginalSelection.prototype.extend) {
Selection.prototype.extend = function(node, offset) {
unsafeUnwrap(this).extend(unwrapIfNeeded(node), offset);
};
}
// WebKit extensions. Not implemented.
// readonly attribute Node baseNode;
// readonly attribute long baseOffset;
// readonly attribute Node extentNode;
// readonly attribute long extentOffset;
// [RaisesException] void setBaseAndExtent([Default=Undefined] optional Node baseNode,
// [Default=Undefined] optional long baseOffset,
// [Default=Undefined] optional Node extentNode,
// [Default=Undefined] optional long extentOffset);
// [RaisesException, ImplementedAs=collapse] void setPosition([Default=Undefined] optional Node node,
// [Default=Undefined] optional long offset);
registerWrapper(window.Selection, Selection, window.getSelection());
scope.wrappers.Selection = Selection;
})(window.ShadowDOMPolyfill);

View File

@@ -1,107 +0,0 @@
/**
* @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(scope) {
'use strict';
var DocumentFragment = scope.wrappers.DocumentFragment;
var TreeScope = scope.TreeScope;
var elementFromPoint = scope.elementFromPoint;
var getInnerHTML = scope.getInnerHTML;
var getTreeScope = scope.getTreeScope;
var mixin = scope.mixin;
var rewrap = scope.rewrap;
var setInnerHTML = scope.setInnerHTML;
var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var shadowHostTable = new WeakMap();
var nextOlderShadowTreeTable = new WeakMap();
function ShadowRoot(hostWrapper) {
var node = unwrap(unsafeUnwrap(hostWrapper).ownerDocument.createDocumentFragment());
DocumentFragment.call(this, node);
// createDocumentFragment associates the node with a wrapper
// DocumentFragment instance. Override that.
rewrap(node, this);
var oldShadowRoot = hostWrapper.shadowRoot;
nextOlderShadowTreeTable.set(this, oldShadowRoot);
this.treeScope_ =
new TreeScope(this, getTreeScope(oldShadowRoot || hostWrapper));
shadowHostTable.set(this, hostWrapper);
}
ShadowRoot.prototype = Object.create(DocumentFragment.prototype);
mixin(ShadowRoot.prototype, {
constructor: ShadowRoot,
get innerHTML() {
return getInnerHTML(this);
},
set innerHTML(value) {
setInnerHTML(this, value);
this.invalidateShadowRenderer();
},
get olderShadowRoot() {
return nextOlderShadowTreeTable.get(this) || null;
},
get host() {
return shadowHostTable.get(this) || null;
},
invalidateShadowRenderer: function() {
return shadowHostTable.get(this).invalidateShadowRenderer();
},
elementFromPoint: function(x, y) {
return elementFromPoint(this, this.ownerDocument, x, y);
},
getSelection: function() {
return document.getSelection();
},
get activeElement() {
var unwrappedActiveElement = unwrap(this).ownerDocument.activeElement;
if (!unwrappedActiveElement || !unwrappedActiveElement.nodeType) return null;
var activeElement = wrap(unwrappedActiveElement);
// Loop while activeElement is not a shallow child of this ShadowRoot.
while (!this.contains(activeElement)) {
// Iterate until we hit activeElement's containing ShadowRoot (which
// isn't this one) or document.
while (activeElement.parentNode) {
activeElement = activeElement.parentNode;
}
// If we've reached a ShadowRoot, move to its host.
if (activeElement.host) {
activeElement = activeElement.host;
// Otherwise, we've reached a document - this ShadowRoot is not an
// ancestor of the active element.
} else {
return null;
}
}
return activeElement;
}
});
scope.wrappers.ShadowRoot = ShadowRoot;
})(window.ShadowDOMPolyfill);

View File

@@ -1,48 +0,0 @@
/**
* @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(scope) {
'use strict';
var CharacterData = scope.wrappers.CharacterData;
var enqueueMutation = scope.enqueueMutation;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
function toUInt32(x) {
return x >>> 0;
}
var OriginalText = window.Text;
function Text(node) {
CharacterData.call(this, node);
}
Text.prototype = Object.create(CharacterData.prototype);
mixin(Text.prototype, {
splitText: function(offset) {
offset = toUInt32(offset);
var s = this.data;
if (offset > s.length)
throw new Error('IndexSizeError');
var head = s.slice(0, offset);
var tail = s.slice(offset);
this.data = head;
var newTextNode = this.ownerDocument.createTextNode(tail);
if (this.parentNode)
this.parentNode.insertBefore(newTextNode, this.nextSibling);
return newTextNode;
}
});
registerWrapper(OriginalText, Text, document.createTextNode(''));
scope.wrappers.Text = Text;
})(window.ShadowDOMPolyfill);

View File

@@ -1,130 +0,0 @@
/**
* @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(scope) {
'use strict';
var UIEvent = scope.wrappers.UIEvent;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var setWrapper = scope.setWrapper;
var unsafeUnwrap = scope.unsafeUnwrap;
var wrap = scope.wrap;
// TouchEvent is WebKit/Blink only.
var OriginalTouchEvent = window.TouchEvent;
if (!OriginalTouchEvent)
return;
var nativeEvent;
try {
nativeEvent = document.createEvent('TouchEvent');
} catch (ex) {
// In Chrome creating a TouchEvent fails if the feature is not turned on
// which it isn't on desktop Chrome.
return;
}
var nonEnumDescriptor = {enumerable: false};
function nonEnum(obj, prop) {
Object.defineProperty(obj, prop, nonEnumDescriptor);
}
function Touch(impl) {
setWrapper(impl, this);
}
Touch.prototype = {
get target() {
return wrap(unsafeUnwrap(this).target);
}
};
var descr = {
configurable: true,
enumerable: true,
get: null
};
[
'clientX',
'clientY',
'screenX',
'screenY',
'pageX',
'pageY',
'identifier',
'webkitRadiusX',
'webkitRadiusY',
'webkitRotationAngle',
'webkitForce'
].forEach(function(name) {
descr.get = function() {
return unsafeUnwrap(this)[name];
};
Object.defineProperty(Touch.prototype, name, descr);
});
function TouchList() {
this.length = 0;
nonEnum(this, 'length');
}
TouchList.prototype = {
item: function(index) {
return this[index];
}
};
function wrapTouchList(nativeTouchList) {
var list = new TouchList();
for (var i = 0; i < nativeTouchList.length; i++) {
list[i] = new Touch(nativeTouchList[i]);
}
list.length = i;
return list;
}
function TouchEvent(impl) {
UIEvent.call(this, impl);
}
TouchEvent.prototype = Object.create(UIEvent.prototype);
mixin(TouchEvent.prototype, {
get touches() {
return wrapTouchList(unsafeUnwrap(this).touches);
},
get targetTouches() {
return wrapTouchList(unsafeUnwrap(this).targetTouches);
},
get changedTouches() {
return wrapTouchList(unsafeUnwrap(this).changedTouches);
},
initTouchEvent: function() {
// The only way to use this is to reuse the TouchList from an existing
// TouchEvent. Since this is WebKit/Blink proprietary API we will not
// implement this until someone screams.
throw new Error('Not implemented');
}
});
registerWrapper(OriginalTouchEvent, TouchEvent, nativeEvent);
scope.wrappers.Touch = Touch;
scope.wrappers.TouchEvent = TouchEvent;
scope.wrappers.TouchList = TouchList;
})(window.ShadowDOMPolyfill);

View File

@@ -1,63 +0,0 @@
/**
* @license
* Copyright (c) 2015 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(scope) {
'use strict';
var registerWrapper = scope.registerWrapper;
var setWrapper = scope.setWrapper;
var unsafeUnwrap = scope.unsafeUnwrap;
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;
var OriginalTreeWalker = window.TreeWalker;
function TreeWalker(impl) {
setWrapper(impl, this);
}
TreeWalker.prototype = {
get root() {
return wrap(unsafeUnwrap(this).root);
},
get currentNode() {
return wrap(unsafeUnwrap(this).currentNode);
},
set currentNode(node) {
unsafeUnwrap(this).currentNode = unwrapIfNeeded(node);
},
get filter() {
return unsafeUnwrap(this).filter;
},
parentNode: function() {
return wrap(unsafeUnwrap(this).parentNode());
},
firstChild: function() {
return wrap(unsafeUnwrap(this).firstChild());
},
lastChild: function() {
return wrap(unsafeUnwrap(this).lastChild());
},
previousSibling: function() {
return wrap(unsafeUnwrap(this).previousSibling());
},
previousNode: function() {
return wrap(unsafeUnwrap(this).previousNode());
},
nextNode: function() {
return wrap(unsafeUnwrap(this).nextNode());
}
};
registerWrapper(OriginalTreeWalker, TreeWalker);
scope.wrappers.TreeWalker = TreeWalker;
})(window.ShadowDOMPolyfill);

View File

@@ -1,68 +0,0 @@
/**
* @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(scope) {
'use strict';
var addForwardingProperties = scope.addForwardingProperties;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var setWrapper = scope.setWrapper;
var unsafeUnwrap = scope.unsafeUnwrap;
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;
var OriginalWebGLRenderingContext = window.WebGLRenderingContext;
// IE10 does not have WebGL.
if (!OriginalWebGLRenderingContext)
return;
function WebGLRenderingContext(impl) {
setWrapper(impl, this);
}
mixin(WebGLRenderingContext.prototype, {
get canvas() {
return wrap(unsafeUnwrap(this).canvas);
},
texImage2D: function() {
arguments[5] = unwrapIfNeeded(arguments[5]);
unsafeUnwrap(this).texImage2D.apply(unsafeUnwrap(this), arguments);
},
texSubImage2D: function() {
arguments[6] = unwrapIfNeeded(arguments[6]);
unsafeUnwrap(this).texSubImage2D.apply(unsafeUnwrap(this), arguments);
}
});
// WebKit has two additional prototypes in the chain for WebGLRenderingContext which are not exposed on `window`: WebGLRenderingContextBase and CanvasRenderingContextBase.
// CanvasRenderingContextBase has only one getter `canvas`, which is taken care of already, so we skip it.
var OriginalWebGLRenderingContextBase = Object.getPrototypeOf(OriginalWebGLRenderingContext.prototype);
if (OriginalWebGLRenderingContextBase !== Object.prototype) {
addForwardingProperties(OriginalWebGLRenderingContextBase, WebGLRenderingContext.prototype);
}
// Blink/WebKit has broken DOM bindings. Usually we would create an instance
// of the object and pass it into registerWrapper as a "blueprint" but
// creating WebGL contexts is expensive and might fail so we use a dummy
// object with dummy instance properties for these broken browsers.
var instanceProperties = /WebKit/.test(navigator.userAgent) ?
{drawingBufferHeight: null, drawingBufferWidth: null} : {};
registerWrapper(OriginalWebGLRenderingContext, WebGLRenderingContext,
instanceProperties);
scope.wrappers.WebGLRenderingContext = WebGLRenderingContext;
})(window.ShadowDOMPolyfill);

View File

@@ -1,94 +0,0 @@
/**
* @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(scope) {
'use strict';
var EventTarget = scope.wrappers.EventTarget;
var Selection = scope.wrappers.Selection;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var renderAllPending = scope.renderAllPending;
var unwrap = scope.unwrap;
var unwrapIfNeeded = scope.unwrapIfNeeded;
var wrap = scope.wrap;
var OriginalWindow = window.Window;
var originalGetComputedStyle = window.getComputedStyle;
var originalGetDefaultComputedStyle = window.getDefaultComputedStyle;
var originalGetSelection = window.getSelection;
function Window(impl) {
EventTarget.call(this, impl);
}
Window.prototype = Object.create(EventTarget.prototype);
OriginalWindow.prototype.getComputedStyle = function(el, pseudo) {
return wrap(this || window).getComputedStyle(unwrapIfNeeded(el), pseudo);
};
// Mozilla proprietary extension.
if (originalGetDefaultComputedStyle) {
OriginalWindow.prototype.getDefaultComputedStyle = function(el, pseudo) {
return wrap(this || window).getDefaultComputedStyle(
unwrapIfNeeded(el), pseudo);
};
}
OriginalWindow.prototype.getSelection = function() {
return wrap(this || window).getSelection();
};
// Work around for https://bugzilla.mozilla.org/show_bug.cgi?id=943065
delete window.getComputedStyle;
delete window.getDefaultComputedStyle;
delete window.getSelection;
['addEventListener', 'removeEventListener', 'dispatchEvent'].forEach(
function(name) {
OriginalWindow.prototype[name] = function() {
var w = wrap(this || window);
return w[name].apply(w, arguments);
};
// Work around for https://bugzilla.mozilla.org/show_bug.cgi?id=943065
delete window[name];
});
mixin(Window.prototype, {
getComputedStyle: function(el, pseudo) {
renderAllPending();
return originalGetComputedStyle.call(unwrap(this), unwrapIfNeeded(el),
pseudo);
},
getSelection: function() {
renderAllPending();
return new Selection(originalGetSelection.call(unwrap(this)));
},
get document() {
return wrap(unwrap(this).document);
}
});
// Mozilla proprietary extension.
if (originalGetDefaultComputedStyle) {
Window.prototype.getDefaultComputedStyle = function(el, pseudo) {
renderAllPending();
return originalGetDefaultComputedStyle.call(unwrap(this),
unwrapIfNeeded(el),pseudo);
};
}
registerWrapper(OriginalWindow, Window, window);
scope.wrappers.Window = Window;
})(window.ShadowDOMPolyfill);

View File

@@ -1,23 +0,0 @@
/**
* @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(scope) {
'use strict';
var unwrapIfNeeded = scope.unwrapIfNeeded;
var originalSend = XMLHttpRequest.prototype.send;
// Since we only need to adjust XHR.send, we just patch it instead of wrapping
// the entire object. This happens when FormData is passed.
XMLHttpRequest.prototype.send = function(obj) {
return originalSend.call(this, unwrapIfNeeded(obj));
};
})(window.ShadowDOMPolyfill);

View File

@@ -1,60 +0,0 @@
/**
* @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(scope) {
'use strict';
var HTMLElement = scope.wrappers.HTMLElement;
var assert = scope.assert;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var elementsWithFormProperty = [
'HTMLButtonElement',
'HTMLFieldSetElement',
'HTMLInputElement',
'HTMLKeygenElement',
'HTMLLabelElement',
'HTMLLegendElement',
'HTMLObjectElement',
// HTMLOptionElement is handled in HTMLOptionElement.js
'HTMLOutputElement',
// HTMLSelectElement is handled in HTMLSelectElement.js
'HTMLTextAreaElement',
];
function createWrapperConstructor(name) {
if (!window[name])
return;
// Ensure we are not overriding an already existing constructor.
assert(!scope.wrappers[name]);
var GeneratedWrapper = function(node) {
// At this point all of them extend HTMLElement.
HTMLElement.call(this, node);
}
GeneratedWrapper.prototype = Object.create(HTMLElement.prototype);
mixin(GeneratedWrapper.prototype, {
get form() {
return wrap(unwrap(this).form);
},
});
registerWrapper(window[name], GeneratedWrapper,
document.createElement(name.slice(4, -7)));
scope.wrappers[name] = GeneratedWrapper;
}
elementsWithFormProperty.forEach(createWrapperConstructor);
})(window.ShadowDOMPolyfill);

View File

@@ -1,952 +0,0 @@
/**
* @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(scope) {
'use strict';
var forwardMethodsToWrapper = scope.forwardMethodsToWrapper;
var getTreeScope = scope.getTreeScope;
var mixin = scope.mixin;
var registerWrapper = scope.registerWrapper;
var setWrapper = scope.setWrapper;
var unsafeUnwrap = scope.unsafeUnwrap;
var unwrap = scope.unwrap;
var wrap = scope.wrap;
var wrappers = scope.wrappers;
var wrappedFuns = new WeakMap();
var listenersTable = new WeakMap();
var handledEventsTable = new WeakMap();
var currentlyDispatchingEvents = new WeakMap();
var targetTable = new WeakMap();
var currentTargetTable = new WeakMap();
var relatedTargetTable = new WeakMap();
var eventPhaseTable = new WeakMap();
var stopPropagationTable = new WeakMap();
var stopImmediatePropagationTable = new WeakMap();
var eventHandlersTable = new WeakMap();
var eventPathTable = new WeakMap();
function isShadowRoot(node) {
return node instanceof wrappers.ShadowRoot;
}
function rootOfNode(node) {
return getTreeScope(node).root;
}
// http://w3c.github.io/webcomponents/spec/shadow/#event-paths
function getEventPath(node, event) {
var path = [];
var current = node;
path.push(current);
while (current) {
// 4.1.
var destinationInsertionPoints = getDestinationInsertionPoints(current);
if (destinationInsertionPoints && destinationInsertionPoints.length > 0) {
// 4.1.1
for (var i = 0; i < destinationInsertionPoints.length; i++) {
var insertionPoint = destinationInsertionPoints[i];
// 4.1.1.1
if (isShadowInsertionPoint(insertionPoint)) {
var shadowRoot = rootOfNode(insertionPoint);
// 4.1.1.1.2
var olderShadowRoot = shadowRoot.olderShadowRoot;
if (olderShadowRoot)
path.push(olderShadowRoot);
}
// 4.1.1.2
path.push(insertionPoint);
}
// 4.1.2
current = destinationInsertionPoints[
destinationInsertionPoints.length - 1];
// 4.2
} else {
if (isShadowRoot(current)) {
if (inSameTree(node, current) && eventMustBeStopped(event)) {
// Stop this algorithm
break;
}
current = current.host;
path.push(current);
// 4.2.2
} else {
current = current.parentNode;
if (current)
path.push(current);
}
}
}
return path;
}
// http://w3c.github.io/webcomponents/spec/shadow/#dfn-events-always-stopped
function eventMustBeStopped(event) {
if (!event)
return false;
switch (event.type) {
case 'abort':
case 'error':
case 'select':
case 'change':
case 'load':
case 'reset':
case 'resize':
case 'scroll':
case 'selectstart':
return true;
}
return false;
}
// http://w3c.github.io/webcomponents/spec/shadow/#dfn-shadow-insertion-point
function isShadowInsertionPoint(node) {
return node instanceof HTMLShadowElement;
// and make sure that there are no shadow precing this?
// and that there is no content ancestor?
}
function getDestinationInsertionPoints(node) {
return scope.getDestinationInsertionPoints(node);
}
// http://w3c.github.io/webcomponents/spec/shadow/#event-retargeting
function eventRetargetting(path, currentTarget) {
if (path.length === 0)
return currentTarget;
// The currentTarget might be the window object. Use its document for the
// purpose of finding the retargetted node.
if (currentTarget instanceof wrappers.Window)
currentTarget = currentTarget.document;
var currentTargetTree = getTreeScope(currentTarget);
var originalTarget = path[0];
var originalTargetTree = getTreeScope(originalTarget);
var relativeTargetTree =
lowestCommonInclusiveAncestor(currentTargetTree, originalTargetTree);
for (var i = 0; i < path.length; i++) {
var node = path[i];
if (getTreeScope(node) === relativeTargetTree)
return node;
}
return path[path.length - 1];
}
function getTreeScopeAncestors(treeScope) {
var ancestors = [];
for (;treeScope; treeScope = treeScope.parent) {
ancestors.push(treeScope);
}
return ancestors;
}
function lowestCommonInclusiveAncestor(tsA, tsB) {
var ancestorsA = getTreeScopeAncestors(tsA);
var ancestorsB = getTreeScopeAncestors(tsB);
var result = null;
while (ancestorsA.length > 0 && ancestorsB.length > 0) {
var a = ancestorsA.pop();
var b = ancestorsB.pop();
if (a === b)
result = a;
else
break;
}
return result;
}
function getTreeScopeRoot(ts) {
if (!ts.parent)
return ts;
return getTreeScopeRoot(ts.parent);
}
function relatedTargetResolution(event, currentTarget, relatedTarget) {
// In case the current target is a window use its document for the purpose
// of retargetting the related target.
if (currentTarget instanceof wrappers.Window)
currentTarget = currentTarget.document;
var currentTargetTree = getTreeScope(currentTarget);
var relatedTargetTree = getTreeScope(relatedTarget);
var relatedTargetEventPath = getEventPath(relatedTarget, event);
var lowestCommonAncestorTree;
// 4
var lowestCommonAncestorTree =
lowestCommonInclusiveAncestor(currentTargetTree, relatedTargetTree);
// 5
if (!lowestCommonAncestorTree)
lowestCommonAncestorTree = relatedTargetTree.root;
// 6
for (var commonAncestorTree = lowestCommonAncestorTree;
commonAncestorTree;
commonAncestorTree = commonAncestorTree.parent) {
// 6.1
var adjustedRelatedTarget;
for (var i = 0; i < relatedTargetEventPath.length; i++) {
var node = relatedTargetEventPath[i];
if (getTreeScope(node) === commonAncestorTree)
return node;
}
}
return null;
}
function inSameTree(a, b) {
return getTreeScope(a) === getTreeScope(b);
}
var NONE = 0;
var CAPTURING_PHASE = 1;
var AT_TARGET = 2;
var BUBBLING_PHASE = 3;
// pendingError is used to rethrow the first error we got during an event
// dispatch. The browser actually reports all errors but to do that we would
// need to rethrow the error asynchronously.
var pendingError;
function dispatchOriginalEvent(originalEvent) {
// Make sure this event is only dispatched once.
if (handledEventsTable.get(originalEvent))
return;
handledEventsTable.set(originalEvent, true);
dispatchEvent(wrap(originalEvent), wrap(originalEvent.target));
if (pendingError) {
var err = pendingError;
pendingError = null;
throw err;
}
}
function isLoadLikeEvent(event) {
switch (event.type) {
// http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#events-and-the-window-object
case 'load':
// http://www.whatwg.org/specs/web-apps/current-work/multipage/browsers.html#unloading-documents
case 'beforeunload':
case 'unload':
return true;
}
return false;
}
function dispatchEvent(event, originalWrapperTarget) {
if (currentlyDispatchingEvents.get(event))
throw new Error('InvalidStateError');
currentlyDispatchingEvents.set(event, true);
// Render to ensure that the event path is correct.
scope.renderAllPending();
var eventPath;
// http://www.whatwg.org/specs/web-apps/current-work/multipage/webappapis.html#events-and-the-window-object
// All events dispatched on Nodes with a default view, except load events,
// should propagate to the Window.
// http://www.whatwg.org/specs/web-apps/current-work/multipage/the-end.html#the-end
var overrideTarget;
var win;
// Should really be not cancelable too but since Firefox has a bug there
// we skip that check.
// https://bugzilla.mozilla.org/show_bug.cgi?id=999456
if (isLoadLikeEvent(event) && !event.bubbles) {
var doc = originalWrapperTarget;
if (doc instanceof wrappers.Document && (win = doc.defaultView)) {
overrideTarget = doc;
eventPath = [];
}
}
if (!eventPath) {
if (originalWrapperTarget instanceof wrappers.Window) {
win = originalWrapperTarget;
eventPath = [];
} else {
eventPath = getEventPath(originalWrapperTarget, event);
if (!isLoadLikeEvent(event)) {
var doc = eventPath[eventPath.length - 1];
if (doc instanceof wrappers.Document)
win = doc.defaultView;
}
}
}
eventPathTable.set(event, eventPath);
if (dispatchCapturing(event, eventPath, win, overrideTarget)) {
if (dispatchAtTarget(event, eventPath, win, overrideTarget)) {
dispatchBubbling(event, eventPath, win, overrideTarget);
}
}
eventPhaseTable.set(event, NONE);
currentTargetTable.delete(event, null);
currentlyDispatchingEvents.delete(event);
return event.defaultPrevented;
}
function dispatchCapturing(event, eventPath, win, overrideTarget) {
var phase = CAPTURING_PHASE;
if (win) {
if (!invoke(win, event, phase, eventPath, overrideTarget))
return false;
}
for (var i = eventPath.length - 1; i > 0; i--) {
if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget))
return false;
}
return true;
}
function dispatchAtTarget(event, eventPath, win, overrideTarget) {
var phase = AT_TARGET;
var currentTarget = eventPath[0] || win;
return invoke(currentTarget, event, phase, eventPath, overrideTarget);
}
function dispatchBubbling(event, eventPath, win, overrideTarget) {
var phase = BUBBLING_PHASE;
for (var i = 1; i < eventPath.length; i++) {
if (!invoke(eventPath[i], event, phase, eventPath, overrideTarget))
return;
}
if (win && eventPath.length > 0) {
invoke(win, event, phase, eventPath, overrideTarget);
}
}
function invoke(currentTarget, event, phase, eventPath, overrideTarget) {
var listeners = listenersTable.get(currentTarget);
if (!listeners)
return true;
var target = overrideTarget || eventRetargetting(eventPath, currentTarget);
if (target === currentTarget) {
if (phase === CAPTURING_PHASE)
return true;
if (phase === BUBBLING_PHASE)
phase = AT_TARGET;
} else if (phase === BUBBLING_PHASE && !event.bubbles) {
return true;
}
if ('relatedTarget' in event) {
var originalEvent = unwrap(event);
var unwrappedRelatedTarget = originalEvent.relatedTarget;
// X-Tag sets relatedTarget on a CustomEvent. If they do that there is no
// way to have relatedTarget return the adjusted target but worse is that
// the originalEvent might not have a relatedTarget so we hit an assert
// when we try to wrap it.
if (unwrappedRelatedTarget) {
// In IE we can get objects that are not EventTargets at this point.
// Safari does not have an EventTarget interface so revert to checking
// for addEventListener as an approximation.
if (unwrappedRelatedTarget instanceof Object &&
unwrappedRelatedTarget.addEventListener) {
var relatedTarget = wrap(unwrappedRelatedTarget);
var adjusted =
relatedTargetResolution(event, currentTarget, relatedTarget);
if (adjusted === target)
return true;
} else {
adjusted = null;
}
relatedTargetTable.set(event, adjusted);
}
}
eventPhaseTable.set(event, phase);
var type = event.type;
var anyRemoved = false;
targetTable.set(event, target);
currentTargetTable.set(event, currentTarget);
// Keep track of the invoke depth so that we only clean up the removed
// listeners if we are in the outermost invoke.
listeners.depth++;
for (var i = 0, len = listeners.length; i < len; i++) {
var listener = listeners[i];
if (listener.removed) {
anyRemoved = true;
continue;
}
if (listener.type !== type ||
!listener.capture && phase === CAPTURING_PHASE ||
listener.capture && phase === BUBBLING_PHASE) {
continue;
}
try {
if (typeof listener.handler === 'function')
listener.handler.call(currentTarget, event);
else
listener.handler.handleEvent(event);
if (stopImmediatePropagationTable.get(event))
return false;
} catch (ex) {
if (!pendingError)
pendingError = ex;
}
}
listeners.depth--;
if (anyRemoved && listeners.depth === 0) {
var copy = listeners.slice();
listeners.length = 0;
for (var i = 0; i < copy.length; i++) {
if (!copy[i].removed)
listeners.push(copy[i]);
}
}
return !stopPropagationTable.get(event);
}
function Listener(type, handler, capture) {
this.type = type;
this.handler = handler;
this.capture = Boolean(capture);
}
Listener.prototype = {
equals: function(that) {
return this.handler === that.handler && this.type === that.type &&
this.capture === that.capture;
},
get removed() {
return this.handler === null;
},
remove: function() {
this.handler = null;
}
};
var OriginalEvent = window.Event;
OriginalEvent.prototype.polymerBlackList_ = {
returnValue: true,
// TODO(arv): keyLocation is part of KeyboardEvent but Firefox does not
// support constructable KeyboardEvent so we keep it here for now.
keyLocation: true
};
/**
* Creates a new Event wrapper or wraps an existin native Event object.
* @param {string|Event} type
* @param {Object=} options
* @constructor
*/
function Event(type, options) {
if (type instanceof OriginalEvent) {
var impl = type;
// In browsers that do not correctly support BeforeUnloadEvent we get to
// the generic Event wrapper but we still want to ensure we create a
// BeforeUnloadEvent. Since BeforeUnloadEvent calls super, we need to
// prevent reentrancty.
if (!OriginalBeforeUnloadEvent && impl.type === 'beforeunload' &&
!(this instanceof BeforeUnloadEvent)) {
return new BeforeUnloadEvent(impl);
}
setWrapper(impl, this);
} else {
return wrap(constructEvent(OriginalEvent, 'Event', type, options));
}
}
Event.prototype = {
get target() {
return targetTable.get(this);
},
get currentTarget() {
return currentTargetTable.get(this);
},
get eventPhase() {
return eventPhaseTable.get(this);
},
get path() {
var eventPath = eventPathTable.get(this);
if (!eventPath)
return [];
// TODO(arv): Event path should contain window.
return eventPath.slice();
},
stopPropagation: function() {
stopPropagationTable.set(this, true);
},
stopImmediatePropagation: function() {
stopPropagationTable.set(this, true);
stopImmediatePropagationTable.set(this, true);
}
};
// defaultPrevented is broken in IE.
// https://connect.microsoft.com/IE/feedback/details/790389/event-defaultprevented-returns-false-after-preventdefault-was-called
var supportsDefaultPrevented = (function() {
var e = document.createEvent('Event');
e.initEvent('test', true, true);
e.preventDefault();
return e.defaultPrevented;
})();
if (!supportsDefaultPrevented) {
Event.prototype.preventDefault = function() {
if (!this.cancelable)
return;
unsafeUnwrap(this).preventDefault();
Object.defineProperty(this, 'defaultPrevented', {
get: function() {
return true;
},
configurable: true
});
};
}
registerWrapper(OriginalEvent, Event, document.createEvent('Event'));
function unwrapOptions(options) {
if (!options || !options.relatedTarget)
return options;
return Object.create(options, {
relatedTarget: {value: unwrap(options.relatedTarget)}
});
}
function registerGenericEvent(name, SuperEvent, prototype) {
var OriginalEvent = window[name];
var GenericEvent = function(type, options) {
if (type instanceof OriginalEvent)
setWrapper(type, this);
else
return wrap(constructEvent(OriginalEvent, name, type, options));
};
GenericEvent.prototype = Object.create(SuperEvent.prototype);
if (prototype)
mixin(GenericEvent.prototype, prototype);
if (OriginalEvent) {
// - Old versions of Safari fails on new FocusEvent (and others?).
// - IE does not support event constructors.
// - createEvent('FocusEvent') throws in Firefox.
// => Try the best practice solution first and fallback to the old way
// if needed.
try {
registerWrapper(OriginalEvent, GenericEvent, new OriginalEvent('temp'));
} catch (ex) {
registerWrapper(OriginalEvent, GenericEvent,
document.createEvent(name));
}
}
return GenericEvent;
}
var UIEvent = registerGenericEvent('UIEvent', Event);
var CustomEvent = registerGenericEvent('CustomEvent', Event);
var relatedTargetProto = {
get relatedTarget() {
var relatedTarget = relatedTargetTable.get(this);
// relatedTarget can be null.
if (relatedTarget !== undefined)
return relatedTarget;
return wrap(unwrap(this).relatedTarget);
}
};
function getInitFunction(name, relatedTargetIndex) {
return function() {
arguments[relatedTargetIndex] = unwrap(arguments[relatedTargetIndex]);
var impl = unwrap(this);
impl[name].apply(impl, arguments);
};
}
var mouseEventProto = mixin({
initMouseEvent: getInitFunction('initMouseEvent', 14)
}, relatedTargetProto);
var focusEventProto = mixin({
initFocusEvent: getInitFunction('initFocusEvent', 5)
}, relatedTargetProto);
var MouseEvent = registerGenericEvent('MouseEvent', UIEvent, mouseEventProto);
var FocusEvent = registerGenericEvent('FocusEvent', UIEvent, focusEventProto);
// In case the browser does not support event constructors we polyfill that
// by calling `createEvent('Foo')` and `initFooEvent` where the arguments to
// `initFooEvent` are derived from the registered default event init dict.
var defaultInitDicts = Object.create(null);
var supportsEventConstructors = (function() {
try {
new window.FocusEvent('focus');
} catch (ex) {
return false;
}
return true;
})();
/**
* Constructs a new native event.
*/
function constructEvent(OriginalEvent, name, type, options) {
if (supportsEventConstructors)
return new OriginalEvent(type, unwrapOptions(options));
// Create the arguments from the default dictionary.
var event = unwrap(document.createEvent(name));
var defaultDict = defaultInitDicts[name];
var args = [type];
Object.keys(defaultDict).forEach(function(key) {
var v = options != null && key in options ?
options[key] : defaultDict[key];
if (key === 'relatedTarget')
v = unwrap(v);
args.push(v);
});
event['init' + name].apply(event, args);
return event;
}
if (!supportsEventConstructors) {
var configureEventConstructor = function(name, initDict, superName) {
if (superName) {
var superDict = defaultInitDicts[superName];
initDict = mixin(mixin({}, superDict), initDict);
}
defaultInitDicts[name] = initDict;
};
// The order of the default event init dictionary keys is important, the
// arguments to initFooEvent is derived from that.
configureEventConstructor('Event', {bubbles: false, cancelable: false});
configureEventConstructor('CustomEvent', {detail: null}, 'Event');
configureEventConstructor('UIEvent', {view: null, detail: 0}, 'Event');
configureEventConstructor('MouseEvent', {
screenX: 0,
screenY: 0,
clientX: 0,
clientY: 0,
ctrlKey: false,
altKey: false,
shiftKey: false,
metaKey: false,
button: 0,
relatedTarget: null
}, 'UIEvent');
configureEventConstructor('FocusEvent', {relatedTarget: null}, 'UIEvent');
}
// Safari 7 does not yet have BeforeUnloadEvent.
// https://bugs.webkit.org/show_bug.cgi?id=120849
var OriginalBeforeUnloadEvent = window.BeforeUnloadEvent;
function BeforeUnloadEvent(impl) {
Event.call(this, impl);
}
BeforeUnloadEvent.prototype = Object.create(Event.prototype);
mixin(BeforeUnloadEvent.prototype, {
get returnValue() {
return unsafeUnwrap(this).returnValue;
},
set returnValue(v) {
unsafeUnwrap(this).returnValue = v;
}
});
if (OriginalBeforeUnloadEvent)
registerWrapper(OriginalBeforeUnloadEvent, BeforeUnloadEvent);
function isValidListener(fun) {
if (typeof fun === 'function')
return true;
return fun && fun.handleEvent;
}
function isMutationEvent(type) {
switch (type) {
case 'DOMAttrModified':
case 'DOMAttributeNameChanged':
case 'DOMCharacterDataModified':
case 'DOMElementNameChanged':
case 'DOMNodeInserted':
case 'DOMNodeInsertedIntoDocument':
case 'DOMNodeRemoved':
case 'DOMNodeRemovedFromDocument':
case 'DOMSubtreeModified':
return true;
}
return false;
}
var OriginalEventTarget = window.EventTarget;
/**
* This represents a wrapper for an EventTarget.
* @param {!EventTarget} impl The original event target.
* @constructor
*/
function EventTarget(impl) {
setWrapper(impl, this);
}
// Node and Window have different internal type checks in WebKit so we cannot
// use the same method as the original function.
var methodNames = [
'addEventListener',
'removeEventListener',
'dispatchEvent'
];
[Node, Window].forEach(function(constructor) {
var p = constructor.prototype;
methodNames.forEach(function(name) {
Object.defineProperty(p, name + '_', {value: p[name]});
});
});
function getTargetToListenAt(wrapper) {
if (wrapper instanceof wrappers.ShadowRoot)
wrapper = wrapper.host;
return unwrap(wrapper);
}
EventTarget.prototype = {
addEventListener: function(type, fun, capture) {
if (!isValidListener(fun) || isMutationEvent(type))
return;
var listener = new Listener(type, fun, capture);
var listeners = listenersTable.get(this);
if (!listeners) {
listeners = [];
listeners.depth = 0;
listenersTable.set(this, listeners);
} else {
// Might have a duplicate.
for (var i = 0; i < listeners.length; i++) {
if (listener.equals(listeners[i]))
return;
}
}
listeners.push(listener);
var target = getTargetToListenAt(this);
target.addEventListener_(type, dispatchOriginalEvent, true);
},
removeEventListener: function(type, fun, capture) {
capture = Boolean(capture);
var listeners = listenersTable.get(this);
if (!listeners)
return;
var count = 0, found = false;
for (var i = 0; i < listeners.length; i++) {
if (listeners[i].type === type && listeners[i].capture === capture) {
count++;
if (listeners[i].handler === fun) {
found = true;
listeners[i].remove();
}
}
}
if (found && count === 1) {
var target = getTargetToListenAt(this);
target.removeEventListener_(type, dispatchOriginalEvent, true);
}
},
dispatchEvent: function(event) {
// We want to use the native dispatchEvent because it triggers the default
// actions (like checking a checkbox). However, if there are no listeners
// in the composed tree then there are no events that will trigger and
// listeners in the non composed tree that are part of the event path are
// not notified.
//
// If we find out that there are no listeners in the composed tree we add
// a temporary listener to the target which makes us get called back even
// in that case.
var nativeEvent = unwrap(event);
var eventType = nativeEvent.type;
// Allow dispatching the same event again. This is safe because if user
// code calls this during an existing dispatch of the same event the
// native dispatchEvent throws (that is required by the spec).
handledEventsTable.set(nativeEvent, false);
// Force rendering since we prefer native dispatch and that works on the
// composed tree.
scope.renderAllPending();
var tempListener;
if (!hasListenerInAncestors(this, eventType)) {
tempListener = function() {};
this.addEventListener(eventType, tempListener, true);
}
try {
return unwrap(this).dispatchEvent_(nativeEvent);
} finally {
if (tempListener)
this.removeEventListener(eventType, tempListener, true);
}
}
};
function hasListener(node, type) {
var listeners = listenersTable.get(node);
if (listeners) {
for (var i = 0; i < listeners.length; i++) {
if (!listeners[i].removed && listeners[i].type === type)
return true;
}
}
return false;
}
function hasListenerInAncestors(target, type) {
for (var node = unwrap(target); node; node = node.parentNode) {
if (hasListener(wrap(node), type))
return true;
}
return false;
}
if (OriginalEventTarget)
registerWrapper(OriginalEventTarget, EventTarget);
function wrapEventTargetMethods(constructors) {
forwardMethodsToWrapper(constructors, methodNames);
}
var originalElementFromPoint = document.elementFromPoint;
function elementFromPoint(self, document, x, y) {
scope.renderAllPending();
var element =
wrap(originalElementFromPoint.call(unsafeUnwrap(document), x, y));
if (!element)
return null;
var path = getEventPath(element, null);
// scope the path to this TreeScope
var idx = path.lastIndexOf(self);
if (idx == -1)
return null;
else
path = path.slice(0, idx);
// TODO(dfreedm): pass idx to eventRetargetting to avoid array copy
return eventRetargetting(path, self);
}
/**
* Returns a function that is to be used as a getter for `onfoo` properties.
* @param {string} name
* @return {Function}
*/
function getEventHandlerGetter(name) {
return function() {
var inlineEventHandlers = eventHandlersTable.get(this);
return inlineEventHandlers && inlineEventHandlers[name] &&
inlineEventHandlers[name].value || null;
};
}
/**
* Returns a function that is to be used as a setter for `onfoo` properties.
* @param {string} name
* @return {Function}
*/
function getEventHandlerSetter(name) {
var eventType = name.slice(2);
return function(value) {
var inlineEventHandlers = eventHandlersTable.get(this);
if (!inlineEventHandlers) {
inlineEventHandlers = Object.create(null);
eventHandlersTable.set(this, inlineEventHandlers);
}
var old = inlineEventHandlers[name];
if (old)
this.removeEventListener(eventType, old.wrapped, false);
if (typeof value === 'function') {
var wrapped = function(e) {
var rv = value.call(this, e);
if (rv === false)
e.preventDefault();
else if (name === 'onbeforeunload' && typeof rv === 'string')
e.returnValue = rv;
// mouseover uses true for preventDefault but preventDefault for
// mouseover is ignored by browsers these day.
};
this.addEventListener(eventType, wrapped, false);
inlineEventHandlers[name] = {
value: value,
wrapped: wrapped
};
}
};
}
scope.elementFromPoint = elementFromPoint;
scope.getEventHandlerGetter = getEventHandlerGetter;
scope.getEventHandlerSetter = getEventHandlerSetter;
scope.wrapEventTargetMethods = wrapEventTargetMethods;
scope.wrappers.BeforeUnloadEvent = BeforeUnloadEvent;
scope.wrappers.CustomEvent = CustomEvent;
scope.wrappers.Event = Event;
scope.wrappers.EventTarget = EventTarget;
scope.wrappers.FocusEvent = FocusEvent;
scope.wrappers.MouseEvent = MouseEvent;
scope.wrappers.UIEvent = UIEvent;
})(window.ShadowDOMPolyfill);

View File

@@ -1,41 +0,0 @@
/**
* @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(scope) {
'use strict';
var Node = scope.wrappers.Node;
var GetElementsByInterface = scope.GetElementsByInterface;
var NonElementParentNodeInterface = scope.NonElementParentNodeInterface;
var ParentNodeInterface = scope.ParentNodeInterface;
var SelectorsInterface = scope.SelectorsInterface;
var mixin = scope.mixin;
var registerObject = scope.registerObject;
var registerWrapper = scope.registerWrapper;
var OriginalDocumentFragment = window.DocumentFragment;
function DocumentFragment(node) {
Node.call(this, node);
}
DocumentFragment.prototype = Object.create(Node.prototype);
mixin(DocumentFragment.prototype, ParentNodeInterface);
mixin(DocumentFragment.prototype, SelectorsInterface);
mixin(DocumentFragment.prototype, GetElementsByInterface);
mixin(DocumentFragment.prototype, NonElementParentNodeInterface);
registerWrapper(OriginalDocumentFragment, DocumentFragment, document.createDocumentFragment());
scope.wrappers.DocumentFragment = DocumentFragment;
var Comment = registerObject(document.createComment(''));
scope.wrappers.Comment = Comment;
})(window.ShadowDOMPolyfill);

View File

@@ -1,90 +0,0 @@
/**
* @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(scope) {
'use strict';
var NodeList = scope.wrappers.NodeList;
function forwardElement(node) {
while (node && node.nodeType !== Node.ELEMENT_NODE) {
node = node.nextSibling;
}
return node;
}
function backwardsElement(node) {
while (node && node.nodeType !== Node.ELEMENT_NODE) {
node = node.previousSibling;
}
return node;
}
var ParentNodeInterface = {
get firstElementChild() {
return forwardElement(this.firstChild);
},
get lastElementChild() {
return backwardsElement(this.lastChild);
},
get childElementCount() {
var count = 0;
for (var child = this.firstElementChild;
child;
child = child.nextElementSibling) {
count++;
}
return count;
},
get children() {
var wrapperList = new NodeList();
var i = 0;
for (var child = this.firstElementChild;
child;
child = child.nextElementSibling) {
wrapperList[i++] = child;
}
wrapperList.length = i;
return wrapperList;
},
remove: function() {
var p = this.parentNode;
if (p)
p.removeChild(this);
}
};
var ChildNodeInterface = {
get nextElementSibling() {
return forwardElement(this.nextSibling);
},
get previousElementSibling() {
return backwardsElement(this.previousSibling);
}
};
var NonElementParentNodeInterface = {
getElementById: function(id) {
if (/[ \t\n\r\f]/.test(id))
return null;
return this.querySelector('[id="' + id + '"]');
}
};
scope.ChildNodeInterface = ChildNodeInterface;
scope.NonElementParentNodeInterface = NonElementParentNodeInterface;
scope.ParentNodeInterface = ParentNodeInterface;
})(window.ShadowDOMPolyfill);

View File

@@ -1,114 +0,0 @@
/**
* @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(scope) {
'use strict';
var isWrapperFor = scope.isWrapperFor;
// This is a list of the elements we currently override the global constructor
// for.
var elements = {
'a': 'HTMLAnchorElement',
// Do not create an applet element by default since it shows a warning in
// IE.
// https://github.com/Polymer/polymer/issues/217
// 'applet': 'HTMLAppletElement',
'area': 'HTMLAreaElement',
'audio': 'HTMLAudioElement',
'base': 'HTMLBaseElement',
'body': 'HTMLBodyElement',
'br': 'HTMLBRElement',
'button': 'HTMLButtonElement',
'canvas': 'HTMLCanvasElement',
'caption': 'HTMLTableCaptionElement',
'col': 'HTMLTableColElement',
// 'command': 'HTMLCommandElement', // Not fully implemented in Gecko.
'content': 'HTMLContentElement',
'data': 'HTMLDataElement',
'datalist': 'HTMLDataListElement',
'del': 'HTMLModElement',
'dir': 'HTMLDirectoryElement',
'div': 'HTMLDivElement',
'dl': 'HTMLDListElement',
'embed': 'HTMLEmbedElement',
'fieldset': 'HTMLFieldSetElement',
'font': 'HTMLFontElement',
'form': 'HTMLFormElement',
'frame': 'HTMLFrameElement',
'frameset': 'HTMLFrameSetElement',
'h1': 'HTMLHeadingElement',
'head': 'HTMLHeadElement',
'hr': 'HTMLHRElement',
'html': 'HTMLHtmlElement',
'iframe': 'HTMLIFrameElement',
'img': 'HTMLImageElement',
'input': 'HTMLInputElement',
'keygen': 'HTMLKeygenElement',
'label': 'HTMLLabelElement',
'legend': 'HTMLLegendElement',
'li': 'HTMLLIElement',
'link': 'HTMLLinkElement',
'map': 'HTMLMapElement',
'marquee': 'HTMLMarqueeElement',
'menu': 'HTMLMenuElement',
'menuitem': 'HTMLMenuItemElement',
'meta': 'HTMLMetaElement',
'meter': 'HTMLMeterElement',
'object': 'HTMLObjectElement',
'ol': 'HTMLOListElement',
'optgroup': 'HTMLOptGroupElement',
'option': 'HTMLOptionElement',
'output': 'HTMLOutputElement',
'p': 'HTMLParagraphElement',
'param': 'HTMLParamElement',
'pre': 'HTMLPreElement',
'progress': 'HTMLProgressElement',
'q': 'HTMLQuoteElement',
'script': 'HTMLScriptElement',
'select': 'HTMLSelectElement',
'shadow': 'HTMLShadowElement',
'source': 'HTMLSourceElement',
'span': 'HTMLSpanElement',
'style': 'HTMLStyleElement',
'table': 'HTMLTableElement',
'tbody': 'HTMLTableSectionElement',
// WebKit and Moz are wrong:
// https://bugs.webkit.org/show_bug.cgi?id=111469
// https://bugzilla.mozilla.org/show_bug.cgi?id=848096
// 'td': 'HTMLTableCellElement',
'template': 'HTMLTemplateElement',
'textarea': 'HTMLTextAreaElement',
'thead': 'HTMLTableSectionElement',
'time': 'HTMLTimeElement',
'title': 'HTMLTitleElement',
'tr': 'HTMLTableRowElement',
'track': 'HTMLTrackElement',
'ul': 'HTMLUListElement',
'video': 'HTMLVideoElement',
};
function overrideConstructor(tagName) {
var nativeConstructorName = elements[tagName];
var nativeConstructor = window[nativeConstructorName];
if (!nativeConstructor)
return;
var element = document.createElement(tagName);
var wrapperConstructor = element.constructor;
window[nativeConstructorName] = wrapperConstructor;
}
Object.keys(elements).forEach(overrideConstructor);
Object.getOwnPropertyNames(scope.wrappers).forEach(function(name) {
window[name] = scope.wrappers[name]
});
})(window.ShadowDOMPolyfill);

View File

@@ -1,253 +0,0 @@
/**
* @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
*/
// minimal template polyfill
(function() {
var needsTemplate = (typeof HTMLTemplateElement === 'undefined');
// NOTE: Patch document.importNode to work around IE11 bug that
// casues children of a document fragment imported while
// there is a mutation observer to not have a parentNode (!?!)
// This needs to happen *after* patching importNode to fix template cloning
if (/Trident/.test(navigator.userAgent)) {
(function() {
var importNode = document.importNode;
document.importNode = function() {
var n = importNode.apply(document, arguments);
// Copy all children to a new document fragment since
// this one may be broken
if (n.nodeType === Node.DOCUMENT_FRAGMENT_NODE) {
var f = document.createDocumentFragment();
f.appendChild(n);
return f;
} else {
return n;
}
};
})();
}
// returns true if nested templates cannot be cloned (they cannot be on
// some impl's like Safari 8)
var needsCloning = (function() {
if (!needsTemplate) {
var t = document.createElement('template');
var t2 = document.createElement('template');
t2.content.appendChild(document.createElement('div'));
t.content.appendChild(t2);
var clone = t.cloneNode(true);
return (clone.content.childNodes.length === 0 || clone.content.firstChild.content.childNodes.length === 0);
}
})();
var TEMPLATE_TAG = 'template';
var TemplateImpl = function() {};
if (needsTemplate) {
var contentDoc = document.implementation.createHTMLDocument('template');
var canDecorate = true;
var templateStyle = document.createElement('style');
templateStyle.textContent = TEMPLATE_TAG + '{display:none;}';
var head = document.head;
head.insertBefore(templateStyle, head.firstElementChild);
/**
Provides a minimal shim for the <template> element.
*/
TemplateImpl.prototype = Object.create(HTMLElement.prototype);
/**
The `decorate` method moves element children to the template's `content`.
NOTE: there is no support for dynamically adding elements to templates.
*/
TemplateImpl.decorate = function(template) {
// if the template is decorated, return fast
if (template.content) {
return;
}
template.content = contentDoc.createDocumentFragment();
var child;
while (child = template.firstChild) {
template.content.appendChild(child);
}
template.cloneNode = function(deep) {
return TemplateImpl.cloneNode(this, deep);
};
// add innerHTML to template, if possible
// Note: this throws on Safari 7
if (canDecorate) {
try {
Object.defineProperty(template, 'innerHTML', {
get: function() {
var o = '';
for (var e = this.content.firstChild; e; e = e.nextSibling) {
o += e.outerHTML || escapeData(e.data);
}
return o;
},
set: function(text) {
contentDoc.body.innerHTML = text;
TemplateImpl.bootstrap(contentDoc);
while (this.content.firstChild) {
this.content.removeChild(this.content.firstChild);
}
while (contentDoc.body.firstChild) {
this.content.appendChild(contentDoc.body.firstChild);
}
},
configurable: true
});
} catch (err) {
canDecorate = false;
}
}
// bootstrap recursively
TemplateImpl.bootstrap(template.content);
};
/**
The `bootstrap` method is called automatically and "fixes" all
<template> elements in the document referenced by the `doc` argument.
*/
TemplateImpl.bootstrap = function(doc) {
var templates = doc.querySelectorAll(TEMPLATE_TAG);
for (var i=0, l=templates.length, t; (i<l) && (t=templates[i]); i++) {
TemplateImpl.decorate(t);
}
};
// auto-bootstrapping for main document
document.addEventListener('DOMContentLoaded', function() {
TemplateImpl.bootstrap(document);
});
// Patch document.createElement to ensure newly created templates have content
var createElement = document.createElement;
document.createElement = function() {
'use strict';
var el = createElement.apply(document, arguments);
if (el.localName === 'template') {
TemplateImpl.decorate(el);
}
return el;
};
var escapeDataRegExp = /[&\u00A0<>]/g;
function escapeReplace(c) {
switch (c) {
case '&':
return '&amp;';
case '<':
return '&lt;';
case '>':
return '&gt;';
case '\u00A0':
return '&nbsp;';
}
}
function escapeData(s) {
return s.replace(escapeDataRegExp, escapeReplace);
}
}
// make cloning/importing work!
if (needsTemplate || needsCloning) {
// NOTE: we rely on this cloneNode not causing element upgrade.
// This means this polyfill must load before the CE polyfill and
// this would need to be re-worked if a browser supports native CE
// but not <template>.
var nativeCloneNode = Node.prototype.cloneNode;
TemplateImpl.cloneNode = function(template, deep) {
var clone = nativeCloneNode.call(template, false);
// NOTE: decorate doesn't auto-fix children because they are already
// decorated so they need special clone fixup.
if (this.decorate) {
this.decorate(clone);
}
if (deep) {
// NOTE: use native clone node to make sure CE's wrapped
// cloneNode does not cause elements to upgrade.
clone.content.appendChild(
nativeCloneNode.call(template.content, true));
// now ensure nested templates are cloned correctly.
this.fixClonedDom(clone.content, template.content);
}
return clone;
};
// Given a source and cloned subtree, find <template>'s in the cloned
// subtree and replace them with cloned <template>'s from source.
// We must do this because only the source templates have proper .content.
TemplateImpl.fixClonedDom = function(clone, source) {
// do nothing if cloned node is not an element
if (!source.querySelectorAll) return;
// these two lists should be coincident
var s$ = source.querySelectorAll(TEMPLATE_TAG);
var t$ = clone.querySelectorAll(TEMPLATE_TAG);
for (var i=0, l=t$.length, t, s; i<l; i++) {
s = s$[i];
t = t$[i];
if (this.decorate) {
this.decorate(s);
}
t.parentNode.replaceChild(s.cloneNode(true), t);
}
};
var originalImportNode = document.importNode;
// override all cloning to fix the cloned subtree to contain properly
// cloned templates.
Node.prototype.cloneNode = function(deep) {
var dom = nativeCloneNode.call(this, deep);
// template.content is cloned iff `deep`.
if (deep) {
TemplateImpl.fixClonedDom(dom, this);
}
return dom;
};
// NOTE: we are cloning instead of importing <template>'s.
// However, the ownerDocument of the cloned template will be correct!
// This is because the native import node creates the right document owned
// subtree and `fixClonedDom` inserts cloned templates into this subtree,
// thus updating the owner doc.
document.importNode = function(element, deep) {
if (element.localName === TEMPLATE_TAG) {
return TemplateImpl.cloneNode(element, deep);
} else {
var dom = originalImportNode.call(document, element, deep);
if (deep) {
TemplateImpl.fixClonedDom(dom, element);
}
return dom;
}
};
if (needsCloning) {
HTMLTemplateElement.prototype.cloneNode = function(deep) {
return TemplateImpl.cloneNode(this, deep);
};
}
}
if (needsTemplate) {
window.HTMLTemplateElement = TemplateImpl;
}
})();

View File

@@ -1,616 +0,0 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
(function(scope) {
'use strict';
// feature detect for URL constructor
var hasWorkingUrl = false;
if (!scope.forceJURL) {
try {
var u = new URL('b', 'http://a');
u.pathname = 'c%20d';
hasWorkingUrl = u.href === 'http://a/c%20d';
} catch(e) {}
}
if (hasWorkingUrl)
return;
var relative = Object.create(null);
relative['ftp'] = 21;
relative['file'] = 0;
relative['gopher'] = 70;
relative['http'] = 80;
relative['https'] = 443;
relative['ws'] = 80;
relative['wss'] = 443;
var relativePathDotMapping = Object.create(null);
relativePathDotMapping['%2e'] = '.';
relativePathDotMapping['.%2e'] = '..';
relativePathDotMapping['%2e.'] = '..';
relativePathDotMapping['%2e%2e'] = '..';
function isRelativeScheme(scheme) {
return relative[scheme] !== undefined;
}
function invalid() {
clear.call(this);
this._isInvalid = true;
}
function IDNAToASCII(h) {
if ('' == h) {
invalid.call(this)
}
// XXX
return h.toLowerCase()
}
function percentEscape(c) {
var unicode = c.charCodeAt(0);
if (unicode > 0x20 &&
unicode < 0x7F &&
// " # < > ? `
[0x22, 0x23, 0x3C, 0x3E, 0x3F, 0x60].indexOf(unicode) == -1
) {
return c;
}
return encodeURIComponent(c);
}
function percentEscapeQuery(c) {
// XXX This actually needs to encode c using encoding and then
// convert the bytes one-by-one.
var unicode = c.charCodeAt(0);
if (unicode > 0x20 &&
unicode < 0x7F &&
// " # < > ` (do not escape '?')
[0x22, 0x23, 0x3C, 0x3E, 0x60].indexOf(unicode) == -1
) {
return c;
}
return encodeURIComponent(c);
}
var EOF = undefined,
ALPHA = /[a-zA-Z]/,
ALPHANUMERIC = /[a-zA-Z0-9\+\-\.]/;
function parse(input, stateOverride, base) {
function err(message) {
errors.push(message)
}
var state = stateOverride || 'scheme start',
cursor = 0,
buffer = '',
seenAt = false,
seenBracket = false,
errors = [];
loop: while ((input[cursor - 1] != EOF || cursor == 0) && !this._isInvalid) {
var c = input[cursor];
switch (state) {
case 'scheme start':
if (c && ALPHA.test(c)) {
buffer += c.toLowerCase(); // ASCII-safe
state = 'scheme';
} else if (!stateOverride) {
buffer = '';
state = 'no scheme';
continue;
} else {
err('Invalid scheme.');
break loop;
}
break;
case 'scheme':
if (c && ALPHANUMERIC.test(c)) {
buffer += c.toLowerCase(); // ASCII-safe
} else if (':' == c) {
this._scheme = buffer;
buffer = '';
if (stateOverride) {
break loop;
}
if (isRelativeScheme(this._scheme)) {
this._isRelative = true;
}
if ('file' == this._scheme) {
state = 'relative';
} else if (this._isRelative && base && base._scheme == this._scheme) {
state = 'relative or authority';
} else if (this._isRelative) {
state = 'authority first slash';
} else {
state = 'scheme data';
}
} else if (!stateOverride) {
buffer = '';
cursor = 0;
state = 'no scheme';
continue;
} else if (EOF == c) {
break loop;
} else {
err('Code point not allowed in scheme: ' + c)
break loop;
}
break;
case 'scheme data':
if ('?' == c) {
this._query = '?';
state = 'query';
} else if ('#' == c) {
this._fragment = '#';
state = 'fragment';
} else {
// XXX error handling
if (EOF != c && '\t' != c && '\n' != c && '\r' != c) {
this._schemeData += percentEscape(c);
}
}
break;
case 'no scheme':
if (!base || !(isRelativeScheme(base._scheme))) {
err('Missing scheme.');
invalid.call(this);
} else {
state = 'relative';
continue;
}
break;
case 'relative or authority':
if ('/' == c && '/' == input[cursor+1]) {
state = 'authority ignore slashes';
} else {
err('Expected /, got: ' + c);
state = 'relative';
continue
}
break;
case 'relative':
this._isRelative = true;
if ('file' != this._scheme)
this._scheme = base._scheme;
if (EOF == c) {
this._host = base._host;
this._port = base._port;
this._path = base._path.slice();
this._query = base._query;
this._username = base._username;
this._password = base._password;
break loop;
} else if ('/' == c || '\\' == c) {
if ('\\' == c)
err('\\ is an invalid code point.');
state = 'relative slash';
} else if ('?' == c) {
this._host = base._host;
this._port = base._port;
this._path = base._path.slice();
this._query = '?';
this._username = base._username;
this._password = base._password;
state = 'query';
} else if ('#' == c) {
this._host = base._host;
this._port = base._port;
this._path = base._path.slice();
this._query = base._query;
this._fragment = '#';
this._username = base._username;
this._password = base._password;
state = 'fragment';
} else {
var nextC = input[cursor+1]
var nextNextC = input[cursor+2]
if (
'file' != this._scheme || !ALPHA.test(c) ||
(nextC != ':' && nextC != '|') ||
(EOF != nextNextC && '/' != nextNextC && '\\' != nextNextC && '?' != nextNextC && '#' != nextNextC)) {
this._host = base._host;
this._port = base._port;
this._username = base._username;
this._password = base._password;
this._path = base._path.slice();
this._path.pop();
}
state = 'relative path';
continue;
}
break;
case 'relative slash':
if ('/' == c || '\\' == c) {
if ('\\' == c) {
err('\\ is an invalid code point.');
}
if ('file' == this._scheme) {
state = 'file host';
} else {
state = 'authority ignore slashes';
}
} else {
if ('file' != this._scheme) {
this._host = base._host;
this._port = base._port;
this._username = base._username;
this._password = base._password;
}
state = 'relative path';
continue;
}
break;
case 'authority first slash':
if ('/' == c) {
state = 'authority second slash';
} else {
err("Expected '/', got: " + c);
state = 'authority ignore slashes';
continue;
}
break;
case 'authority second slash':
state = 'authority ignore slashes';
if ('/' != c) {
err("Expected '/', got: " + c);
continue;
}
break;
case 'authority ignore slashes':
if ('/' != c && '\\' != c) {
state = 'authority';
continue;
} else {
err('Expected authority, got: ' + c);
}
break;
case 'authority':
if ('@' == c) {
if (seenAt) {
err('@ already seen.');
buffer += '%40';
}
seenAt = true;
for (var i = 0; i < buffer.length; i++) {
var cp = buffer[i];
if ('\t' == cp || '\n' == cp || '\r' == cp) {
err('Invalid whitespace in authority.');
continue;
}
// XXX check URL code points
if (':' == cp && null === this._password) {
this._password = '';
continue;
}
var tempC = percentEscape(cp);
(null !== this._password) ? this._password += tempC : this._username += tempC;
}
buffer = '';
} else if (EOF == c || '/' == c || '\\' == c || '?' == c || '#' == c) {
cursor -= buffer.length;
buffer = '';
state = 'host';
continue;
} else {
buffer += c;
}
break;
case 'file host':
if (EOF == c || '/' == c || '\\' == c || '?' == c || '#' == c) {
if (buffer.length == 2 && ALPHA.test(buffer[0]) && (buffer[1] == ':' || buffer[1] == '|')) {
state = 'relative path';
} else if (buffer.length == 0) {
state = 'relative path start';
} else {
this._host = IDNAToASCII.call(this, buffer);
buffer = '';
state = 'relative path start';
}
continue;
} else if ('\t' == c || '\n' == c || '\r' == c) {
err('Invalid whitespace in file host.');
} else {
buffer += c;
}
break;
case 'host':
case 'hostname':
if (':' == c && !seenBracket) {
// XXX host parsing
this._host = IDNAToASCII.call(this, buffer);
buffer = '';
state = 'port';
if ('hostname' == stateOverride) {
break loop;
}
} else if (EOF == c || '/' == c || '\\' == c || '?' == c || '#' == c) {
this._host = IDNAToASCII.call(this, buffer);
buffer = '';
state = 'relative path start';
if (stateOverride) {
break loop;
}
continue;
} else if ('\t' != c && '\n' != c && '\r' != c) {
if ('[' == c) {
seenBracket = true;
} else if (']' == c) {
seenBracket = false;
}
buffer += c;
} else {
err('Invalid code point in host/hostname: ' + c);
}
break;
case 'port':
if (/[0-9]/.test(c)) {
buffer += c;
} else if (EOF == c || '/' == c || '\\' == c || '?' == c || '#' == c || stateOverride) {
if ('' != buffer) {
var temp = parseInt(buffer, 10);
if (temp != relative[this._scheme]) {
this._port = temp + '';
}
buffer = '';
}
if (stateOverride) {
break loop;
}
state = 'relative path start';
continue;
} else if ('\t' == c || '\n' == c || '\r' == c) {
err('Invalid code point in port: ' + c);
} else {
invalid.call(this);
}
break;
case 'relative path start':
if ('\\' == c)
err("'\\' not allowed in path.");
state = 'relative path';
if ('/' != c && '\\' != c) {
continue;
}
break;
case 'relative path':
if (EOF == c || '/' == c || '\\' == c || (!stateOverride && ('?' == c || '#' == c))) {
if ('\\' == c) {
err('\\ not allowed in relative path.');
}
var tmp;
if (tmp = relativePathDotMapping[buffer.toLowerCase()]) {
buffer = tmp;
}
if ('..' == buffer) {
this._path.pop();
if ('/' != c && '\\' != c) {
this._path.push('');
}
} else if ('.' == buffer && '/' != c && '\\' != c) {
this._path.push('');
} else if ('.' != buffer) {
if ('file' == this._scheme && this._path.length == 0 && buffer.length == 2 && ALPHA.test(buffer[0]) && buffer[1] == '|') {
buffer = buffer[0] + ':';
}
this._path.push(buffer);
}
buffer = '';
if ('?' == c) {
this._query = '?';
state = 'query';
} else if ('#' == c) {
this._fragment = '#';
state = 'fragment';
}
} else if ('\t' != c && '\n' != c && '\r' != c) {
buffer += percentEscape(c);
}
break;
case 'query':
if (!stateOverride && '#' == c) {
this._fragment = '#';
state = 'fragment';
} else if (EOF != c && '\t' != c && '\n' != c && '\r' != c) {
this._query += percentEscapeQuery(c);
}
break;
case 'fragment':
if (EOF != c && '\t' != c && '\n' != c && '\r' != c) {
this._fragment += c;
}
break;
}
cursor++;
}
}
function clear() {
this._scheme = '';
this._schemeData = '';
this._username = '';
this._password = null;
this._host = '';
this._port = '';
this._path = [];
this._query = '';
this._fragment = '';
this._isInvalid = false;
this._isRelative = false;
}
// Does not process domain names or IP addresses.
// Does not handle encoding for the query parameter.
function jURL(url, base /* , encoding */) {
if (base !== undefined && !(base instanceof jURL))
base = new jURL(String(base));
this._url = url;
clear.call(this);
var input = url.replace(/^[ \t\r\n\f]+|[ \t\r\n\f]+$/g, '');
// encoding = encoding || 'utf-8'
parse.call(this, input, null, base);
}
jURL.prototype = {
toString: function() {
return this.href;
},
get href() {
if (this._isInvalid)
return this._url;
var authority = '';
if ('' != this._username || null != this._password) {
authority = this._username +
(null != this._password ? ':' + this._password : '') + '@';
}
return this.protocol +
(this._isRelative ? '//' + authority + this.host : '') +
this.pathname + this._query + this._fragment;
},
set href(href) {
clear.call(this);
parse.call(this, href);
},
get protocol() {
return this._scheme + ':';
},
set protocol(protocol) {
if (this._isInvalid)
return;
parse.call(this, protocol + ':', 'scheme start');
},
get host() {
return this._isInvalid ? '' : this._port ?
this._host + ':' + this._port : this._host;
},
set host(host) {
if (this._isInvalid || !this._isRelative)
return;
parse.call(this, host, 'host');
},
get hostname() {
return this._host;
},
set hostname(hostname) {
if (this._isInvalid || !this._isRelative)
return;
parse.call(this, hostname, 'hostname');
},
get port() {
return this._port;
},
set port(port) {
if (this._isInvalid || !this._isRelative)
return;
parse.call(this, port, 'port');
},
get pathname() {
return this._isInvalid ? '' : this._isRelative ?
'/' + this._path.join('/') : this._schemeData;
},
set pathname(pathname) {
if (this._isInvalid || !this._isRelative)
return;
this._path = [];
parse.call(this, pathname, 'relative path start');
},
get search() {
return this._isInvalid || !this._query || '?' == this._query ?
'' : this._query;
},
set search(search) {
if (this._isInvalid || !this._isRelative)
return;
this._query = '?';
if ('?' == search[0])
search = search.slice(1);
parse.call(this, search, 'query');
},
get hash() {
return this._isInvalid || !this._fragment || '#' == this._fragment ?
'' : this._fragment;
},
set hash(hash) {
if (this._isInvalid)
return;
this._fragment = '#';
if ('#' == hash[0])
hash = hash.slice(1);
parse.call(this, hash, 'fragment');
},
get origin() {
var host;
if (this._isInvalid || !this._scheme) {
return '';
}
// javascript: Gecko returns String(""), WebKit/Blink String("null")
// Gecko throws error for "data://"
// data: Gecko returns "", Blink returns "data://", WebKit returns "null"
// Gecko returns String("") for file: mailto:
// WebKit/Blink returns String("SCHEME://") for file: mailto:
switch (this._scheme) {
case 'data':
case 'file':
case 'javascript':
case 'mailto':
return 'null';
}
host = this.host;
if (!host) {
return '';
}
return this._scheme + '://' + host;
}
};
// Copy over the static methods
var OriginalURL = scope.URL;
if (OriginalURL) {
jURL.createObjectURL = function(blob) {
// IE extension allows a second optional options argument.
// http://msdn.microsoft.com/en-us/library/ie/hh772302(v=vs.85).aspx
return OriginalURL.createObjectURL.apply(OriginalURL, arguments);
};
jURL.revokeObjectURL = function(url) {
OriginalURL.revokeObjectURL(url);
};
}
scope.URL = jURL;
})(self);

View File

@@ -1,49 +0,0 @@
/**
* @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
*/
if (typeof WeakMap === 'undefined') {
(function() {
var defineProperty = Object.defineProperty;
var counter = Date.now() % 1e9;
var WeakMap = function() {
this.name = '__st' + (Math.random() * 1e9 >>> 0) + (counter++ + '__');
};
WeakMap.prototype = {
set: function(key, value) {
var entry = key[this.name];
if (entry && entry[0] === key)
entry[1] = value;
else
defineProperty(key, this.name, {value: [key, value], writable: true});
return this;
},
get: function(key) {
var entry;
return (entry = key[this.name]) && entry[0] === key ?
entry[1] : undefined;
},
delete: function(key) {
var entry = key[this.name];
if (!entry || entry[0] !== key) return false;
entry[0] = entry[1] = undefined;
return true;
},
has: function(key) {
var entry = key[this.name];
if (!entry) return false;
return entry[0] === key;
}
};
window.WeakMap = WeakMap;
})();
}

View File

@@ -1,186 +0,0 @@
(function() {
if (!window.Promise) {
function MakePromise (asap) {
function Promise(fn) {
if (typeof this !== 'object' || typeof fn !== 'function') throw new TypeError();
this._state = null;
this._value = null;
this._deferreds = []
doResolve(fn, resolve.bind(this), reject.bind(this));
}
function handle(deferred) {
var me = this;
if (this._state === null) {
this._deferreds.push(deferred);
return
}
asap(function() {
var cb = me._state ? deferred.onFulfilled : deferred.onRejected
if (typeof cb !== 'function') {
(me._state ? deferred.resolve : deferred.reject)(me._value);
return;
}
var ret;
try {
ret = cb(me._value);
}
catch (e) {
deferred.reject(e);
return;
}
deferred.resolve(ret);
})
}
function resolve(newValue) {
try { //Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
if (newValue === this) throw new TypeError();
if (newValue && (typeof newValue === 'object' || typeof newValue === 'function')) {
var then = newValue.then;
if (typeof then === 'function') {
doResolve(then.bind(newValue), resolve.bind(this), reject.bind(this));
return;
}
}
this._state = true;
this._value = newValue;
finale.call(this);
} catch (e) { reject.call(this, e); }
}
function reject(newValue) {
this._state = false;
this._value = newValue;
finale.call(this);
}
function finale() {
for (var i = 0, len = this._deferreds.length; i < len; i++) {
handle.call(this, this._deferreds[i]);
}
this._deferreds = null;
}
/**
* Take a potentially misbehaving resolver function and make sure
* onFulfilled and onRejected are only called once.
*
* Makes no guarantees about asynchrony.
*/
function doResolve(fn, onFulfilled, onRejected) {
var done = false;
try {
fn(function (value) {
if (done) return;
done = true;
onFulfilled(value);
}, function (reason) {
if (done) return;
done = true;
onRejected(reason);
})
} catch (ex) {
if (done) return;
done = true;
onRejected(ex);
}
}
Promise.prototype['catch'] = function (onRejected) {
return this.then(null, onRejected);
};
Promise.prototype.then = function(onFulfilled, onRejected) {
var me = this;
return new Promise(function(resolve, reject) {
handle.call(me, {
onFulfilled: onFulfilled,
onRejected: onRejected,
resolve: resolve,
reject: reject
});
})
};
Promise.resolve = function (value) {
if (value && typeof value === 'object' && value.constructor === Promise) {
return value;
}
return new Promise(function (resolve) {
resolve(value);
});
};
Promise.reject = function (value) {
return new Promise(function (resolve, reject) {
reject(value);
});
};
return Promise;
}
function makeAsync() {
var twiddle = document.createTextNode('');
var content = 0;
return function(callback) {
// To preserve timing with Promise microtasks
// we create a new observer for every callback.
var observer = new MutationObserver(function(mxns) {
observer.disconnect();
callback();
});
observer.observe(twiddle, {characterData: true});
twiddle.textContent = content++;
}
}
window.Promise = MakePromise(makeAsync());
window.Promise.all = function () {
var args = Array.prototype.slice.call(arguments.length === 1 && Array.isArray(arguments[0]) ? arguments[0] : arguments);
return new Promise(function (resolve, reject) {
if (args.length === 0) return resolve([]);
var remaining = args.length;
function res(i, val) {
try {
if (val && (typeof val === 'object' || typeof val === 'function')) {
var then = val.then;
if (typeof then === 'function') {
then.call(val, function (val) { res(i, val) }, reject);
return;
}
}
args[i] = val;
if (--remaining === 0) {
resolve(args);
}
} catch (ex) {
reject(ex);
}
}
for (var i = 0; i < args.length; i++) {
res(i, args[i]);
}
});
};
window.Promise.race = function (values) {
return new Promise(function (resolve, reject) {
for(var i = 0, len = values.length; i < len; i++) {
values[i].then(resolve, reject);
}
});
};
}
})();

View File

@@ -1,16 +0,0 @@
/**
* @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(scope) {
// alias to Platform for bc
window.Platform = scope;
})(window.WebComponents);

View File

@@ -1,15 +0,0 @@
[
"build/boot-lite.js",
"../URL/URL.js",
"../WeakMap/WeakMap.js",
"../MutationObserver/MutationObserver.js",
"../Template/Template.js",
"../HTMLImports/build.json",
"Promise.js",
"../../custom-elements/custom-elements.min.js",
"../../shadydom/shadydom.min.js",
"../../shadycss/shadycss.min.js",
"lang.js",
"dom.js",
"unresolved.js"
]

View File

@@ -1,15 +0,0 @@
[
"build/boot.js",
"build/if-poly.js",
"../ShadowDOM/build.json",
"../ShadowCSS/ShadowCSS.js",
"build/end-if.js",
"shadowdom.js",
"../URL/URL.js",
"../HTMLImports/build.json",
"../CustomElements/build.json",
"lang.js",
"dom.js",
"unresolved.js",
"bc.js"
]

View File

@@ -1,71 +0,0 @@
/**
* @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() {
// Establish scope.
window.WebComponents = window.WebComponents || {flags:{}};
// loading script
var file = 'webcomponents.js';
var script = document.querySelector('script[src*="' + file + '"]');
// Flags. Convert url arguments to flags
var flags = {};
if (!flags.noOpts) {
// from url
location.search.slice(1).split('&').forEach(function(option) {
var parts = option.split('=');
var match;
if (parts[0] && (match = parts[0].match(/wc-(.+)/))) {
flags[match[1]] = parts[1] || true;
}
});
// from script
if (script) {
for (var i=0, a; (a=script.attributes[i]); i++) {
if (a.name !== 'src') {
flags[a.name] = a.value || true;
}
}
}
// log flags
if (flags.log && flags.log.split) {
var parts = flags.log.split(',');
flags.log = {};
parts.forEach(function(f) {
flags.log[f] = true;
});
} else {
flags.log = {};
}
}
// Determine default settings.
// If any of these flags match 'native', then force native ShadowDOM; any
// other truthy value, or failure to detect native
// ShadowDOM, results in polyfill
flags.shadow = (flags.shadow || flags.shadowdom || flags.polyfill);
if (flags.shadow === 'native') {
flags.shadow = false;
} else {
flags.shadow = flags.shadow || !HTMLElement.prototype.createShadowRoot;
}
// forward flags
if (flags.register) {
window.CustomElements = window.CustomElements || {flags: {}};
window.CustomElements.flags.register = flags.register;
}
// exports
WebComponents.flags = flags;
})();

View File

@@ -1 +0,0 @@
} else {

View File

@@ -1 +0,0 @@
}

View File

@@ -1,2 +0,0 @@
// select ShadowDOM impl
if (WebComponents.flags.shadow) {

View File

@@ -1,131 +0,0 @@
/**
* @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(scope) {
'use strict';
// polyfill performance.now
// Note: old Safari has performance, but not now().
if (!(window.performance && window.performance.now)) {
var start = Date.now();
// only at millisecond precision
window.performance = {now: function(){ return Date.now() - start; }};
}
// polyfill for requestAnimationFrame
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = (function() {
var nativeRaf = window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame;
return nativeRaf ?
function(callback) {
return nativeRaf(function() {
callback(performance.now());
});
} :
function( callback ){
return window.setTimeout(callback, 1000 / 60);
};
})();
}
if (!window.cancelAnimationFrame) {
window.cancelAnimationFrame = (function() {
return window.webkitCancelAnimationFrame ||
window.mozCancelAnimationFrame ||
function(id) {
clearTimeout(id);
};
})();
}
// defaultPrevented is broken in IE.
// https://connect.microsoft.com/IE/feedback/details/790389/event-defaultprevented-returns-false-after-preventdefault-was-called
var workingDefaultPrevented = (function() {
var e = document.createEvent('Event');
e.initEvent('foo', true, true);
e.preventDefault();
return e.defaultPrevented;
})();
if (!workingDefaultPrevented) {
var origPreventDefault = Event.prototype.preventDefault;
Event.prototype.preventDefault = function() {
if (!this.cancelable) {
return;
}
origPreventDefault.call(this);
Object.defineProperty(this, 'defaultPrevented', {
get: function() {
return true;
},
configurable: true
});
};
}
var isIE = /Trident/.test(navigator.userAgent);
// CustomEvent constructor shim
if (!window.CustomEvent || isIE && (typeof window.CustomEvent !== 'function')) {
window.CustomEvent = function(inType, params) {
params = params || {};
var e = document.createEvent('CustomEvent');
e.initCustomEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable), params.detail);
return e;
};
window.CustomEvent.prototype = window.Event.prototype;
}
// Event constructor shim
if (!window.Event || isIE && (typeof window.Event !== 'function')) {
var origEvent = window.Event;
window.Event = function(inType, params) {
params = params || {};
var e = document.createEvent('Event');
e.initEvent(inType, Boolean(params.bubbles), Boolean(params.cancelable));
return e;
};
if (origEvent) {
for (var i in origEvent) {
window.Event[i] = origEvent[i];
}
}
window.Event.prototype = origEvent.prototype;
}
if (!window.MouseEvent || isIE && (typeof window.MouseEvent !== 'function')) {
var origMouseEvent = window.MouseEvent;
window.MouseEvent = function(inType, params) {
params = params || {};
var e = document.createEvent('MouseEvent');
e.initMouseEvent(inType,
Boolean(params.bubbles), Boolean(params.cancelable),
params.view || window, params.detail,
params.screenX, params.screenY, params.clientX, params.clientY,
params.ctrlKey, params.altKey, params.shiftKey, params.metaKey,
params.button, params.relatedTarget);
return e;
};
if (origMouseEvent) {
for (var i in origMouseEvent) {
window.MouseEvent[i] = origMouseEvent[i];
}
}
window.MouseEvent.prototype = origMouseEvent.prototype;
}
})(window.WebComponents);

View File

@@ -1,56 +0,0 @@
/**
* @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(scope) {
'use strict';
// Old versions of iOS do not have bind.
if (!Function.prototype.bind) {
Function.prototype.bind = function(scope) {
var self = this;
var args = Array.prototype.slice.call(arguments, 1);
return function() {
var args2 = args.slice();
args2.push.apply(args2, arguments);
return self.apply(scope, args2);
};
};
}
// ES6 stuff
if (!Array.from) {
Array.from = function (object) {
return [].slice.call(object);
};
}
if (!Object.assign) {
var assign = function(target, source) {
var n$ = Object.getOwnPropertyNames(source);
for (var i=0, p; i < n$.length; i++) {
p = n$[i];
target[p] = source[p];
}
}
Object.assign = function(target, sources) {
var args = [].slice.call(arguments, 1);
for (var i=0, s; i < args.length; i++) {
s = args[i];
if (s) {
assign(target, s);
}
}
return target;
}
}
})(window.WebComponents);

View File

@@ -1,30 +0,0 @@
/**
* @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(scope) {
/**
The ShadowDOM polyfill uses a wrapping strategy on dom elements. This is
99% transparent but there are a few nodes (e.g. document) that cannot be
automatically wrapped. Therefore, rarely it's necessary to wrap nodes in
user code. Here we're choosing to make convenient globals `wrap` and
`unwrap` that can be used whether or not the polyfill is in use.
*/
// convenient global
if (window.ShadowDOMPolyfill) {
window.wrap = ShadowDOMPolyfill.wrapIfNeeded;
window.unwrap = ShadowDOMPolyfill.unwrapIfNeeded;
} else {
// so we can call wrap/unwrap without testing for ShadowDOMPolyfill
window.wrap = window.unwrap = function(n) {
return n;
};
}
})(window.WebComponents);

View File

@@ -48,12 +48,6 @@
}
}
// forward flags
if (flags.register) {
window.CustomElements = window.CustomElements || {flags: {}};
window.CustomElements.flags.register = flags.register;
}
// exports
WebComponents.flags = flags;

12
src/build-lite.json Normal file
View File

@@ -0,0 +1,12 @@
[
"boot-lite.js",
"../html-imports/html-imports.min.js",
"../../es6-promise/dist/es6-promise.auto.min.js",
"../../custom-elements/custom-elements.min.js",
"../../shadydom/shadydom.min.js",
"../../shadycss/shadycss.min.js",
"../../webcomponents-platform/webcomponents-platform.js",
"../../URL/url.js",
"../../template/template.js",
"unresolved.js"
]

View File

@@ -12,14 +12,6 @@
'use strict';
window.CustomElements = {
takeRecords: function() {
if (customElements.flush) {
customElements.flush();
}
}
}
HTMLImports.whenReady(function() {
requestAnimationFrame(function() {
window.dispatchEvent(new CustomEvent('WebComponentsReady'));

View File

@@ -1,46 +0,0 @@
<!doctype html>
<!--
@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
-->
<html>
<head>
<title>HTML Imports Test</title>
<script src="../../../src/HTMLImports/HTMLImports.js"></script>
<script src="../../../../web-component-tester/browser.js"></script>
<link rel="import" href="imports/import-1.html">
</head>
<body>
<script>
test('importer', function() {
if (HTMLImports.useNative) {
return;
}
chai.assert.equal(5, Object.keys(HTMLImports.importLoader.cache).length,
'must cache exactly nine resources');
chai.assert.equal(5, Object.keys(HTMLImports.importer.documents).length,
'must cache exactly nine documents');
Object.keys(HTMLImports.importer.documents).forEach(function(key) {
var doc = HTMLImports.importer.documents[key];
if (!doc) {
return;
}
var links = doc.querySelectorAll('link[rel=import]');
Array.prototype.forEach.call(links, function(link) {
var href = link.getAttribute('href');
if (href.indexOf('404') <= 0) {
chai.assert.isDefined(link.import, 'import should have an import property');
}
});
});
});
</script>
</body>
</html>

View File

@@ -1,34 +0,0 @@
<!doctype html>
<!--
@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
-->
<html>
<head>
<title>HTMLImportsLoaded, native</title>
<script>WCT = {waitFor: function(cb){ cb() }}</script>
<script>
var loaded = false;
addEventListener('HTMLImportsLoaded', function(e) {
loaded = true;
});
</script>
<script src="../../../src/HTMLImports/HTMLImports.js"></script>
<script src="../../../../web-component-tester/browser.js"></script>
</head>
<body>
<link rel="import" href="imports/import-1.html">
<script>
test('HTMLImportsLoaded fires with native imports', function() {
if (HTMLImports.useNative) {
assert.isTrue(loaded);
}
});
</script>
</body>
</html>

View File

@@ -1,57 +0,0 @@
<!doctype html>
<!--
@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
-->
<html>
<head>
<title>base load test</title>
<base href="../../html/">
<script>
window.loadEvents = 0;
(function() {
function importLoaded(event) {
window.loadEvents++;
if (event.type === 'load' && event.target.import) {
var s = event.target.import.querySelector('script');
chai.assert.ok(s, 'load event target can be used to find element in import');
}
}
function importError(event) {
window.loadEvents++;
}
window.importLoaded = importLoaded;
window.importError = importError;
})();
</script>
<script src="../../../../web-component-tester/browser.js"></script>
<script src="../../../src/HTMLImports/HTMLImports.js"></script>
<link rel="import" href="imports/load-1.html" onload="importLoaded(event)">
<link rel="import" href="imports/load-2.html" onload="importLoaded(event)">
<link rel="import" id="willError" href="imports/404.html" onerror="importError(event)">
</head>
<body>
<div id="test1" class="red">Test</div>
<div id="test2" class="blue">Test</div>
<div id="test3" class="image"></div>
<script>
test('imports with base tag', function() {
var baseURI = location.protocol + '//' + location.host + location.pathname.replace('base/load-base.html', '');
chai.assert.equal(document.baseURI, baseURI, 'document.baseURI is correctly modified by base element');
//
chai.assert.equal(loadEvents, 3, 'expected # of load events');
var test1 = getComputedStyle(document.querySelector('#test1')).backgroundColor;
chai.assert.equal(test1, 'rgb(255, 0, 0)');
var test2 = getComputedStyle(document.querySelector('#test2')).backgroundColor;
chai.assert.equal(test2, 'rgb(0, 0, 255)');
});
</script>
</body>
</html>

View File

@@ -1,23 +0,0 @@
<!doctype html>
<!--
@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
-->
<html>
<head>
<title>parser Test</title>
<script src="../../../src/HTMLImports/HTMLImports.js"></script>
<script src="../../../../web-component-tester/browser.js"></script>
<meta http-equiv='Content-Security-Policy' content="script-src 'self';">
<link rel="import" href="imports/csp-import-1.html">
</head>
<body>
<script src="csp.js"></script>
</body>
</html>

View File

@@ -1,14 +0,0 @@
/**
* @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
*/
test('imported scripts loaded under CSP', function() {
chai.assert.ok(window.externalScriptParsed1, 'externalScriptParsed1');
chai.assert.ok(window.externalScriptParsed2, 'externalScriptParsed2');
});

View File

@@ -1,31 +0,0 @@
<!doctype html>
<!--
@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
-->
<html>
<head>
<title>_currentScript Test</title>
<script>WCT = {waitFor: function(cb){cb()}};</script>
<script src="../../../src/HTMLImports/HTMLImports.js"></script>
<script src="../../../../web-component-tester/browser.js"></script>
<link rel="import" href="imports/script-1.html">
<script src="imports/current-script.js"></script>
</head>
<body>
<script>
var cs = document._currentScript;
test('currentScript', function() {
chai.assert.equal(cs.parentNode, document.body, '_currentScript set in main document');
addEventListener('HTMLImportsLoaded', function() {
chai.assert.equal(window.remoteCurrentScriptExecuted, 2, 'remote script executed from import and main document');
});
});
</script>
</body>
</html>

View File

@@ -1,31 +0,0 @@
<!doctype html>
<!--
@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
-->
<html>
<head>
<title>CustomEvent detail test</title>
<script src="../../../src/HTMLImports/HTMLImports.js"></script>
<script src="../../../../web-component-tester/browser.js"></script>
</head>
<body>
<script>
test('CustomEvent detail', function(done) {
var eventName = 'some-event';
var eventDetail = 'some-detail';
document.body.addEventListener(eventName, function(evt) {
chai.assert.equal(evt.detail, eventDetail, 'expected CustomEvent detail');
done();
});
var evt = new CustomEvent(eventName, {detail: eventDetail});
document.body.dispatchEvent(evt);
});
</script>
</body>
</html>

View File

@@ -1,34 +0,0 @@
<!doctype html>
<!--
@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
-->
<html>
<head>
<title>HTML dedupe Test</title>
<script src="../../../src/HTMLImports/HTMLImports.js"></script>
<script src="../../../../web-component-tester/browser.js"></script>
<link rel="import" href="imports/dedupe.html">
<script>
var link = document.createElement('link');
link.href = 'imports/dedupe.html';
link.rel = 'import';
link.addEventListener('load', function(e) {
console.log('dynamic link loaded', e.target.href);
})
document.head.appendChild(link);
</script>
</head>
<body>
<script>
test('imports deduped', function() {
chai.assert.equal(dedupe, 1, 'import loaded');
});
</script>
</body>
</html>

Some files were not shown because too many files have changed in this diff Show More