| OLD | NEW |
| 1 if ((!HTMLElement.prototype.createShadowRoot) || | 1 if ((!HTMLElement.prototype.createShadowRoot && |
| 2 !HTMLElement.prototype.webkitCreateShadowRoot) || |
| 2 window.__forceShadowDomPolyfill) { | 3 window.__forceShadowDomPolyfill) { |
| 3 | 4 |
| 4 /* | 5 /* |
| 5 * Copyright 2013 The Polymer Authors. All rights reserved. | 6 * Copyright 2013 The Polymer Authors. All rights reserved. |
| 6 * Use of this source code is governed by a BSD-style | 7 * Use of this source code is governed by a BSD-style |
| 7 * license that can be found in the LICENSE file. | 8 * license that can be found in the LICENSE file. |
| 8 */ | 9 */ |
| 9 (function() { | 10 (function() { |
| 10 // TODO(jmesserly): fix dart:html to use unprefixed name | 11 // TODO(jmesserly): fix dart:html to use unprefixed name |
| 11 if (Element.prototype.webkitCreateShadowRoot) { | 12 if (Element.prototype.webkitCreateShadowRoot) { |
| (...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 717 this.path.setValueFrom(this.object, newValue); | 718 this.path.setValueFrom(this.object, newValue); |
| 718 } | 719 } |
| 719 }); | 720 }); |
| 720 | 721 |
| 721 function CompoundPathObserver(callback, target, token, valueFn) { | 722 function CompoundPathObserver(callback, target, token, valueFn) { |
| 722 Observer.call(this, undefined, callback, target, token); | 723 Observer.call(this, undefined, callback, target, token); |
| 723 this.valueFn = valueFn; | 724 this.valueFn = valueFn; |
| 724 | 725 |
| 725 this.observed = []; | 726 this.observed = []; |
| 726 this.values = []; | 727 this.values = []; |
| 727 this.value = undefined; | |
| 728 this.oldValue = undefined; | |
| 729 this.oldValues = undefined; | |
| 730 this.changeFlags = undefined; | |
| 731 this.started = false; | 728 this.started = false; |
| 732 } | 729 } |
| 733 | 730 |
| 734 CompoundPathObserver.prototype = createObject({ | 731 CompoundPathObserver.prototype = createObject({ |
| 735 __proto__: PathObserver.prototype, | 732 __proto__: PathObserver.prototype, |
| 736 | 733 |
| 737 addPath: function(object, path) { | 734 addPath: function(object, path) { |
| 738 if (this.started) | 735 if (this.started) |
| 739 throw Error('Cannot add more paths once started.'); | 736 throw Error('Cannot add more paths once started.'); |
| 740 | 737 |
| (...skipping 15 matching lines...) Expand all Loading... |
| 756 | 753 |
| 757 var anyChanged = false; | 754 var anyChanged = false; |
| 758 for (var i = 0; i < this.observed.length; i = i+2) { | 755 for (var i = 0; i < this.observed.length; i = i+2) { |
| 759 var path = this.observed[i+1]; | 756 var path = this.observed[i+1]; |
| 760 if (!path) | 757 if (!path) |
| 761 continue; | 758 continue; |
| 762 var object = this.observed[i]; | 759 var object = this.observed[i]; |
| 763 var value = path.getValueFrom(object, this.observedSet); | 760 var value = path.getValueFrom(object, this.observedSet); |
| 764 var oldValue = this.values[i/2]; | 761 var oldValue = this.values[i/2]; |
| 765 if (!areSameValue(value, oldValue)) { | 762 if (!areSameValue(value, oldValue)) { |
| 766 if (!anyChanged && !this.valueFn) { | |
| 767 this.oldValues = this.oldValues || []; | |
| 768 this.changeFlags = this.changeFlags || []; | |
| 769 for (var j = 0; j < this.values.length; j++) { | |
| 770 this.oldValues[j] = this.values[j]; | |
| 771 this.changeFlags[j] = false; | |
| 772 } | |
| 773 } | |
| 774 | |
| 775 if (!this.valueFn) | |
| 776 this.changeFlags[i/2] = true; | |
| 777 | |
| 778 this.values[i/2] = value; | 763 this.values[i/2] = value; |
| 779 anyChanged = true; | 764 anyChanged = true; |
| 780 } | 765 } |
| 781 } | 766 } |
| 782 | 767 |
| 783 if (this.observedSet) | 768 if (this.observedSet) |
| 784 this.observedSet.cleanup(); | 769 this.observedSet.cleanup(); |
| 785 | 770 |
| 786 return anyChanged; | 771 return anyChanged; |
| 787 }, | 772 }, |
| 788 | 773 |
| 789 check: function() { | 774 check: function() { |
| 790 if (!this.getValues()) | 775 if (!this.getValues()) |
| 791 return; | 776 return; |
| 792 | 777 |
| 793 if (this.valueFn) { | 778 this.value = this.valueFn(this.values); |
| 794 this.value = this.valueFn(this.values); | |
| 795 | 779 |
| 796 if (areSameValue(this.value, this.oldValue)) | 780 if (areSameValue(this.value, this.oldValue)) |
| 797 return false; | 781 return false; |
| 798 | 782 |
| 799 this.reportArgs = [this.value, this.oldValue]; | 783 this.reportArgs = [this.value, this.oldValue]; |
| 800 } else { | |
| 801 this.reportArgs = [this.values, this.oldValues, this.changeFlags]; | |
| 802 } | |
| 803 | |
| 804 return true; | 784 return true; |
| 805 }, | 785 }, |
| 806 | 786 |
| 807 sync: function(hard) { | 787 sync: function(hard) { |
| 808 if (hard) { | 788 if (hard) { |
| 809 this.getValues(); | 789 this.getValues(); |
| 810 if (this.valueFn) | 790 this.value = this.valueFn(this.values); |
| 811 this.value = this.valueFn(this.values); | |
| 812 } | 791 } |
| 813 | 792 |
| 814 if (this.valueFn) | 793 this.oldValue = this.value; |
| 815 this.oldValue = this.value; | |
| 816 }, | 794 }, |
| 817 | 795 |
| 818 close: function() { | 796 close: function() { |
| 819 if (this.observed) { | 797 if (this.observed) { |
| 820 for (var i = 0; i < this.observed.length; i = i + 2) { | 798 for (var i = 0; i < this.observed.length; i = i + 2) { |
| 821 var object = this.observed[i]; | 799 var object = this.observed[i]; |
| 822 if (object && typeof object.close === 'function') | 800 if (object && typeof object.close === 'function') |
| 823 object.close(); | 801 object.close(); |
| 824 } | 802 } |
| 825 this.observed = undefined; | 803 this.observed = undefined; |
| (...skipping 2083 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2909 nodesWereAdded(nodes); | 2887 nodesWereAdded(nodes); |
| 2910 | 2888 |
| 2911 return oldChildWrapper; | 2889 return oldChildWrapper; |
| 2912 }, | 2890 }, |
| 2913 | 2891 |
| 2914 /** | 2892 /** |
| 2915 * Called after a node was added. Subclasses override this to invalidate | 2893 * Called after a node was added. Subclasses override this to invalidate |
| 2916 * the renderer as needed. | 2894 * the renderer as needed. |
| 2917 * @private | 2895 * @private |
| 2918 */ | 2896 */ |
| 2919 nodeWasAdded_: function() { | 2897 nodeWasAdded_: function() {}, |
| 2920 for (var child = this.firstChild; child; child = child.nextSibling) { | |
| 2921 child.nodeWasAdded_(); | |
| 2922 } | |
| 2923 }, | |
| 2924 | 2898 |
| 2925 hasChildNodes: function() { | 2899 hasChildNodes: function() { |
| 2926 return this.firstChild === null; | 2900 return this.firstChild === null; |
| 2927 }, | 2901 }, |
| 2928 | 2902 |
| 2929 /** @type {Node} */ | 2903 /** @type {Node} */ |
| 2930 get parentNode() { | 2904 get parentNode() { |
| 2931 // If the parentNode has not been overridden, use the original parentNode. | 2905 // If the parentNode has not been overridden, use the original parentNode. |
| 2932 return this.parentNode_ !== undefined ? | 2906 return this.parentNode_ !== undefined ? |
| 2933 this.parentNode_ : wrap(this.impl.parentNode); | 2907 this.parentNode_ : wrap(this.impl.parentNode); |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3236 var GetElementsByInterface = scope.GetElementsByInterface; | 3210 var GetElementsByInterface = scope.GetElementsByInterface; |
| 3237 var Node = scope.wrappers.Node; | 3211 var Node = scope.wrappers.Node; |
| 3238 var ParentNodeInterface = scope.ParentNodeInterface; | 3212 var ParentNodeInterface = scope.ParentNodeInterface; |
| 3239 var SelectorsInterface = scope.SelectorsInterface; | 3213 var SelectorsInterface = scope.SelectorsInterface; |
| 3240 var addWrapNodeListMethod = scope.addWrapNodeListMethod; | 3214 var addWrapNodeListMethod = scope.addWrapNodeListMethod; |
| 3241 var mixin = scope.mixin; | 3215 var mixin = scope.mixin; |
| 3242 var oneOf = scope.oneOf; | 3216 var oneOf = scope.oneOf; |
| 3243 var registerWrapper = scope.registerWrapper; | 3217 var registerWrapper = scope.registerWrapper; |
| 3244 var wrappers = scope.wrappers; | 3218 var wrappers = scope.wrappers; |
| 3245 | 3219 |
| 3220 var shadowRootTable = new WeakMap(); |
| 3246 var OriginalElement = window.Element; | 3221 var OriginalElement = window.Element; |
| 3247 | 3222 |
| 3223 |
| 3248 var matchesName = oneOf(OriginalElement.prototype, [ | 3224 var matchesName = oneOf(OriginalElement.prototype, [ |
| 3249 'matches', | 3225 'matches', |
| 3250 'mozMatchesSelector', | 3226 'mozMatchesSelector', |
| 3251 'msMatchesSelector', | 3227 'msMatchesSelector', |
| 3252 'webkitMatchesSelector', | 3228 'webkitMatchesSelector', |
| 3253 ]); | 3229 ]); |
| 3254 | 3230 |
| 3255 var originalMatches = OriginalElement.prototype[matchesName]; | 3231 var originalMatches = OriginalElement.prototype[matchesName]; |
| 3256 | 3232 |
| 3257 function invalidateRendererBasedOnAttribute(element, name) { | 3233 function invalidateRendererBasedOnAttribute(element, name) { |
| 3258 // Only invalidate if parent node is a shadow host. | 3234 // Only invalidate if parent node is a shadow host. |
| 3259 var p = element.parentNode; | 3235 var p = element.parentNode; |
| 3260 if (!p || !p.shadowRoot) | 3236 if (!p || !p.shadowRoot) |
| 3261 return; | 3237 return; |
| 3262 | 3238 |
| 3263 var renderer = scope.getRendererForHost(p); | 3239 var renderer = scope.getRendererForHost(p); |
| 3264 if (renderer.dependsOnAttribute(name)) | 3240 if (renderer.dependsOnAttribute(name)) |
| 3265 renderer.invalidate(); | 3241 renderer.invalidate(); |
| 3266 } | 3242 } |
| 3267 | 3243 |
| 3268 function Element(node) { | 3244 function Element(node) { |
| 3269 Node.call(this, node); | 3245 Node.call(this, node); |
| 3270 } | 3246 } |
| 3271 Element.prototype = Object.create(Node.prototype); | 3247 Element.prototype = Object.create(Node.prototype); |
| 3272 mixin(Element.prototype, { | 3248 mixin(Element.prototype, { |
| 3273 createShadowRoot: function() { | 3249 createShadowRoot: function() { |
| 3274 var newShadowRoot = new wrappers.ShadowRoot(this); | 3250 var newShadowRoot = new wrappers.ShadowRoot(this); |
| 3275 this.impl.polymerShadowRoot_ = newShadowRoot; | 3251 shadowRootTable.set(this, newShadowRoot); |
| 3276 | 3252 |
| 3277 var renderer = scope.getRendererForHost(this); | 3253 var renderer = scope.getRendererForHost(this); |
| 3278 renderer.invalidate(); | 3254 renderer.invalidate(); |
| 3279 | 3255 |
| 3280 return newShadowRoot; | 3256 return newShadowRoot; |
| 3281 }, | 3257 }, |
| 3282 | 3258 |
| 3283 get shadowRoot() { | 3259 get shadowRoot() { |
| 3284 return this.impl.polymerShadowRoot_ || null; | 3260 return shadowRootTable.get(this) || null; |
| 3285 }, | 3261 }, |
| 3286 | 3262 |
| 3287 setAttribute: function(name, value) { | 3263 setAttribute: function(name, value) { |
| 3288 this.impl.setAttribute(name, value); | 3264 this.impl.setAttribute(name, value); |
| 3289 invalidateRendererBasedOnAttribute(this, name); | 3265 invalidateRendererBasedOnAttribute(this, name); |
| 3290 }, | 3266 }, |
| 3291 | 3267 |
| 3292 removeAttribute: function(name) { | 3268 removeAttribute: function(name) { |
| 3293 this.impl.removeAttribute(name); | 3269 this.impl.removeAttribute(name); |
| 3294 invalidateRendererBasedOnAttribute(this, name); | 3270 invalidateRendererBasedOnAttribute(this, name); |
| (...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3889 if (parentNodeWrapper.firstChild === nodeWrapper) | 3865 if (parentNodeWrapper.firstChild === nodeWrapper) |
| 3890 parentNodeWrapper.firstChild_ = nodeWrapper; | 3866 parentNodeWrapper.firstChild_ = nodeWrapper; |
| 3891 | 3867 |
| 3892 parentNode.removeChild(node); | 3868 parentNode.removeChild(node); |
| 3893 } | 3869 } |
| 3894 | 3870 |
| 3895 var distributedChildNodesTable = new WeakMap(); | 3871 var distributedChildNodesTable = new WeakMap(); |
| 3896 var eventParentsTable = new WeakMap(); | 3872 var eventParentsTable = new WeakMap(); |
| 3897 var insertionParentTable = new WeakMap(); | 3873 var insertionParentTable = new WeakMap(); |
| 3898 var rendererForHostTable = new WeakMap(); | 3874 var rendererForHostTable = new WeakMap(); |
| 3875 var shadowDOMRendererTable = new WeakMap(); |
| 3899 | 3876 |
| 3900 function distributeChildToInsertionPoint(child, insertionPoint) { | 3877 function distributeChildToInsertionPoint(child, insertionPoint) { |
| 3901 getDistributedChildNodes(insertionPoint).push(child); | 3878 getDistributedChildNodes(insertionPoint).push(child); |
| 3902 assignToInsertionPoint(child, insertionPoint); | 3879 assignToInsertionPoint(child, insertionPoint); |
| 3903 | 3880 |
| 3904 var eventParents = eventParentsTable.get(child); | 3881 var eventParents = eventParentsTable.get(child); |
| 3905 if (!eventParents) | 3882 if (!eventParents) |
| 3906 eventParentsTable.set(child, eventParents = []); | 3883 eventParentsTable.set(child, eventParents = []); |
| 3907 eventParents.push(insertionPoint); | 3884 eventParents.push(insertionPoint); |
| 3908 } | 3885 } |
| (...skipping 432 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4341 assignToInsertionPoint(tree, point); // 4.3.2.2. | 4318 assignToInsertionPoint(tree, point); // 4.3.2.2. |
| 4342 continue; // 4.3.2.3. | 4319 continue; // 4.3.2.3. |
| 4343 } | 4320 } |
| 4344 } else { | 4321 } else { |
| 4345 break; // 4.4. | 4322 break; // 4.4. |
| 4346 } | 4323 } |
| 4347 } | 4324 } |
| 4348 }, | 4325 }, |
| 4349 | 4326 |
| 4350 associateNode: function(node) { | 4327 associateNode: function(node) { |
| 4351 node.impl.polymerShadowRenderer_ = this; | 4328 shadowDOMRendererTable.set(node, this); |
| 4352 } | 4329 } |
| 4353 }; | 4330 }; |
| 4354 | 4331 |
| 4355 function isInsertionPoint(node) { | 4332 function isInsertionPoint(node) { |
| 4356 // Should this include <shadow>? | 4333 // Should this include <shadow>? |
| 4357 return node instanceof HTMLContentElement; | 4334 return node instanceof HTMLContentElement; |
| 4358 } | 4335 } |
| 4359 | 4336 |
| 4360 function isActiveInsertionPoint(node) { | 4337 function isActiveInsertionPoint(node) { |
| 4361 // <content> inside another <content> or <shadow> is considered inactive. | 4338 // <content> inside another <content> or <shadow> is considered inactive. |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4400 // - a new shadow root is created | 4377 // - a new shadow root is created |
| 4401 // - a direct child to a content/shadow element is added or removed | 4378 // - a direct child to a content/shadow element is added or removed |
| 4402 // - a sibling to a content/shadow element is added or removed | 4379 // - a sibling to a content/shadow element is added or removed |
| 4403 // - content[select] is changed | 4380 // - content[select] is changed |
| 4404 // - an attribute in a direct child to a host is modified | 4381 // - an attribute in a direct child to a host is modified |
| 4405 | 4382 |
| 4406 /** | 4383 /** |
| 4407 * This gets called when a node was added or removed to it. | 4384 * This gets called when a node was added or removed to it. |
| 4408 */ | 4385 */ |
| 4409 Node.prototype.invalidateShadowRenderer = function(force) { | 4386 Node.prototype.invalidateShadowRenderer = function(force) { |
| 4410 var renderer = this.impl.polymerShadowRenderer_; | 4387 var renderer = shadowDOMRendererTable.get(this); |
| 4411 if (renderer) { | 4388 if (renderer) { |
| 4412 renderer.invalidate(); | 4389 renderer.invalidate(); |
| 4413 return true; | 4390 return true; |
| 4414 } | 4391 } |
| 4415 | 4392 |
| 4416 return false; | 4393 return false; |
| 4417 }; | 4394 }; |
| 4418 | 4395 |
| 4419 HTMLContentElement.prototype.getDistributedNodes = function() { | 4396 HTMLContentElement.prototype.getDistributedNodes = function() { |
| 4420 // TODO(arv): We should only rerender the dirty ancestor renderers (from | 4397 var renderer = shadowDOMRendererTable.get(this); |
| 4421 // the root and down). | 4398 if (renderer) |
| 4422 renderAllPending(); | 4399 renderer.render(); |
| 4423 return getDistributedChildNodes(this); | 4400 return getDistributedChildNodes(this); |
| 4424 }; | 4401 }; |
| 4425 | 4402 |
| 4426 HTMLShadowElement.prototype.nodeWasAdded_ = | 4403 HTMLShadowElement.prototype.nodeWasAdded_ = |
| 4427 HTMLContentElement.prototype.nodeWasAdded_ = function() { | 4404 HTMLContentElement.prototype.nodeWasAdded_ = function() { |
| 4428 // Invalidate old renderer if any. | 4405 // Invalidate old renderer if any. |
| 4429 this.invalidateShadowRenderer(); | 4406 this.invalidateShadowRenderer(); |
| 4430 | 4407 |
| 4431 var shadowRoot = getShadowRootAncestor(this); | 4408 var shadowRoot = getShadowRootAncestor(this); |
| 4432 var renderer; | 4409 var renderer; |
| 4433 if (shadowRoot) | 4410 if (shadowRoot) |
| 4434 renderer = getRendererForShadowRoot(shadowRoot); | 4411 renderer = getRendererForShadowRoot(shadowRoot); |
| 4435 this.impl.polymerShadowRenderer_ = renderer; | 4412 shadowDOMRendererTable.set(this, renderer); |
| 4436 if (renderer) | 4413 if (renderer) |
| 4437 renderer.invalidate(); | 4414 renderer.invalidate(); |
| 4438 }; | 4415 }; |
| 4439 | 4416 |
| 4440 scope.eventParentsTable = eventParentsTable; | 4417 scope.eventParentsTable = eventParentsTable; |
| 4441 scope.getRendererForHost = getRendererForHost; | 4418 scope.getRendererForHost = getRendererForHost; |
| 4442 scope.getShadowTrees = getShadowTrees; | 4419 scope.getShadowTrees = getShadowTrees; |
| 4443 scope.insertionParentTable = insertionParentTable; | 4420 scope.insertionParentTable = insertionParentTable; |
| 4444 scope.renderAllPending = renderAllPending; | 4421 scope.renderAllPending = renderAllPending; |
| 4445 | 4422 |
| (...skipping 705 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5151 | 5128 |
| 5152 // TODO(jmesserly): we need to wrap document somehow (a dart:html hook?) | 5129 // TODO(jmesserly): we need to wrap document somehow (a dart:html hook?) |
| 5153 window.dartExperimentalFixupGetTag = function(originalGetTag) { | 5130 window.dartExperimentalFixupGetTag = function(originalGetTag) { |
| 5154 var NodeList = ShadowDOMPolyfill.wrappers.NodeList; | 5131 var NodeList = ShadowDOMPolyfill.wrappers.NodeList; |
| 5155 var ShadowRoot = ShadowDOMPolyfill.wrappers.ShadowRoot; | 5132 var ShadowRoot = ShadowDOMPolyfill.wrappers.ShadowRoot; |
| 5156 var unwrapIfNeeded = ShadowDOMPolyfill.unwrapIfNeeded; | 5133 var unwrapIfNeeded = ShadowDOMPolyfill.unwrapIfNeeded; |
| 5157 function getTag(obj) { | 5134 function getTag(obj) { |
| 5158 // TODO(jmesserly): do we still need these? | 5135 // TODO(jmesserly): do we still need these? |
| 5159 if (obj instanceof NodeList) return 'NodeList'; | 5136 if (obj instanceof NodeList) return 'NodeList'; |
| 5160 if (obj instanceof ShadowRoot) return 'ShadowRoot'; | 5137 if (obj instanceof ShadowRoot) return 'ShadowRoot'; |
| 5161 if (window.MutationRecord && (obj instanceof MutationRecord)) | 5138 if (obj instanceof MutationRecord) return 'MutationRecord'; |
| 5162 return 'MutationRecord'; | 5139 if (obj instanceof MutationObserver) return 'MutationObserver'; |
| 5163 if (window.MutationObserver && (obj instanceof MutationObserver)) | |
| 5164 return 'MutationObserver'; | |
| 5165 | 5140 |
| 5166 var unwrapped = unwrapIfNeeded(obj); | 5141 var unwrapped = unwrapIfNeeded(obj); |
| 5167 if (obj !== unwrapped) { | 5142 if (obj !== unwrapped) { |
| 5168 // Fix up class names for Firefox. | 5143 // Fix up class names for Firefox. |
| 5169 // For some of them (like HTMLFormElement and HTMLInputElement), | 5144 // For some of them (like HTMLFormElement and HTMLInputElement), |
| 5170 // the "constructor" property of the unwrapped nodes points at the | 5145 // the "constructor" property of the unwrapped nodes points at the |
| 5171 // same constructor as the wrapper. | 5146 // same constructor as the wrapper. |
| 5172 var ctor = obj.constructor | 5147 var ctor = obj.constructor |
| 5173 if (ctor === unwrapped.constructor) { | 5148 if (ctor === unwrapped.constructor) { |
| 5174 var name = ctor._ShadowDOMPolyfill$cacheTag_; | 5149 var name = ctor._ShadowDOMPolyfill$cacheTag_; |
| (...skipping 532 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5707 css.push(cssRules[i].cssText); | 5682 css.push(cssRules[i].cssText); |
| 5708 } | 5683 } |
| 5709 return css.join('\n\n'); | 5684 return css.join('\n\n'); |
| 5710 } | 5685 } |
| 5711 | 5686 |
| 5712 // exports | 5687 // exports |
| 5713 scope.ShadowCSS.shimShadowDOMStyling2 = shimShadowDOMStyling2; | 5688 scope.ShadowCSS.shimShadowDOMStyling2 = shimShadowDOMStyling2; |
| 5714 })(window.Platform); | 5689 })(window.Platform); |
| 5715 | 5690 |
| 5716 } | 5691 } |
| OLD | NEW |