Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(209)

Unified Diff: pkg/web_components/lib/platform.concat.js

Issue 182073003: Update platform.js to latest. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/web_components/lib/platform.js ('k') | pkg/web_components/lib/platform.concat.js.map » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/web_components/lib/platform.concat.js
diff --git a/pkg/web_components/lib/platform.concat.js b/pkg/web_components/lib/platform.concat.js
index 293c435aee306e4f9ae4adc6131324832b64a3ce..0be0a0855658dd28524f3a915c89381299ee6dc0 100644
--- a/pkg/web_components/lib/platform.concat.js
+++ b/pkg/web_components/lib/platform.concat.js
@@ -3378,6 +3378,22 @@ window.ShadowDOMPolyfill = {};
})(window.ShadowDOMPolyfill);
+/*
+ * Copyright 2014 The Polymer Authors. All rights reserved.
+ * Use of this source code is goverened by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+(function(scope) {
+ 'use strict';
+
+ // TODO(arv): Implement.
+
+ scope.wrapHTMLCollection = scope.wrapNodeList;
+ scope.wrappers.HTMLCollection = scope.wrappers.NodeList;
+
+})(window.ShadowDOMPolyfill);
+
// Copyright 2012 The Polymer Authors. All rights reserved.
// Use of this source code is goverened by a BSD-style
// license that can be found in the LICENSE file.
@@ -5137,6 +5153,191 @@ window.ShadowDOMPolyfill = {};
scope.wrappers.Option = Option;
})(window.ShadowDOMPolyfill);
+// Copyright 2014 The Polymer Authors. All rights reserved.
+// Use of this source code is goverened by a BSD-style
+// license that can be found in the LICENSE file.
+
+(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 (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);
+
+/*
+ * Copyright 2014 The Polymer Authors. All rights reserved.
+ * Use of this source code is goverened by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+(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);
+
+/*
+ * Copyright 2014 The Polymer Authors. All rights reserved.
+ * Use of this source code is goverened by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+(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, {
+ 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);
+
+/*
+ * Copyright 2014 The Polymer Authors. All rights reserved.
+ * Use of this source code is goverened by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+
+(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);
+
// Copyright 2013 The Polymer Authors. All rights reserved.
// Use of this source code is goverened by a BSD-style
// license that can be found in the LICENSE file.
@@ -5702,7 +5903,10 @@ window.ShadowDOMPolyfill = {};
}
function getDistributedChildNodes(insertionPoint) {
- return distributedChildNodesTable.get(insertionPoint);
+ var rv = distributedChildNodesTable.get(insertionPoint);
+ if (!rv)
+ distributedChildNodesTable.set(insertionPoint, rv = []);
+ return rv;
}
function getChildNodesSnapshot(node) {
@@ -5810,9 +6014,12 @@ window.ShadowDOMPolyfill = {};
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++) {
pendingDirtyRenderers[i].render();
}
+
pendingDirtyRenderers = [];
}
@@ -5986,7 +6193,8 @@ window.ShadowDOMPolyfill = {};
if (isShadowHost(node)) {
var renderer = getRendererForHost(node);
- renderNode.skip = !renderer.dirty;
+ // renderNode.skip = !renderer.dirty;
+ renderer.invalidate();
renderer.render(renderNode);
} else {
for (var child = node.firstChild; child; child = child.nextSibling) {
@@ -6273,7 +6481,7 @@ window.ShadowDOMPolyfill = {};
'HTMLObjectElement',
// HTMLOptionElement is handled in HTMLOptionElement.js
'HTMLOutputElement',
- 'HTMLSelectElement',
+ // HTMLSelectElement is handled in HTMLSelectElement.js
'HTMLTextAreaElement',
];
@@ -6764,38 +6972,44 @@ window.ShadowDOMPolyfill = {};
// 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',
- 'br': 'HTMLBRElement',
+ 'audio': 'HTMLAudioElement',
'base': 'HTMLBaseElement',
'body': 'HTMLBodyElement',
+ 'br': 'HTMLBRElement',
'button': 'HTMLButtonElement',
+ 'canvas': 'HTMLCanvasElement',
+ 'caption': 'HTMLTableCaptionElement',
+ 'col': 'HTMLTableColElement',
// 'command': 'HTMLCommandElement', // Not fully implemented in Gecko.
- 'dl': 'HTMLDListElement',
- 'datalist': 'HTMLDataListElement',
+ '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',
- 'hr': 'HTMLHRElement',
- 'head': 'HTMLHeadElement',
'h1': 'HTMLHeadingElement',
+ 'head': 'HTMLHeadElement',
+ 'hr': 'HTMLHRElement',
'html': 'HTMLHtmlElement',
'iframe': 'HTMLIFrameElement',
+ 'img': 'HTMLImageElement',
'input': 'HTMLInputElement',
- 'li': 'HTMLLIElement',
+ 'keygen': 'HTMLKeygenElement',
'label': 'HTMLLabelElement',
'legend': 'HTMLLegendElement',
+ 'li': 'HTMLLIElement',
'link': 'HTMLLinkElement',
'map': 'HTMLMapElement',
'marquee': 'HTMLMarqueeElement',
@@ -6803,9 +7017,8 @@ window.ShadowDOMPolyfill = {};
'menuitem': 'HTMLMenuItemElement',
'meta': 'HTMLMetaElement',
'meter': 'HTMLMeterElement',
- 'del': 'HTMLModElement',
- 'ol': 'HTMLOListElement',
'object': 'HTMLObjectElement',
+ 'ol': 'HTMLOListElement',
'optgroup': 'HTMLOptGroupElement',
'option': 'HTMLOptionElement',
'output': 'HTMLOutputElement',
@@ -6816,23 +7029,23 @@ window.ShadowDOMPolyfill = {};
'q': 'HTMLQuoteElement',
'script': 'HTMLScriptElement',
'select': 'HTMLSelectElement',
+ 'shadow': 'HTMLShadowElement',
'source': 'HTMLSourceElement',
'span': 'HTMLSpanElement',
'style': 'HTMLStyleElement',
- 'time': 'HTMLTimeElement',
- 'caption': 'HTMLTableCaptionElement',
+ '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',
- 'col': 'HTMLTableColElement',
- 'table': 'HTMLTableElement',
- 'tr': 'HTMLTableRowElement',
- 'thead': 'HTMLTableSectionElement',
- 'tbody': 'HTMLTableSectionElement',
+ 'template': 'HTMLTemplateElement',
'textarea': 'HTMLTextAreaElement',
- 'track': 'HTMLTrackElement',
+ 'thead': 'HTMLTableSectionElement',
+ 'time': 'HTMLTimeElement',
'title': 'HTMLTitleElement',
+ 'tr': 'HTMLTableRowElement',
+ 'track': 'HTMLTrackElement',
'ul': 'HTMLUListElement',
'video': 'HTMLVideoElement',
};
@@ -6853,9 +7066,6 @@ window.ShadowDOMPolyfill = {};
window[name] = scope.wrappers[name]
});
- // Export for testing.
- scope.knownElements = elements;
-
})(window.ShadowDOMPolyfill);
/*
@@ -7028,7 +7238,7 @@ var ShadowCSS = {
// 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) {
+ shimStyling: function(root, name, extendsName, ownSheet) {
var typeExtension = this.isTypeExtension(extendsName);
// use caching to make working with styles nodes easier and to facilitate
// lookup of extendee
@@ -7050,7 +7260,11 @@ var ShadowCSS = {
s.parentNode.removeChild(s);
}
// add style to document
- addCssToDocument(cssText);
+ if (ownSheet) {
+ addOwnSheet(cssText, name);
+ } else {
+ addCssToDocument(cssText);
+ }
},
// apply @polyfill rules + :host and scope shimming
stylesToShimmedCssText: function(rootStyles, scopeStyles, name,
@@ -7203,8 +7417,12 @@ var ShadowCSS = {
cssText = this.convertColonAncestor(cssText);
cssText = this.convertCombinators(cssText);
if (name) {
- var rules = cssToRules(cssText);
- cssText = this.scopeRules(rules, name, typeExtension);
+ var self = this, cssText;
+
+ withCssRules(cssText, function(rules) {
+ cssText = self.scopeRules(rules, name, typeExtension);
+ });
+
}
return cssText;
},
@@ -7273,19 +7491,21 @@ var ShadowCSS = {
// change a selector like 'div' to 'name div'
scopeRules: function(cssRules, name, typeExtension) {
var cssText = '';
- Array.prototype.forEach.call(cssRules, function(rule) {
- if (rule.selectorText && (rule.style && rule.style.cssText)) {
- cssText += this.scopeSelector(rule.selectorText, name, typeExtension,
- this.strictStyling) + ' {\n\t';
- cssText += this.propertiesFromRule(rule) + '\n}\n\n';
- } else if (rule.media) {
- cssText += '@media ' + rule.media.mediaText + ' {\n';
- cssText += this.scopeRules(rule.cssRules, name, typeExtension);
- cssText += '\n}\n\n';
- } else if (rule.cssText) {
- cssText += rule.cssText + '\n\n';
- }
- }, this);
+ if (cssRules) {
+ Array.prototype.forEach.call(cssRules, function(rule) {
+ if (rule.selectorText && (rule.style && rule.style.cssText)) {
+ cssText += this.scopeSelector(rule.selectorText, name, typeExtension,
+ this.strictStyling) + ' {\n\t';
+ cssText += this.propertiesFromRule(rule) + '\n}\n\n';
+ } else if (rule.type === CSSRule.MEDIA_RULE) {
+ cssText += '@media ' + rule.media.mediaText + ' {\n';
+ cssText += this.scopeRules(rule.cssRules, name, typeExtension);
+ cssText += '\n}\n\n';
+ } else if (rule.cssText) {
+ cssText += rule.cssText + '\n\n';
+ }
+ }, this);
+ }
return cssText;
},
scopeSelector: function(selector, name, typeExtension, strict) {
@@ -7399,11 +7619,65 @@ function cssTextToStyle(cssText) {
function cssToRules(cssText) {
var style = cssTextToStyle(cssText);
document.head.appendChild(style);
- var rules = style.sheet.cssRules;
+ 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 = style.sheet.cssRules;
+ 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);
@@ -7417,6 +7691,13 @@ function addCssToDocument(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';
@@ -8290,17 +8571,6 @@ scope.mixin = mixin;
})();
}
- // TODO(sorvell): workaround for bug:
- // https://code.google.com/p/chromium/issues/detail?id=229142
- // remove when this bug is addressed
- // give main document templates a base that allows them to fetch eagerly
- // resolved paths relative to the main document
- var template = document.createElement('template');
- var base = document.createElement('base');
- base.href = document.baseURI;
- template.content.ownerDocument.appendChild(base);
-
-
// utility
function createDOM(inTagOrNode, inHTML, inAttrs) {
@@ -8329,7 +8599,9 @@ scope.mixin = mixin;
// deliver queued delcarations
scope.deliverDeclarations = function() {
- scope.deliverDeclarations = null;
+ scope.deliverDeclarations = function() {
+ throw 'Possible attempt to load Polymer twice';
+ };
return elementDeclarations;
}
@@ -8683,6 +8955,9 @@ var urlResolver = {
}
}
},
+ resolveTemplate: function(template) {
+ this.resolveDom(template.content, template.ownerDocument.baseURI);
+ },
resolveStyles: function(root, url) {
var styles = root.querySelectorAll('style');
if (styles) {
@@ -9598,9 +9873,12 @@ var importParser = {
document.head.appendChild(elt);
},
// tracks when a loadable element has loaded
- trackElement: function(elt) {
+ trackElement: function(elt, callback) {
var self = this;
- var done = function() {
+ var done = function(e) {
+ if (callback) {
+ callback(e);
+ }
self.markParsingComplete(elt);
};
elt.addEventListener('load', done);
@@ -9632,31 +9910,23 @@ var importParser = {
}
}
},
+ // NOTE: execute scripts by injecting them and watching for the load/error
+ // event. Inline scripts are handled via dataURL's because browsers tend to
+ // provide correct parsing errors in this case. If this has any compatibility
+ // issues, we can switch to injecting the inline script with textContent.
+ // Scripts with dataURL's do not appear to generate load events and therefore
+ // we assume they execute synchronously.
parseScript: function(scriptElt) {
- // acquire code to execute
- var code = (scriptElt.__resource || scriptElt.textContent).trim();
- if (code) {
- // calculate source map hint
- var moniker = scriptElt.__nodeUrl;
- if (!moniker) {
- moniker = scriptElt.ownerDocument.baseURI;
- // there could be more than one script this url
- var tag = '[' + Math.floor((Math.random()+1)*1000) + ']';
- // TODO(sjmiles): Polymer hack, should be pluggable if we need to allow
- // this sort of thing
- var matches = code.match(/Polymer\(['"]([^'"]*)/);
- tag = matches && matches[1] || tag;
- // tag the moniker
- moniker += '/' + tag + '.js';
- }
- // source map hint
- code += "\n//# sourceURL=" + moniker + "\n";
- // evaluate the code
- scope.currentScript = scriptElt;
- eval.call(window, code);
- scope.currentScript = null;
- }
- this.markParsingComplete(scriptElt);
+ var script = document.createElement('script');
+ script.__importElement = scriptElt;
+ script.src = scriptElt.src ? scriptElt.src :
+ generateScriptDataUrl(scriptElt);
+ scope.currentScript = scriptElt;
+ this.trackElement(script, function(e) {
+ script.parentNode.removeChild(script);
+ scope.currentScript = null;
+ });
+ document.head.appendChild(script);
},
// determine the next element in the tree which should be parsed
nextToParse: function() {
@@ -9688,9 +9958,6 @@ var importParser = {
if (nodeIsImport(node) && !node.import) {
return false;
}
- if (node.localName === 'script' && node.src && !node.__resource) {
- return false;
- }
return true;
}
};
@@ -9699,6 +9966,39 @@ function nodeIsImport(elt) {
return (elt.localName === 'link') && (elt.rel === IMPORT_LINK_TYPE);
}
+function generateScriptDataUrl(script) {
+ var scriptContent = generateScriptContent(script), b64;
+ try {
+ b64 = btoa(scriptContent);
+ } catch(e) {
+ b64 = btoa(unescape(encodeURIComponent(scriptContent)));
+ console.warn('Script contained non-latin characters that were forced ' +
+ 'to latin. Some characters may be wrong.', script);
+ }
+ return 'data:text/javascript;base64,' + b64;
+}
+
+function generateScriptContent(script) {
+ return script.textContent + generateSourceMapHint(script);
+}
+
+// calculate source map hint
+function generateSourceMapHint(script) {
+ var moniker = script.__nodeUrl;
+ if (!moniker) {
+ moniker = script.ownerDocument.baseURI;
+ // there could be more than one script this url
+ var tag = '[' + Math.floor((Math.random()+1)*1000) + ']';
+ // TODO(sjmiles): Polymer hack, should be pluggable if we need to allow
+ // this sort of thing
+ var matches = script.textContent.match(/Polymer\(['"]([^'"]*)/);
+ tag = matches && matches[1] || tag;
+ // tag the moniker
+ moniker += '/' + tag + '.js';
+ }
+ return '\n//# sourceURL=' + moniker + '\n';
+}
+
// style/stylesheet handling
// clone style with proper path resolution for main document
@@ -9773,8 +10073,6 @@ if (!useNative) {
// for any document, importer:
// - loads any linked import documents (with deduping)
- // for any import document, importer also:
- // - loads text of external script tags
var importer = {
documents: {},
@@ -9782,9 +10080,7 @@ if (!useNative) {
documentPreloadSelectors: 'link[rel=' + IMPORT_LINK_TYPE + ']',
// nodes to load in imports
importsPreloadSelectors: [
- 'link[rel=' + IMPORT_LINK_TYPE + ']',
- 'script[src]:not([type])',
- 'script[src][type="text/javascript"]'
+ 'link[rel=' + IMPORT_LINK_TYPE + ']'
].join(','),
loadNode: function(node) {
importLoader.addNode(node);
@@ -9871,6 +10167,11 @@ if (!useNative) {
if (!doc.baseURI) {
doc.baseURI = 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 last as it may trigger CustomElement upgrades
// TODO(sjmiles): problem wrt to template boostrapping below,
@@ -10441,7 +10742,6 @@ function upgradeDocument(doc) {
function upgradeDocumentTree(doc) {
doc = wrapIfNeeded(doc);
- upgradeDocument(doc);
//console.log('upgradeDocumentTree: ', (doc.baseURI).split('/').pop());
// upgrade contained imported documents
var imports = doc.querySelectorAll('link[rel=' + IMPORT_LINK_TYPE + ']');
@@ -10450,6 +10750,7 @@ function upgradeDocumentTree(doc) {
upgradeDocumentTree(n.import);
}
}
+ upgradeDocument(doc);
}
// exports
@@ -10723,11 +11024,9 @@ if (useNative) {
var used = {};
// start with inSrc
var p = inSrc;
- // sometimes the default is HTMLUnknownElement.prototype instead of
- // HTMLElement.prototype, so we add a test
- // the idea is to avoid mixing in native prototypes, so adding
- // the second test is WLOG
- while (p !== inNative && p !== HTMLUnknownElement.prototype) {
+ // The default is HTMLElement.prototype, so we add a test to avoid mixing in
+ // native prototypes
+ while (p !== inNative && p !== HTMLElement.prototype) {
var keys = Object.getOwnPropertyNames(p);
for (var i=0, k; k=keys[i]; i++) {
if (!used[k]) {
@@ -10799,6 +11098,17 @@ if (useNative) {
};
}
+ var HTML_NAMESPACE = 'http://www.w3.org/1999/xhtml';
+ function createElementNS(namespace, tag, typeExtension) {
+ // NOTE: we do not support non-HTML elements,
+ // just call createElementNS for non HTML Elements
+ if (namespace === HTML_NAMESPACE) {
+ return createElement(tag, typeExtension);
+ } else {
+ return domCreateElementNS(namespace, tag);
+ }
+ }
+
function createElement(tag, typeExtension) {
// TODO(sjmiles): ignore 'tag' when using 'typeExtension', we could
// error check it, or perhaps there should only ever be one argument
@@ -10851,6 +11161,7 @@ if (useNative) {
// capture native createElement before we override it
var domCreateElement = document.createElement.bind(document);
+ var domCreateElementNS = document.createElementNS.bind(document);
// capture native cloneNode before we override it
@@ -10860,6 +11171,7 @@ if (useNative) {
document.registerElement = register;
document.createElement = createElement; // override
+ document.createElementNS = createElementNS; // override
Node.prototype.cloneNode = cloneNode; // override
scope.registry = registry;
@@ -10878,6 +11190,32 @@ if (useNative) {
scope.upgrade = upgradeElement;
}
+// Create a custom 'instanceof'. This is necessary when CustomElements
+// are implemented via a mixin strategy, as for example on IE10.
+var isInstance;
+if (!Object.__proto__ && !useNative) {
+ isInstance = function(obj, ctor) {
+ var p = obj;
+ while (p) {
+ // NOTE: this is not technically correct since we're not checking if
+ // an object is an instance of a constructor; however, this should
+ // be good enough for the mixin strategy.
+ if (p === ctor.prototype) {
+ return true;
+ }
+ p = p.__proto__;
+ }
+ return false;
+ }
+} else {
+ isInstance = function(obj, base) {
+ return obj instanceof base;
+ }
+}
+
+// exports
+scope.instanceof = isInstance;
+
// bc
document.register = document.registerElement;
@@ -11026,12 +11364,6 @@ if (document.readyState === 'complete' || scope.flags.eager) {
*/
(function() {
-// inject style sheet
-var style = document.createElement('style');
-style.textContent = 'element {display: none !important;} /* injected by platform.js */';
-var head = document.querySelector('head');
-head.insertBefore(style, head.firstChild);
-
if (window.ShadowDOMPolyfill) {
// ensure wrapped inputs for these functions
@@ -11061,87 +11393,158 @@ if (window.ShadowDOMPolyfill) {
* license that can be found in the LICENSE file.
*/
(function(scope) {
+ var endOfMicrotask = scope.endOfMicrotask;
-var STYLE_SELECTOR = 'style';
+ // Generic url loader
+ function Loader(regex) {
+ this.regex = regex;
+ }
+ Loader.prototype = {
+ // TODO(dfreedm): there may be a better factoring here
+ // extract absolute urls from the text (full of relative urls)
+ extractUrls: function(text, base) {
+ var matches = [];
+ var matched, u;
+ while ((matched = this.regex.exec(text))) {
+ u = new URL(matched[1], base);
+ matches.push({matched: matched[0], url: u.href});
+ }
+ return matches;
+ },
+ // take a text blob, a root url, and a callback and load all the urls found within the text
+ // returns a map of absolute url to text
+ process: function(text, root, callback) {
+ var matches = this.extractUrls(text, root);
+ this.fetch(matches, {}, callback);
+ },
+ // build a mapping of url -> text from matches
+ fetch: function(matches, map, callback) {
+ var inflight = matches.length;
+
+ // return early if there is no fetching to be done
+ if (!inflight) {
+ return callback(map);
+ }
+
+ var done = function() {
+ if (--inflight === 0) {
+ callback(map);
+ }
+ };
-var urlResolver = scope.urlResolver;
+ // map url -> responseText
+ var handleXhr = function(err, request) {
+ var match = request.match;
+ var key = match.url;
+ // handle errors with an empty string
+ if (err) {
+ map[key] = '';
+ return done();
+ }
+ var response = request.response || request.responseText;
+ map[key] = response;
+ this.fetch(this.extractUrls(response, key), map, done);
+ };
-var loader = {
- cacheStyles: function(styles, callback) {
- var css = [];
- for (var i=0, l=styles.length, s; (i<l) && (s=styles[i]); i++) {
- css.push(s.textContent);
+ var m, req, url;
+ for (var i = 0; i < inflight; i++) {
+ m = matches[i];
+ url = m.url;
+ // if this url has already been requested, skip requesting it again
+ if (map[url]) {
+ // Async call to done to simplify the inflight logic
+ endOfMicrotask(done);
+ continue;
+ }
+ req = this.xhr(url, handleXhr, this);
+ req.match = m;
+ // tag the map with an XHR request to deduplicate at the same level
+ map[url] = req;
+ }
+ },
+ xhr: function(url, callback, scope) {
+ var request = new XMLHttpRequest();
+ request.open('GET', url, true);
+ request.send();
+ request.onload = function() {
+ callback.call(scope, null, request);
+ };
+ request.onerror = function() {
+ callback.call(scope, null, request);
+ };
+ return request;
}
- cacheCssText(css.join('\n'), callback);
+ };
+
+ scope.Loader = Loader;
+})(window.Platform);
+
+/*
+ * Copyright 2014 The Polymer Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style
+ * license that can be found in the LICENSE file.
+ */
+(function(scope) {
+
+var urlResolver = scope.urlResolver;
+var Loader = scope.Loader;
+
+function StyleResolver() {
+ this.loader = new Loader(this.regex);
+}
+StyleResolver.prototype = {
+ regex: /@import\s+(?:url)?["'\(]*([^'"\)]*)['"\)]*;/g,
+ // Recursively replace @imports with the text at that url
+ resolve: function(text, url, callback) {
+ var done = function(map) {
+ callback(this.flatten(text, url, map));
+ }.bind(this);
+ this.loader.process(text, url, done);
},
- xhrStyles: function(styles, callback) {
+ // resolve the textContent of a style node
+ resolveNode: function(style, callback) {
+ var text = style.textContent;
+ var url = style.ownerDocument.baseURI;
+ var done = function(text) {
+ style.textContent = text;
+ callback(style);
+ };
+ this.resolve(text, url, done);
+ },
+ // flatten all the @imports to text
+ flatten: function(text, base, map) {
+ var matches = this.loader.extractUrls(text, base);
+ var match, url, intermediate;
+ for (var i = 0; i < matches.length; i++) {
+ match = matches[i];
+ url = match.url;
+ // resolve any css text to be relative to the importer
+ intermediate = urlResolver.resolveCssText(map[url], url);
+ // flatten intermediate @imports
+ intermediate = this.flatten(intermediate, url, map);
+ text = text.replace(match.matched, intermediate);
+ }
+ return text;
+ },
+ loadStyles: function(styles, callback) {
var loaded=0, l = styles.length;
// called in the context of the style
function loadedStyle(style) {
- //console.log(style.textContent);
loaded++;
if (loaded === l && callback) {
callback();
}
}
for (var i=0, s; (i<l) && (s=styles[i]); i++) {
- xhrLoadStyle(s, loadedStyle);
+ this.resolveNode(s, loadedStyle);
}
}
};
-// use the platform to preload styles
-var preloadElement = document.createElement('preloader');
-preloadElement.style.display = 'none';
-var preloadRoot = preloadElement.createShadowRoot();
-document.head.appendChild(preloadElement);
-
-function cacheCssText(cssText, callback) {
- var style = createStyleElement(cssText);
- if (callback) {
- style.addEventListener('load', callback);
- style.addEventListener('error', callback);
- }
- preloadRoot.appendChild(style);
-}
-
-function createStyleElement(cssText, scope) {
- scope = scope || document;
- scope = scope.createElement ? scope : scope.ownerDocument;
- var style = scope.createElement('style');
- style.textContent = cssText;
- return style;
-}
-
-// TODO(sorvell): use a common loader shared with HTMLImports polyfill
-// currently, this just loads the first @import per style element
-// and does not recurse into loaded elements; we'll address this with a
-// generalized loader that's built out of the one in the HTMLImports polyfill.
-// polyfill the loading of a style element's @import via xhr
-function xhrLoadStyle(style, callback) {
- HTMLImports.xhr.load(atImportUrlFromStyle(style), function (err, resource,
- url) {
- replaceAtImportWithCssText(this, url, resource);
- this.textContent = urlResolver.resolveCssText(this.textContent, url);
- callback && callback(this);
- }, style);
-}
-
-var atImportRe = /@import\s[(]?['"]?([^\s'";)]*)/;
-
-// get the first @import rule from a style
-function atImportUrlFromStyle(style) {
- var matches = style.textContent.match(atImportRe);
- return matches && matches[1];
-}
-
-function replaceAtImportWithCssText(style, url, cssText) {
- var re = new RegExp('@import[^;]*' + url + '[^;]*;', 'i');
- style.textContent = style.textContent.replace(re, cssText);
-}
+var styleResolver = new StyleResolver();
// exports
-scope.loader = loader;
+scope.styleResolver = styleResolver;
})(window.Platform);
@@ -11650,12 +12053,15 @@ scope.loader = loader;
},
// EVENTS
down: function(inEvent) {
+ inEvent.bubbles = true;
this.fireEvent('pointerdown', inEvent);
},
move: function(inEvent) {
+ inEvent.bubbles = true;
this.fireEvent('pointermove', inEvent);
},
up: function(inEvent) {
+ inEvent.bubbles = true;
this.fireEvent('pointerup', inEvent);
},
enter: function(inEvent) {
@@ -11675,6 +12081,7 @@ scope.loader = loader;
this.fireEvent('pointerout', inEvent);
},
cancel: function(inEvent) {
+ inEvent.bubbles = true;
this.fireEvent('pointercancel', inEvent);
},
leaveOut: function(event) {
@@ -12998,9 +13405,19 @@ PointerGestureEvent.prototype.preventTap = function() {
* @class hold
*/
/**
- * Milliseconds pointer has been held down.
+ * Type of pointer that made the holding event.
+ * @type String
+ * @property pointerType
+ */
+/**
+ * Screen X axis position of the held pointer
* @type Number
- * @property holdTime
+ * @property clientX
+ */
+/**
+ * Screen Y axis position of the held pointer
+ * @type Number
+ * @property clientY
*/
/**
* Type of pointer that made the holding event.
@@ -13014,15 +13431,15 @@ PointerGestureEvent.prototype.preventTap = function() {
* @extends hold
*/
/**
+ * Milliseconds pointer has been held down.
+ * @type Number
+ * @property holdTime
+ */
+/**
* This event is fired when a held pointer is released or moved.
*
* @class released
*/
-/**
- * Type of pointer that made the holding event.
- * @type String
- * @property pointerType
- */
(function(scope) {
var dispatcher = scope.dispatcher;
@@ -13081,7 +13498,9 @@ PointerGestureEvent.prototype.preventTap = function() {
},
fireHold: function(inType, inHoldTime) {
var p = {
- pointerType: this.heldPointer.pointerType
+ pointerType: this.heldPointer.pointerType,
+ clientX: this.heldPointer.clientX,
+ clientY: this.heldPointer.clientY
};
if (inHoldTime) {
p.holdTime = inHoldTime;
@@ -13648,9 +14067,15 @@ PointerGestureEvent.prototype.preventTap = function() {
}
}
},
+ shouldTap: function(e) {
+ if (!e.tapPrevented) {
+ // only allow left click to tap for mouse
+ return e.pointerType === 'mouse' ? e.buttons === 1 : true;
+ }
+ },
pointerup: function(inEvent) {
var start = pointermap.get(inEvent.pointerId);
- if (start && !inEvent.tapPrevented) {
+ if (start && this.shouldTap(inEvent)) {
var t = scope.findLCA(start.target, inEvent.target);
if (t) {
var e = dispatcher.makeEvent('tap', {
@@ -13876,6 +14301,9 @@ PointerGestureEvent.prototype.preventTap = function() {
case 'select-multiple':
case 'select-one':
return 'change';
+ case 'range':
+ if (/Trident|MSIE/.test(navigator.userAgent))
+ return 'change';
default:
return 'input';
}
@@ -14228,6 +14656,20 @@ PointerGestureEvent.prototype.preventTap = function() {
};
var hasTemplateElement = typeof HTMLTemplateElement !== 'undefined';
+ if (hasTemplateElement) {
+ // TODO(rafaelw): Remove when fix for
+ // https://codereview.chromium.org/164803002/
+ // makes it to Chrome release.
+ (function() {
+ var t = document.createElement('template');
+ var d = t.content.ownerDocument;
+ var html = d.appendChild(d.createElement('html'));
+ var head = html.appendChild(d.createElement('head'));
+ var base = d.createElement('base');
+ base.href = document.baseURI;
+ head.appendChild(base);
+ })();
+ }
var allTemplatesSelectors = 'template, ' +
Object.keys(semanticTemplateElements).map(function(tagName) {
@@ -14325,6 +14767,14 @@ PointerGestureEvent.prototype.preventTap = function() {
var owner = template.ownerDocument;
if (!owner.stagingDocument_) {
owner.stagingDocument_ = owner.implementation.createHTMLDocument('');
+
+ // TODO(rafaelw): Remove when fix for
+ // https://codereview.chromium.org/164803002/
+ // makes it to Chrome release.
+ var base = owner.stagingDocument_.createElement('base');
+ base.href = document.baseURI;
+ owner.stagingDocument_.head.appendChild(base);
+
owner.stagingDocument_.stagingDocument_ = owner.stagingDocument_;
}
« no previous file with comments | « pkg/web_components/lib/platform.js ('k') | pkg/web_components/lib/platform.concat.js.map » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698