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