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

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

Issue 349313005: update polymer and platform.js (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 6 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 be0db90657c39e80d29d1498ad277a8f1db78489..2044ee351a452fa27b35c88e93128acf2c446804 100644
--- a/pkg/web_components/lib/platform.concat.js
+++ b/pkg/web_components/lib/platform.concat.js
@@ -192,7 +192,7 @@ if (typeof WeakMap === 'undefined') {
return obj === Object(obj);
}
- var numberIsNaN = global.Number.isNaN || function isNaN(value) {
+ var numberIsNaN = global.Number.isNaN || function(value) {
return typeof value === 'number' && global.isNaN(value);
}
@@ -221,45 +221,194 @@ if (typeof WeakMap === 'undefined') {
var identStart = '[\$_a-zA-Z]';
var identPart = '[\$_a-zA-Z0-9]';
- var ident = identStart + '+' + identPart + '*';
- var elementIndex = '(?:[0-9]|[1-9]+[0-9]+)';
- var identOrElementIndex = '(?:' + ident + '|' + elementIndex + ')';
- var path = '(?:' + identOrElementIndex + ')(?:\\s*\\.\\s*' + identOrElementIndex + ')*';
- var pathRegExp = new RegExp('^' + path + '$');
-
- function isPathValid(s) {
- if (typeof s != 'string')
- return false;
- s = s.trim();
+ var identRegExp = new RegExp('^' + identStart + '+' + identPart + '*' + '$');
- if (s == '')
- return true;
+ function getPathCharType(char) {
+ if (char === undefined)
+ return 'eof';
- if (s[0] == '.')
- return false;
+ var code = char.charCodeAt(0);
+
+ switch(code) {
+ case 0x5B: // [
+ case 0x5D: // ]
+ case 0x2E: // .
+ case 0x22: // "
+ case 0x27: // '
+ case 0x30: // 0
+ return char;
+
+ case 0x5F: // _
+ case 0x24: // $
+ return 'ident';
+
+ case 0x20: // Space
+ case 0x09: // Tab
+ case 0x0A: // Newline
+ case 0x0D: // Return
+ case 0xA0: // No-break space
+ case 0xFEFF: // Byte Order Mark
+ case 0x2028: // Line Separator
+ case 0x2029: // Paragraph Separator
+ return 'ws';
+ }
+
+ // a-z, A-Z
+ if ((0x61 <= code && code <= 0x7A) || (0x41 <= code && code <= 0x5A))
+ return 'ident';
- return pathRegExp.test(s);
+ // 1-9
+ if (0x31 <= code && code <= 0x39)
+ return 'number';
+
+ return 'else';
}
- var constructorIsPrivate = {};
+ var pathStateMachine = {
+ 'beforePath': {
+ 'ws': ['beforePath'],
+ 'ident': ['inIdent', 'append'],
+ '[': ['beforeElement'],
+ 'eof': ['afterPath']
+ },
- function Path(s, privateToken) {
- if (privateToken !== constructorIsPrivate)
- throw Error('Use Path.get to retrieve path objects');
+ 'inPath': {
+ 'ws': ['inPath'],
+ '.': ['beforeIdent'],
+ '[': ['beforeElement'],
+ 'eof': ['afterPath']
+ },
+
+ 'beforeIdent': {
+ 'ws': ['beforeIdent'],
+ 'ident': ['inIdent', 'append']
+ },
+
+ 'inIdent': {
+ 'ident': ['inIdent', 'append'],
+ '0': ['inIdent', 'append'],
+ 'number': ['inIdent', 'append'],
+ 'ws': ['inPath', 'push'],
+ '.': ['beforeIdent', 'push'],
+ '[': ['beforeElement', 'push'],
+ 'eof': ['afterPath', 'push']
+ },
+
+ 'beforeElement': {
+ 'ws': ['beforeElement'],
+ '0': ['afterZero', 'append'],
+ 'number': ['inIndex', 'append'],
+ "'": ['inSingleQuote', 'append', ''],
+ '"': ['inDoubleQuote', 'append', '']
+ },
+
+ 'afterZero': {
+ 'ws': ['afterElement', 'push'],
+ ']': ['inPath', 'push']
+ },
- if (s.trim() == '')
- return this;
+ 'inIndex': {
+ '0': ['inIndex', 'append'],
+ 'number': ['inIndex', 'append'],
+ 'ws': ['afterElement'],
+ ']': ['inPath', 'push']
+ },
- if (isIndex(s)) {
- this.push(s);
- return this;
+ 'inSingleQuote': {
+ "'": ['afterElement'],
+ 'eof': ['error'],
+ 'else': ['inSingleQuote', 'append']
+ },
+
+ 'inDoubleQuote': {
+ '"': ['afterElement'],
+ 'eof': ['error'],
+ 'else': ['inDoubleQuote', 'append']
+ },
+
+ 'afterElement': {
+ 'ws': ['afterElement'],
+ ']': ['inPath', 'push']
}
+ }
- s.split(/\s*\.\s*/).filter(function(part) {
- return part;
- }).forEach(function(part) {
- this.push(part);
- }, this);
+ function noop() {}
+
+ function parsePath(path) {
+ var keys = [];
+ var index = -1;
+ var c, newChar, key, type, transition, action, typeMap, mode = 'beforePath';
+
+ var actions = {
+ push: function() {
+ if (key === undefined)
+ return;
+
+ keys.push(key);
+ key = undefined;
+ },
+
+ append: function() {
+ if (key === undefined)
+ key = newChar
+ else
+ key += newChar;
+ }
+ };
+
+ function maybeUnescapeQuote() {
+ if (index >= path.length)
+ return;
+
+ var nextChar = path[index + 1];
+ if ((mode == 'inSingleQuote' && nextChar == "'") ||
+ (mode == 'inDoubleQuote' && nextChar == '"')) {
+ index++;
+ newChar = nextChar;
+ actions.append();
+ return true;
+ }
+ }
+
+ while (mode) {
+ index++;
+ c = path[index];
+
+ if (c == '\\' && maybeUnescapeQuote(mode))
+ continue;
+
+ type = getPathCharType(c);
+ typeMap = pathStateMachine[mode];
+ transition = typeMap[type] || typeMap['else'] || 'error';
+
+ if (transition == 'error')
+ return; // parse error;
+
+ mode = transition[0];
+ action = actions[transition[1]] || noop;
+ newChar = transition[2] === undefined ? c : transition[2];
+ action();
+
+ if (mode === 'afterPath') {
+ return keys;
+ }
+ }
+
+ return; // parse error
+ }
+
+ function isIdent(s) {
+ return identRegExp.test(s);
+ }
+
+ var constructorIsPrivate = {};
+
+ function Path(parts, privateToken) {
+ if (privateToken !== constructorIsPrivate)
+ throw Error('Use Path.get to retrieve path objects');
+
+ if (parts.length)
+ Array.prototype.push.apply(this, parts.slice());
if (hasEval && this.length) {
this.getValueFrom = this.compiledGetValueFromFn();
@@ -273,30 +422,57 @@ if (typeof WeakMap === 'undefined') {
if (pathString instanceof Path)
return pathString;
- if (pathString == null)
+ if (pathString == null || pathString.length == 0)
pathString = '';
- if (typeof pathString !== 'string')
+ if (typeof pathString != 'string') {
+ if (isIndex(pathString.length)) {
+ // Constructed with array-like (pre-parsed) keys
+ return new Path(pathString, constructorIsPrivate);
+ }
+
pathString = String(pathString);
+ }
var path = pathCache[pathString];
if (path)
return path;
- if (!isPathValid(pathString))
+
+ var parts = parsePath(pathString);
+ if (!parts)
return invalidPath;
- var path = new Path(pathString, constructorIsPrivate);
+
+ var path = new Path(parts, constructorIsPrivate);
pathCache[pathString] = path;
return path;
}
Path.get = getPath;
+ function formatAccessor(key) {
+ if (isIndex(key)) {
+ return '[' + key + ']';
+ } else {
+ return '["' + key.replace(/"/g, '\\"') + '"]';
+ }
+ }
+
Path.prototype = createObject({
__proto__: [],
valid: true,
toString: function() {
- return this.join('.');
+ var pathString = '';
+ for (var i = 0; i < this.length; i++) {
+ var key = this[i];
+ if (isIdent(key)) {
+ pathString += i ? '.' + key : key;
+ } else {
+ pathString += formatAccessor(key);
+ }
+ }
+
+ return pathString;
},
getValueFrom: function(obj, directObserver) {
@@ -319,22 +495,20 @@ if (typeof WeakMap === 'undefined') {
},
compiledGetValueFromFn: function() {
- var accessors = this.map(function(ident) {
- return isIndex(ident) ? '["' + ident + '"]' : '.' + ident;
- });
-
var str = '';
var pathString = 'obj';
str += 'if (obj != null';
var i = 0;
+ var key;
for (; i < (this.length - 1); i++) {
- var ident = this[i];
- pathString += accessors[i];
+ key = this[i];
+ pathString += isIdent(key) ? '.' + key : formatAccessor(key);
str += ' &&\n ' + pathString + ' != null';
}
str += ')\n';
- pathString += accessors[i];
+ var key = this[i];
+ pathString += isIdent(key) ? '.' + key : formatAccessor(key);
str += ' return ' + pathString + ';\nelse\n return undefined;';
return new Function('obj', str);
@@ -935,6 +1109,10 @@ if (typeof WeakMap === 'undefined') {
PathObserver.prototype = createObject({
__proto__: Observer.prototype,
+ get path() {
+ return this.path_;
+ },
+
connect_: function() {
if (hasObserve)
this.directObserver_ = getObservedSet(this, this.object_);
@@ -961,7 +1139,7 @@ if (typeof WeakMap === 'undefined') {
if (skipChanges || areSameValue(this.value_, oldValue))
return false;
- this.report_([this.value_, oldValue]);
+ this.report_([this.value_, oldValue, this]);
return true;
},
@@ -1171,98 +1349,6 @@ if (typeof WeakMap === 'undefined') {
delete: true
};
- var updateRecord = {
- object: undefined,
- type: 'update',
- name: undefined,
- oldValue: undefined
- };
-
- function notify(object, name, value, oldValue) {
- if (areSameValue(value, oldValue))
- return;
-
- // TODO(rafaelw): Hack hack hack. This entire code really needs to move
- // out of observe-js into polymer.
- if (typeof object.propertyChanged_ == 'function')
- object.propertyChanged_(name, value, oldValue);
-
- if (!hasObserve)
- return;
-
- var notifier = object.notifier_;
- if (!notifier)
- notifier = object.notifier_ = Object.getNotifier(object);
-
- updateRecord.object = object;
- updateRecord.name = name;
- updateRecord.oldValue = oldValue;
-
- notifier.notify(updateRecord);
- }
-
- Observer.createBindablePrototypeAccessor = function(proto, name) {
- var privateName = name + '_';
- var privateObservable = name + 'Observable_';
-
- proto[privateName] = proto[name];
-
- Object.defineProperty(proto, name, {
- get: function() {
- var observable = this[privateObservable];
- if (observable)
- observable.deliver();
-
- return this[privateName];
- },
- set: function(value) {
- var observable = this[privateObservable];
- if (observable) {
- observable.setValue(value);
- return;
- }
-
- var oldValue = this[privateName];
- this[privateName] = value;
- notify(this, name, value, oldValue);
-
- return value;
- },
- configurable: true
- });
- }
-
- Observer.bindToInstance = function(instance, name, observable, resolveFn) {
- var privateName = name + '_';
- var privateObservable = name + 'Observable_';
-
- instance[privateObservable] = observable;
- var oldValue = instance[privateName];
- var value = observable.open(function(value, oldValue) {
- instance[privateName] = value;
- notify(instance, name, value, oldValue);
- });
-
- if (resolveFn && !areSameValue(oldValue, value)) {
- var resolvedValue = resolveFn(oldValue, value);
- if (!areSameValue(value, resolvedValue)) {
- value = resolvedValue;
- if (observable.setValue)
- observable.setValue(value);
- }
- }
-
- instance[privateName] = value;
- notify(instance, name, value, oldValue);
-
- return {
- close: function() {
- observable.close();
- instance[privateObservable] = undefined;
- }
- };
- }
-
function diffObjectFromChangeRecords(object, changeRecords, oldValues) {
var added = {};
var removed = {};
@@ -3044,7 +3130,11 @@ window.ShadowDOMPolyfill = {};
targetTable.set(event, target);
currentTargetTable.set(event, currentTarget);
- for (var i = 0; i < listeners.length; i++) {
+ // 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;
@@ -3072,7 +3162,9 @@ window.ShadowDOMPolyfill = {};
}
}
- if (anyRemoved) {
+ listeners.depth--;
+
+ if (anyRemoved && listeners.depth === 0) {
var copy = listeners.slice();
listeners.length = 0;
for (var i = 0; i < copy.length; i++) {
@@ -3137,25 +3229,11 @@ window.ShadowDOMPolyfill = {};
return eventPhaseTable.get(this);
},
get path() {
- var nodeList = new wrappers.NodeList();
var eventPath = eventPathTable.get(this);
- if (eventPath) {
- var index = 0;
- var lastIndex = eventPath.length - 1;
- var baseRoot = getTreeScope(currentTargetTable.get(this));
-
- for (var i = 0; i <= lastIndex; i++) {
- var currentTarget = eventPath[i];
- var currentRoot = getTreeScope(currentTarget);
- if (currentRoot.contains(baseRoot) &&
- // Make sure we do not add Window to the path.
- (i !== lastIndex || currentTarget instanceof wrappers.Node)) {
- nodeList[index++] = currentTarget;
- }
- }
- nodeList.length = index;
- }
- return nodeList;
+ if (!eventPath)
+ return [];
+ // TODO(arv): Event path should contain window.
+ return eventPath.slice();
},
stopPropagation: function() {
stopPropagationTable.set(this, true);
@@ -3383,6 +3461,7 @@ window.ShadowDOMPolyfill = {};
var listeners = listenersTable.get(this);
if (!listeners) {
listeners = [];
+ listeners.depth = 0;
listenersTable.set(this, listeners);
} else {
// Might have a duplicate.
@@ -3491,6 +3570,15 @@ window.ShadowDOMPolyfill = {};
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);
}
@@ -4448,7 +4536,7 @@ window.ShadowDOMPolyfill = {};
} else {
if (modNode && remNodes.length) {
modNode.data += s;
- cleanUpNodes(remNodes);
+ cleanupNodes(remNodes);
}
remNodes = [];
s = '';
@@ -4766,6 +4854,53 @@ window.ShadowDOMPolyfill = {};
scope.wrappers.Text = Text;
})(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';
+
+ function invalidateClass(el) {
+ scope.invalidateRendererBasedOnAttribute(el, 'class');
+ }
+
+ function DOMTokenList(impl, ownerElement) {
+ this.impl = impl;
+ this.ownerElement_ = ownerElement;
+ }
+
+ DOMTokenList.prototype = {
+ get length() {
+ return this.impl.length;
+ },
+ item: function(index) {
+ return this.impl.item(index);
+ },
+ contains: function(token) {
+ return this.impl.contains(token);
+ },
+ add: function() {
+ this.impl.add.apply(this.impl, arguments);
+ invalidateClass(this.ownerElement_);
+ },
+ remove: function() {
+ this.impl.remove.apply(this.impl, arguments);
+ invalidateClass(this.ownerElement_);
+ },
+ toggle: function(token) {
+ var rv = this.impl.toggle.apply(this.impl, arguments);
+ invalidateClass(this.ownerElement_);
+ return rv;
+ },
+ toString: function() {
+ return this.impl.toString();
+ }
+ };
+
+ scope.wrappers.DOMTokenList = DOMTokenList;
+})(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.
@@ -4776,6 +4911,7 @@ window.ShadowDOMPolyfill = {};
var ChildNodeInterface = scope.ChildNodeInterface;
var GetElementsByInterface = scope.GetElementsByInterface;
var Node = scope.wrappers.Node;
+ var DOMTokenList = scope.wrappers.DOMTokenList;
var ParentNodeInterface = scope.ParentNodeInterface;
var SelectorsInterface = scope.SelectorsInterface;
var addWrapNodeListMethod = scope.addWrapNodeListMethod;
@@ -4783,6 +4919,7 @@ window.ShadowDOMPolyfill = {};
var mixin = scope.mixin;
var oneOf = scope.oneOf;
var registerWrapper = scope.registerWrapper;
+ var unwrap = scope.unwrap;
var wrappers = scope.wrappers;
var OriginalElement = window.Element;
@@ -4822,6 +4959,8 @@ window.ShadowDOMPolyfill = {};
});
}
+ var classListTable = new WeakMap();
+
function Element(node) {
Node.call(this, node);
}
@@ -4859,6 +4998,31 @@ window.ShadowDOMPolyfill = {};
matches: function(selector) {
return originalMatches.call(this.impl, selector);
+ },
+
+ get classList() {
+ var list = classListTable.get(this);
+ if (!list) {
+ classListTable.set(this,
+ list = new DOMTokenList(unwrap(this).classList, this));
+ }
+ return list;
+ },
+
+ get className() {
+ return unwrap(this).className;
+ },
+
+ set className(v) {
+ this.setAttribute('class', v);
+ },
+
+ get id() {
+ return unwrap(this).id;
+ },
+
+ set id(v) {
+ this.setAttribute('id', v);
}
});
@@ -4875,28 +5039,6 @@ window.ShadowDOMPolyfill = {};
Element.prototype.createShadowRoot;
}
- /**
- * Useful for generating the accessor pair for a property that reflects an
- * attribute.
- */
- function setterDirtiesAttribute(prototype, propertyName, opt_attrName) {
- var attrName = opt_attrName || propertyName;
- Object.defineProperty(prototype, propertyName, {
- get: function() {
- return this.impl[propertyName];
- },
- set: function(v) {
- this.impl[propertyName] = v;
- invalidateRendererBasedOnAttribute(this, attrName);
- },
- configurable: true,
- enumerable: true
- });
- }
-
- setterDirtiesAttribute(Element.prototype, 'id');
- setterDirtiesAttribute(Element.prototype, 'className', 'class');
-
mixin(Element.prototype, ChildNodeInterface);
mixin(Element.prototype, GetElementsByInterface);
mixin(Element.prototype, ParentNodeInterface);
@@ -4905,8 +5047,7 @@ window.ShadowDOMPolyfill = {};
registerWrapper(OriginalElement, Element,
document.createElementNS(null, 'x'));
- // TODO(arv): Export setterDirtiesAttribute and apply it to more bindings
- // that reflect attributes.
+ scope.invalidateRendererBasedOnAttribute = invalidateRendererBasedOnAttribute;
scope.matchesNames = matchesNames;
scope.wrappers.Element = Element;
})(window.ShadowDOMPolyfill);
@@ -5802,6 +5943,8 @@ window.ShadowDOMPolyfill = {};
(function(scope) {
'use strict';
+ var Element = scope.wrappers.Element;
+ var HTMLElement = scope.wrappers.HTMLElement;
var registerObject = scope.registerObject;
var SVG_NS = 'http://www.w3.org/2000/svg';
@@ -5809,6 +5952,16 @@ window.ShadowDOMPolyfill = {};
var SVGTitleElement = registerObject(svgTitleElement);
var SVGElement = Object.getPrototypeOf(SVGTitleElement.prototype).constructor;
+ // 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;
+ }
+
scope.wrappers.SVGElement = SVGElement;
})(window.ShadowDOMPolyfill);
@@ -7100,6 +7253,10 @@ window.ShadowDOMPolyfill = {};
getSelection: function() {
renderAllPending();
return new Selection(originalGetSelection.call(unwrap(this)));
+ },
+ getElementsByName: function(name) {
+ return SelectorsInterface.querySelectorAll.call(this,
+ '[name=' + JSON.stringify(String(name)) + ']');
}
});
@@ -7244,6 +7401,7 @@ window.ShadowDOMPolyfill = {};
'createTextNode',
'elementFromPoint',
'getElementById',
+ 'getElementsByName',
'getSelection',
]);
@@ -7534,7 +7692,7 @@ window.ShadowDOMPolyfill = {};
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
-(function() {
+(function(scope) {
// convenient global
window.wrap = ShadowDOMPolyfill.wrapIfNeeded;
@@ -7567,7 +7725,62 @@ window.ShadowDOMPolyfill = {};
};
Element.prototype.webkitCreateShadowRoot = Element.prototype.createShadowRoot;
-})();
+
+ function queryShadow(node, selector) {
+ var m, el = node.firstElementChild;
+ var shadows, sr, i;
+ shadows = [];
+ sr = node.shadowRoot;
+ while(sr) {
+ shadows.push(sr);
+ sr = sr.olderShadowRoot;
+ }
+ for(i = shadows.length - 1; i >= 0; i--) {
+ m = shadows[i].querySelector(selector);
+ if (m) {
+ return m;
+ }
+ }
+ while(el) {
+ m = queryShadow(el, selector);
+ if (m) {
+ return m;
+ }
+ el = el.nextElementSibling;
+ }
+ return null;
+ }
+
+ function queryAllShadows(node, selector, results) {
+ var el = node.firstElementChild;
+ var temp, sr, shadows, i, j;
+ shadows = [];
+ sr = node.shadowRoot;
+ while(sr) {
+ shadows.push(sr);
+ sr = sr.olderShadowRoot;
+ }
+ for (i = shadows.length - 1; i >= 0; i--) {
+ temp = shadows[i].querySelectorAll(selector);
+ for(j = 0; j < temp.length; j++) {
+ results.push(temp[j]);
+ }
+ }
+ while (el) {
+ queryAllShadows(el, selector, results);
+ el = el.nextElementSibling;
+ }
+ return results;
+ }
+
+ scope.queryAllShadows = function(node, selector, all) {
+ if (all) {
+ return queryAllShadows(node, selector, []);
+ } else {
+ return queryShadow(node, selector);
+ }
+ };
+})(window.Platform);
/*
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
@@ -7969,7 +8182,7 @@ var ShadowCSS = {
var cssText = '';
if (cssRules) {
Array.prototype.forEach.call(cssRules, function(rule) {
- if (rule.selectorText && (rule.style && rule.style.cssText)) {
+ if (rule.selectorText && (rule.style && rule.style.cssText !== undefined)) {
cssText += this.scopeSelector(rule.selectorText, scopeSelector,
this.strictStyling) + ' {\n\t';
cssText += this.propertiesFromRule(rule) + '\n}\n\n';
@@ -7977,8 +8190,23 @@ var ShadowCSS = {
cssText += '@media ' + rule.media.mediaText + ' {\n';
cssText += this.scopeRules(rule.cssRules, scopeSelector);
cssText += '\n}\n\n';
- } else if (rule.cssText) {
- cssText += rule.cssText + '\n\n';
+ } else {
+ // TODO(sjmiles): KEYFRAMES_RULE in IE11 throws when we query cssText
+ // 'cssText' in rule returns true, but rule.cssText throws anyway
+ // We can test the rule type, e.g.
+ // else if (rule.type !== CSSRule.KEYFRAMES_RULE && rule.cssText) {
+ // but this will prevent cssText propagation in other browsers which
+ // support it.
+ // KEYFRAMES_RULE has a CSSRuleSet, so the text can probably be reconstructed
+ // from that collection; this would be a proper fix.
+ // For now, I'm trapping the exception so IE11 is unblocked in other areas.
+ try {
+ if (rule.cssText) {
+ cssText += rule.cssText + '\n\n';
+ }
+ } catch(x) {
+ // squelch
+ }
}
}, this);
}
@@ -8306,6 +8534,7 @@ if (window.ShadowDOMPolyfill) {
}
style.__importParsed = true;
this.markParsingComplete(elt);
+ this.parseNext();
}
var hasResource = HTMLImports.parser.hasResource;
@@ -9420,9 +9649,11 @@ scope.mixin = mixin;
module = null;
break;
case 2:
+ // dependsOrFactory is `factory` in this case
module = dependsOrFactory.apply(this);
break;
default:
+ // dependsOrFactory is `depends` in this case
module = withDependencies(moduleFactory, dependsOrFactory);
break;
}
@@ -9444,7 +9675,8 @@ scope.mixin = mixin;
// exports
scope.marshal = marshal;
- scope.module = module;
+ // `module` confuses commonjs detectors
+ scope.modularize = module;
scope.using = using;
})(window);
@@ -9551,7 +9783,7 @@ var urlResolver = {
var replacement;
if (value && value.search(URL_TEMPLATE_SEARCH) < 0) {
if (v === 'style') {
- replacement = replaceUrlsInCssText(value, url, CSS_URL_REGEXP);
+ replacement = replaceUrlsInCssText(value, url, false, CSS_URL_REGEXP);
} else {
replacement = resolveRelativeUrl(url, value);
}
@@ -9563,7 +9795,7 @@ var urlResolver = {
var CSS_URL_REGEXP = /(url\()([^)]*)(\))/g;
var CSS_IMPORT_REGEXP = /(@import[\s]+(?!url\())([^;]*)(;)/g;
-var URL_ATTRS = ['href', 'src', 'action', 'style'];
+var URL_ATTRS = ['href', 'src', 'action', 'style', 'url'];
var URL_ATTRS_SELECTOR = '[' + URL_ATTRS.join('],[') + ']';
var URL_TEMPLATE_SEARCH = '{{.*}}';
@@ -10261,8 +10493,8 @@ window.HTMLImports = window.HTMLImports || {flags:{}};
this.receive(url, elt, null, body);
}.bind(this), 0);
} else {
- var receiveXhr = function(err, resource) {
- this.receive(url, elt, err, resource);
+ var receiveXhr = function(err, resource, redirectedUrl) {
+ this.receive(url, elt, err, resource, redirectedUrl);
}.bind(this);
xhr.load(url, receiveXhr);
// TODO(sorvell): blocked on)
@@ -10280,16 +10512,25 @@ window.HTMLImports = window.HTMLImports || {flags:{}};
*/
}
},
- receive: function(url, elt, err, resource) {
+ receive: function(url, elt, err, resource, redirectedUrl) {
this.cache[url] = resource;
var $p = this.pending[url];
+ if ( redirectedUrl && redirectedUrl !== url ) {
+ this.cache[redirectedUrl] = resource;
+ $p = $p.concat(this.pending[redirectedUrl]);
+ }
for (var i=0, l=$p.length, p; (i<l) && (p=$p[i]); i++) {
//if (!err) {
- this.onload(url, p, resource);
+ // If url was redirected, use the redirected location so paths are
+ // calculated relative to that.
+ this.onload(redirectedUrl || url, p, resource);
//}
this.tail();
}
this.pending[url] = null;
+ if ( redirectedUrl && redirectedUrl !== url ) {
+ this.pending[redirectedUrl] = null;
+ }
},
tail: function() {
--this.inflight;
@@ -10317,8 +10558,17 @@ window.HTMLImports = window.HTMLImports || {flags:{}};
request.open('GET', url, xhr.async);
request.addEventListener('readystatechange', function(e) {
if (request.readyState === 4) {
+ // Servers redirecting an import can add a Location header to help us
+ // polyfill correctly.
+ var locationHeader = request.getResponseHeader("Location");
+ var redirectedUrl = null;
+ if (locationHeader) {
+ var redirectedUrl = (locationHeader.substr( 0, 1 ) === "/")
+ ? location.origin + locationHeader // Location is a relative path
+ : redirectedUrl; // Full path
+ }
next.call(nextContext, !xhr.ok(request) && request,
- request.response || request.responseText, url);
+ request.response || request.responseText, redirectedUrl);
}
});
request.send();
@@ -10392,9 +10642,14 @@ var importParser = {
fn.call(this, elt);
}
},
- // only 1 element may be parsed at a time; parsing is async so, each
+ // 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;
@@ -10406,16 +10661,31 @@ var importParser = {
}
this.parsingElement = null;
flags.parse && console.log('completed', elt);
- this.parseNext();
+ },
+ invalidateParse: function(doc) {
+ if (doc && doc.__importLink) {
+ doc.__importParsed = doc.__importLink.__importParsed = false;
+ this.parseSoon();
+ }
+ },
+ parseSoon: function() {
+ if (this._parseSoon) {
+ cancelAnimationFrame(this._parseDelay);
+ }
+ var parser = this;
+ this._parseSoon = requestAnimationFrame(function() {
+ parser.parseNext();
+ });
},
parseImport: function(elt) {
- elt.import.__importParsed = true;
// TODO(sorvell): consider if there's a better way to do this;
// expose an imports parsing hook; this is needed, for example, by the
// CustomElements polyfill.
if (HTMLImports.__importsParsingHook) {
HTMLImports.__importsParsingHook(elt);
}
+ elt.import.__importParsed = true;
+ this.markParsingComplete(elt);
// fire load event
if (elt.__resource) {
elt.dispatchEvent(new CustomEvent('load', {bubbles: false}));
@@ -10433,7 +10703,7 @@ var importParser = {
}
}
}
- this.markParsingComplete(elt);
+ this.parseNext();
},
parseLink: function(linkElt) {
if (nodeIsImport(linkElt)) {
@@ -10463,6 +10733,7 @@ var importParser = {
callback(e);
}
self.markParsingComplete(elt);
+ self.parseNext();
};
elt.addEventListener('load', done);
elt.addEventListener('error', done);
@@ -10934,6 +11205,7 @@ license that can be found in the LICENSE file.
var IMPORT_LINK_TYPE = scope.IMPORT_LINK_TYPE;
var importSelector = 'link[rel=' + IMPORT_LINK_TYPE + ']';
var importer = scope.importer;
+var parser = scope.parser;
// we track mutations for addedNodes, looking for imports
function handler(mutations) {
@@ -10946,7 +11218,9 @@ function handler(mutations) {
// find loadable elements and add them to the importer
function addedNodes(nodes) {
+ var owner;
for (var i=0, l=nodes.length, n; (i<l) && (n=nodes[i]); i++) {
+ owner = owner || n.ownerDocument;
if (shouldLoadNode(n)) {
importer.loadNode(n);
}
@@ -10954,6 +11228,14 @@ function addedNodes(nodes) {
addedNodes(n.children);
}
}
+ // TODO(sorvell): This is not the right approach here. We shouldn't need to
+ // invalidate parsing when an element is added. Disabling this code
+ // until a better approach is found.
+ /*
+ if (owner) {
+ parser.invalidateParse(owner);
+ }
+ */
}
function shouldLoadNode(node) {
@@ -11418,12 +11700,9 @@ var flags = scope.flags;
// native document.registerElement?
var hasNative = Boolean(document.registerElement);
-// TODO(sorvell): See https://github.com/Polymer/polymer/issues/399
-// we'll address this by defaulting to CE polyfill in the presence of the SD
-// polyfill. This will avoid spamming excess attached/detached callbacks.
-// If there is a compelling need to run CE native with SD polyfill,
-// we'll need to fix this issue.
-var useNative = !flags.register && hasNative && !window.ShadowDOMPolyfill;
+// For consistent timing, use native custom elements only when not polyfilling
+// other key related web components features.
+var useNative = !flags.register && hasNative && !window.ShadowDOMPolyfill && (!window.HTMLImports || HTMLImports.useNative);
if (useNative) {
@@ -11713,6 +11992,7 @@ if (useNative) {
// https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/custom/
// index.html#dfn-attribute-changed-callback
function changeAttribute(name, value, operation) {
+ name = name.toLowerCase();
var oldValue = this.getAttribute(name);
operation.apply(this, arguments);
var newValue = this.getAttribute(name);
@@ -13193,9 +13473,6 @@ scope.styleResolver = styleResolver;
};
},
- // TODO(rafaelw): Assigning .bindingDelegate always succeeds. It may
- // make sense to issue a warning or even throw if the template is already
- // "activated", since this would be a strange thing to do.
set bindingDelegate(bindingDelegate) {
if (this.delegate_) {
throw Error('Template must be cleared before a new bindingDelegate ' +
« 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