diff --git a/.travis.yml b/.travis.yml index c56b9b6..872d303 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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= diff --git a/README.md b/README.md index d92ed6f..3a9255b 100644 --- a/README.md +++ b/README.md @@ -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, `'); -}); - -// exports -window.HTMLImports.flags = flags; - -})(); diff --git a/src/HTMLImports/Loader.js b/src/HTMLImports/Loader.js deleted file mode 100644 index 959bcaa..0000000 --- a/src/HTMLImports/Loader.js +++ /dev/null @@ -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 -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 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 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.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 - 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; - -}); diff --git a/src/HTMLImports/module.js b/src/HTMLImports/module.js deleted file mode 100644 index 9a9304d..0000000 --- a/src/HTMLImports/module.js +++ /dev/null @@ -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); - diff --git a/src/HTMLImports/parser.js b/src/HTMLImports/parser.js deleted file mode 100644 index a52d9de..0000000 --- a/src/HTMLImports/parser.js +++ /dev/null @@ -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 - - - could become: - - -
- -
- - 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 .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 .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); diff --git a/src/ShadowDOM/ArraySplice.js b/src/ShadowDOM/ArraySplice.js deleted file mode 100644 index f87800a..0000000 --- a/src/ShadowDOM/ArraySplice.js +++ /dev/null @@ -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 - * - * - * - * 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); diff --git a/src/ShadowDOM/MutationObserver.js b/src/ShadowDOM/MutationObserver.js deleted file mode 100644 index ff6c56d..0000000 --- a/src/ShadowDOM/MutationObserver.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/ShadowDOM.js b/src/ShadowDOM/ShadowDOM.js deleted file mode 100644 index 63ff209..0000000 --- a/src/ShadowDOM/ShadowDOM.js +++ /dev/null @@ -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(''); -}); - -})(); diff --git a/src/ShadowDOM/ShadowRenderer.js b/src/ShadowDOM/ShadowRenderer.js deleted file mode 100644 index cd3d22e..0000000 --- a/src/ShadowDOM/ShadowRenderer.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/TreeScope.js b/src/ShadowDOM/TreeScope.js deleted file mode 100644 index 07011a7..0000000 --- a/src/ShadowDOM/TreeScope.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/build.json b/src/ShadowDOM/build.json deleted file mode 100644 index f0e6767..0000000 --- a/src/ShadowDOM/build.json +++ /dev/null @@ -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" -] diff --git a/src/ShadowDOM/microtask.js b/src/ShadowDOM/microtask.js deleted file mode 100644 index 31e7246..0000000 --- a/src/ShadowDOM/microtask.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/querySelector.js b/src/ShadowDOM/querySelector.js deleted file mode 100644 index adf7364..0000000 --- a/src/ShadowDOM/querySelector.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers.js b/src/ShadowDOM/wrappers.js deleted file mode 100644 index e073836..0000000 --- a/src/ShadowDOM/wrappers.js +++ /dev/null @@ -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.} constructors - * @parem {Array.} 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); diff --git a/src/ShadowDOM/wrappers/CanvasRenderingContext2D.js b/src/ShadowDOM/wrappers/CanvasRenderingContext2D.js deleted file mode 100644 index 44ac212..0000000 --- a/src/ShadowDOM/wrappers/CanvasRenderingContext2D.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/CharacterData.js b/src/ShadowDOM/wrappers/CharacterData.js deleted file mode 100644 index 95e1986..0000000 --- a/src/ShadowDOM/wrappers/CharacterData.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/DOMTokenList.js b/src/ShadowDOM/wrappers/DOMTokenList.js deleted file mode 100644 index 5345134..0000000 --- a/src/ShadowDOM/wrappers/DOMTokenList.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/DataTransfer.js b/src/ShadowDOM/wrappers/DataTransfer.js deleted file mode 100644 index 528c14a..0000000 --- a/src/ShadowDOM/wrappers/DataTransfer.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/Document.js b/src/ShadowDOM/wrappers/Document.js deleted file mode 100644 index 4ceffaa..0000000 --- a/src/ShadowDOM/wrappers/Document.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/Element.js b/src/ShadowDOM/wrappers/Element.js deleted file mode 100644 index 0fc646c..0000000 --- a/src/ShadowDOM/wrappers/Element.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/FormData.js b/src/ShadowDOM/wrappers/FormData.js deleted file mode 100644 index 57cb27b..0000000 --- a/src/ShadowDOM/wrappers/FormData.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/HTMLAudioElement.js b/src/ShadowDOM/wrappers/HTMLAudioElement.js deleted file mode 100644 index 71e668a..0000000 --- a/src/ShadowDOM/wrappers/HTMLAudioElement.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/HTMLCanvasElement.js b/src/ShadowDOM/wrappers/HTMLCanvasElement.js deleted file mode 100644 index 71b962d..0000000 --- a/src/ShadowDOM/wrappers/HTMLCanvasElement.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/HTMLCollection.js b/src/ShadowDOM/wrappers/HTMLCollection.js deleted file mode 100644 index 64cd1bb..0000000 --- a/src/ShadowDOM/wrappers/HTMLCollection.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/HTMLContentElement.js b/src/ShadowDOM/wrappers/HTMLContentElement.js deleted file mode 100644 index b2f5f6f..0000000 --- a/src/ShadowDOM/wrappers/HTMLContentElement.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/HTMLElement.js b/src/ShadowDOM/wrappers/HTMLElement.js deleted file mode 100644 index 8c3a64d..0000000 --- a/src/ShadowDOM/wrappers/HTMLElement.js +++ /dev/null @@ -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 '&'; - case '<': - return '<'; - case '>': - return '>'; - case '"': - return '"' - case '\u00A0': - return ' '; - } - } - - 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) + ''; - - case Node.TEXT_NODE: - var data = node.data; - if (parentNode && plaintextParents[parentNode.localName]) - return data; - return escapeData(data); - - case Node.COMMENT_NODE: - return ''; - - 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 = 'test' - // - // 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); diff --git a/src/ShadowDOM/wrappers/HTMLFormElement.js b/src/ShadowDOM/wrappers/HTMLFormElement.js deleted file mode 100644 index 9aa71ce..0000000 --- a/src/ShadowDOM/wrappers/HTMLFormElement.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/HTMLImageElement.js b/src/ShadowDOM/wrappers/HTMLImageElement.js deleted file mode 100644 index 7288f8b..0000000 --- a/src/ShadowDOM/wrappers/HTMLImageElement.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/HTMLMediaElement.js b/src/ShadowDOM/wrappers/HTMLMediaElement.js deleted file mode 100644 index 006fe47..0000000 --- a/src/ShadowDOM/wrappers/HTMLMediaElement.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/HTMLOptionElement.js b/src/ShadowDOM/wrappers/HTMLOptionElement.js deleted file mode 100644 index 63a7fe8..0000000 --- a/src/ShadowDOM/wrappers/HTMLOptionElement.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/HTMLSelectElement.js b/src/ShadowDOM/wrappers/HTMLSelectElement.js deleted file mode 100644 index e091999..0000000 --- a/src/ShadowDOM/wrappers/HTMLSelectElement.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/HTMLShadowElement.js b/src/ShadowDOM/wrappers/HTMLShadowElement.js deleted file mode 100644 index 32ac49b..0000000 --- a/src/ShadowDOM/wrappers/HTMLShadowElement.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/HTMLTableElement.js b/src/ShadowDOM/wrappers/HTMLTableElement.js deleted file mode 100644 index 446e5ac..0000000 --- a/src/ShadowDOM/wrappers/HTMLTableElement.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/HTMLTableRowElement.js b/src/ShadowDOM/wrappers/HTMLTableRowElement.js deleted file mode 100644 index 3a9a484..0000000 --- a/src/ShadowDOM/wrappers/HTMLTableRowElement.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/HTMLTableSectionElement.js b/src/ShadowDOM/wrappers/HTMLTableSectionElement.js deleted file mode 100644 index 871b8b9..0000000 --- a/src/ShadowDOM/wrappers/HTMLTableSectionElement.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/HTMLTemplateElement.js b/src/ShadowDOM/wrappers/HTMLTemplateElement.js deleted file mode 100644 index a145bc2..0000000 --- a/src/ShadowDOM/wrappers/HTMLTemplateElement.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/HTMLUnknownElement.js b/src/ShadowDOM/wrappers/HTMLUnknownElement.js deleted file mode 100644 index 606ddae..0000000 --- a/src/ShadowDOM/wrappers/HTMLUnknownElement.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/Node.js b/src/ShadowDOM/wrappers/Node.js deleted file mode 100644 index aa97b42..0000000 --- a/src/ShadowDOM/wrappers/Node.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/NodeList.js b/src/ShadowDOM/wrappers/NodeList.js deleted file mode 100644 index 1461592..0000000 --- a/src/ShadowDOM/wrappers/NodeList.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/Range.js b/src/ShadowDOM/wrappers/Range.js deleted file mode 100644 index e5961ac..0000000 --- a/src/ShadowDOM/wrappers/Range.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/SVGElement.js b/src/ShadowDOM/wrappers/SVGElement.js deleted file mode 100644 index c6d44e2..0000000 --- a/src/ShadowDOM/wrappers/SVGElement.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/SVGElementInstance.js b/src/ShadowDOM/wrappers/SVGElementInstance.js deleted file mode 100644 index 5fd9e46..0000000 --- a/src/ShadowDOM/wrappers/SVGElementInstance.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/SVGUseElement.js b/src/ShadowDOM/wrappers/SVGUseElement.js deleted file mode 100644 index 0ff18ed..0000000 --- a/src/ShadowDOM/wrappers/SVGUseElement.js +++ /dev/null @@ -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 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); diff --git a/src/ShadowDOM/wrappers/Selection.js b/src/ShadowDOM/wrappers/Selection.js deleted file mode 100644 index d43a677..0000000 --- a/src/ShadowDOM/wrappers/Selection.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/ShadowRoot.js b/src/ShadowDOM/wrappers/ShadowRoot.js deleted file mode 100644 index 915462e..0000000 --- a/src/ShadowDOM/wrappers/ShadowRoot.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/Text.js b/src/ShadowDOM/wrappers/Text.js deleted file mode 100644 index 8559e08..0000000 --- a/src/ShadowDOM/wrappers/Text.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/TouchEvent.js b/src/ShadowDOM/wrappers/TouchEvent.js deleted file mode 100644 index 7464411..0000000 --- a/src/ShadowDOM/wrappers/TouchEvent.js +++ /dev/null @@ -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); - diff --git a/src/ShadowDOM/wrappers/TreeWalker.js b/src/ShadowDOM/wrappers/TreeWalker.js deleted file mode 100644 index 25b7c0d..0000000 --- a/src/ShadowDOM/wrappers/TreeWalker.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/WebGLRenderingContext.js b/src/ShadowDOM/wrappers/WebGLRenderingContext.js deleted file mode 100644 index 223a360..0000000 --- a/src/ShadowDOM/wrappers/WebGLRenderingContext.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/Window.js b/src/ShadowDOM/wrappers/Window.js deleted file mode 100644 index b9e5010..0000000 --- a/src/ShadowDOM/wrappers/Window.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/XMLHttpRequest.js b/src/ShadowDOM/wrappers/XMLHttpRequest.js deleted file mode 100644 index 5ca6d67..0000000 --- a/src/ShadowDOM/wrappers/XMLHttpRequest.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/elements-with-form-property.js b/src/ShadowDOM/wrappers/elements-with-form-property.js deleted file mode 100644 index 81c52bb..0000000 --- a/src/ShadowDOM/wrappers/elements-with-form-property.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/events.js b/src/ShadowDOM/wrappers/events.js deleted file mode 100644 index 2ac5843..0000000 --- a/src/ShadowDOM/wrappers/events.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/generic.js b/src/ShadowDOM/wrappers/generic.js deleted file mode 100644 index 7420c22..0000000 --- a/src/ShadowDOM/wrappers/generic.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/node-interfaces.js b/src/ShadowDOM/wrappers/node-interfaces.js deleted file mode 100644 index 622f425..0000000 --- a/src/ShadowDOM/wrappers/node-interfaces.js +++ /dev/null @@ -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); diff --git a/src/ShadowDOM/wrappers/override-constructors.js b/src/ShadowDOM/wrappers/override-constructors.js deleted file mode 100644 index 1937b76..0000000 --- a/src/ShadowDOM/wrappers/override-constructors.js +++ /dev/null @@ -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); diff --git a/src/Template/Template.js b/src/Template/Template.js deleted file mode 100644 index f43e72a..0000000 --- a/src/Template/Template.js +++ /dev/null @@ -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