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

Side by Side Diff: dart/pkg/shadow_dom/lib/shadow_dom.debug.js

Issue 59073003: Version 0.8.10.4 (Closed) Base URL: http://dart.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 1 month 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 if (!HTMLElement.prototype.createShadowRoot 1 if (!HTMLElement.prototype.createShadowRoot
2 || window.__forceShadowDomPolyfill) { 2 || window.__forceShadowDomPolyfill) {
3 3
4 /* 4 /*
5 * Copyright 2013 The Polymer Authors. All rights reserved. 5 * Copyright 2013 The Polymer Authors. All rights reserved.
6 * Use of this source code is governed by a BSD-style 6 * Use of this source code is governed by a BSD-style
7 * license that can be found in the LICENSE file. 7 * license that can be found in the LICENSE file.
8 */ 8 */
9 (function() { 9 (function() {
10 // TODO(jmesserly): fix dart:html to use unprefixed name 10 // TODO(jmesserly): fix dart:html to use unprefixed name
(...skipping 1866 matching lines...) Expand 10 before | Expand all | Expand 10 after
1877 return node.parentNode || (dv = node.defaultView) && wrap(dv) || null; 1877 return node.parentNode || (dv = node.defaultView) && wrap(dv) || null;
1878 } 1878 }
1879 1879
1880 // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#df n-adjusted-parent 1880 // https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#df n-adjusted-parent
1881 function calculateParents(node, context, ancestors) { 1881 function calculateParents(node, context, ancestors) {
1882 if (ancestors.length) 1882 if (ancestors.length)
1883 return ancestors.shift(); 1883 return ancestors.shift();
1884 1884
1885 // 1. 1885 // 1.
1886 if (isShadowRoot(node)) 1886 if (isShadowRoot(node))
1887 return getInsertionParent(node) || scope.getHostForShadowRoot(node); 1887 return getInsertionParent(node) || node.host;
1888 1888
1889 // 2. 1889 // 2.
1890 var eventParents = scope.eventParentsTable.get(node); 1890 var eventParents = scope.eventParentsTable.get(node);
1891 if (eventParents) { 1891 if (eventParents) {
1892 // Copy over the remaining event parents for next iteration. 1892 // Copy over the remaining event parents for next iteration.
1893 for (var i = 1; i < eventParents.length; i++) { 1893 for (var i = 1; i < eventParents.length; i++) {
1894 ancestors[i - 1] = eventParents[i]; 1894 ancestors[i - 1] = eventParents[i];
1895 } 1895 }
1896 return eventParents[0]; 1896 return eventParents[0];
1897 } 1897 }
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1973 if (inSameTree(ancestor, target)) // 3.4.4. 1973 if (inSameTree(ancestor, target)) // 3.4.4.
1974 return stack[stack.length - 1]; 1974 return stack[stack.length - 1];
1975 1975
1976 if (isShadowRoot(ancestor)) // 3.4.5. 1976 if (isShadowRoot(ancestor)) // 3.4.5.
1977 stack.pop(); 1977 stack.pop();
1978 1978
1979 last = ancestor; // 3.4.6. 1979 last = ancestor; // 3.4.6.
1980 ancestor = calculateParents(ancestor, context, ancestors); // 3.4.7. 1980 ancestor = calculateParents(ancestor, context, ancestors); // 3.4.7.
1981 } 1981 }
1982 if (isShadowRoot(target)) // 3.5. 1982 if (isShadowRoot(target)) // 3.5.
1983 target = scope.getHostForShadowRoot(target); 1983 target = target.host;
1984 else 1984 else
1985 target = target.parentNode; // 3.6. 1985 target = target.parentNode; // 3.6.
1986 } 1986 }
1987 } 1987 }
1988 1988
1989 function getInsertionParent(node) { 1989 function getInsertionParent(node) {
1990 return scope.insertionParentTable.get(node); 1990 return scope.insertionParentTable.get(node);
1991 } 1991 }
1992 1992
1993 function isDistributed(node) { 1993 function isDistributed(node) {
1994 return getInsertionParent(node); 1994 return getInsertionParent(node);
1995 } 1995 }
1996 1996
1997 function rootOfNode(node) { 1997 function rootOfNode(node) {
1998 var p; 1998 var p;
1999 while (p = node.parentNode) { 1999 while (p = node.parentNode) {
2000 node = p; 2000 node = p;
2001 } 2001 }
2002 return node; 2002 return node;
2003 } 2003 }
2004 2004
2005 function inSameTree(a, b) { 2005 function inSameTree(a, b) {
2006 return rootOfNode(a) === rootOfNode(b); 2006 return rootOfNode(a) === rootOfNode(b);
2007 } 2007 }
2008 2008
2009 function enclosedBy(a, b) { 2009 function enclosedBy(a, b) {
2010 if (a === b) 2010 if (a === b)
2011 return true; 2011 return true;
2012 if (a instanceof wrappers.ShadowRoot) { 2012 if (a instanceof wrappers.ShadowRoot)
2013 var host = scope.getHostForShadowRoot(a); 2013 return enclosedBy(rootOfNode(a.host), b);
2014 return enclosedBy(rootOfNode(host), b);
2015 }
2016 return false; 2014 return false;
2017 } 2015 }
2018 2016
2019 var mutationEventsAreSilenced = 0; 2017 var mutationEventsAreSilenced = 0;
2020 2018
2021 function muteMutationEvents() { 2019 function muteMutationEvents() {
2022 mutationEventsAreSilenced++; 2020 mutationEventsAreSilenced++;
2023 } 2021 }
2024 2022
2025 function unmuteMutationEvents() { 2023 function unmuteMutationEvents() {
(...skipping 401 matching lines...) Expand 10 before | Expand all | Expand 10 after
2427 2425
2428 [Node, Window].forEach(function(constructor) { 2426 [Node, Window].forEach(function(constructor) {
2429 var p = constructor.prototype; 2427 var p = constructor.prototype;
2430 methodNames.forEach(function(name) { 2428 methodNames.forEach(function(name) {
2431 Object.defineProperty(p, name + '_', {value: p[name]}); 2429 Object.defineProperty(p, name + '_', {value: p[name]});
2432 }); 2430 });
2433 }); 2431 });
2434 2432
2435 function getTargetToListenAt(wrapper) { 2433 function getTargetToListenAt(wrapper) {
2436 if (wrapper instanceof wrappers.ShadowRoot) 2434 if (wrapper instanceof wrappers.ShadowRoot)
2437 wrapper = scope.getHostForShadowRoot(wrapper); 2435 wrapper = wrapper.host;
2438 return unwrap(wrapper); 2436 return unwrap(wrapper);
2439 } 2437 }
2440 2438
2441 EventTarget.prototype = { 2439 EventTarget.prototype = {
2442 addEventListener: function(type, fun, capture) { 2440 addEventListener: function(type, fun, capture) {
2443 if (!isValidListener(fun)) 2441 if (!isValidListener(fun))
2444 return; 2442 return;
2445 2443
2446 var listener = new Listener(type, fun, capture); 2444 var listener = new Listener(type, fun, capture);
2447 var listeners = listenersTable.get(this); 2445 var listeners = listenersTable.get(this);
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
2664 node.previousSibling_ = previousNode; 2662 node.previousSibling_ = previousNode;
2665 node.nextSibling_ = nextNode; 2663 node.nextSibling_ = nextNode;
2666 if (previousNode) 2664 if (previousNode)
2667 previousNode.nextSibling_ = node; 2665 previousNode.nextSibling_ = node;
2668 if (nextNode) 2666 if (nextNode)
2669 nextNode.previousSibling_ = node; 2667 nextNode.previousSibling_ = node;
2670 return [node]; 2668 return [node];
2671 } 2669 }
2672 2670
2673 var nodes = []; 2671 var nodes = [];
2674 var firstChild; 2672 for (var child = node.firstChild; child; child = child.nextSibling) {
2675 while (firstChild = node.firstChild) { 2673 nodes.push(child);
2676 node.removeChild(firstChild); 2674 }
2677 nodes.push(firstChild); 2675
2678 firstChild.parentNode_ = parentNode; 2676 for (var i = nodes.length - 1; i >= 0; i--) {
2677 node.removeChild(nodes[i]);
2678 nodes[i].parentNode_ = parentNode;
2679 } 2679 }
2680 2680
2681 for (var i = 0; i < nodes.length; i++) { 2681 for (var i = 0; i < nodes.length; i++) {
2682 nodes[i].previousSibling_ = nodes[i - 1] || previousNode; 2682 nodes[i].previousSibling_ = nodes[i - 1] || previousNode;
2683 nodes[i].nextSibling_ = nodes[i + 1] || nextNode; 2683 nodes[i].nextSibling_ = nodes[i + 1] || nextNode;
2684 } 2684 }
2685 2685
2686 if (previousNode) 2686 if (previousNode)
2687 previousNode.nextSibling_ = nodes[0]; 2687 previousNode.nextSibling_ = nodes[0];
2688 if (nextNode) 2688 if (nextNode)
(...skipping 129 matching lines...) Expand 10 before | Expand all | Expand 10 after
2818 */ 2818 */
2819 this.nextSibling_ = undefined; 2819 this.nextSibling_ = undefined;
2820 2820
2821 /** 2821 /**
2822 * @type {Node|undefined} 2822 * @type {Node|undefined}
2823 * @private 2823 * @private
2824 */ 2824 */
2825 this.previousSibling_ = undefined; 2825 this.previousSibling_ = undefined;
2826 }; 2826 };
2827 2827
2828 var OriginalDocumentFragment = window.DocumentFragment;
2828 var originalAppendChild = OriginalNode.prototype.appendChild; 2829 var originalAppendChild = OriginalNode.prototype.appendChild;
2829 var originalInsertBefore = OriginalNode.prototype.insertBefore;
2830 var originalReplaceChild = OriginalNode.prototype.replaceChild;
2831 var originalRemoveChild = OriginalNode.prototype.removeChild;
2832 var originalCompareDocumentPosition = 2830 var originalCompareDocumentPosition =
2833 OriginalNode.prototype.compareDocumentPosition; 2831 OriginalNode.prototype.compareDocumentPosition;
2832 var originalInsertBefore = OriginalNode.prototype.insertBefore;
2833 var originalRemoveChild = OriginalNode.prototype.removeChild;
2834 var originalReplaceChild = OriginalNode.prototype.replaceChild;
2835
2836 var isIe = /Trident/.test(navigator.userAgent);
2837
2838 var removeChildOriginalHelper = isIe ?
2839 function(parent, child) {
2840 try {
2841 originalRemoveChild.call(parent, child);
2842 } catch (ex) {
2843 if (!(parent instanceof OriginalDocumentFragment))
2844 throw ex;
2845 }
2846 } :
2847 function(parent, child) {
2848 originalRemoveChild.call(parent, child);
2849 };
2834 2850
2835 Node.prototype = Object.create(EventTarget.prototype); 2851 Node.prototype = Object.create(EventTarget.prototype);
2836 mixin(Node.prototype, { 2852 mixin(Node.prototype, {
2837 appendChild: function(childWrapper) { 2853 appendChild: function(childWrapper) {
2838 assertIsNodeWrapper(childWrapper); 2854 assertIsNodeWrapper(childWrapper);
2839 2855
2840 var nodes; 2856 var nodes;
2841 2857
2842 if (this.invalidateShadowRenderer() || invalidateParent(childWrapper)) { 2858 if (this.invalidateShadowRenderer() || invalidateParent(childWrapper)) {
2843 var previousNode = this.lastChild; 2859 var previousNode = this.lastChild;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2899 } 2915 }
2900 2916
2901 nodesWereAdded(nodes); 2917 nodesWereAdded(nodes);
2902 2918
2903 return childWrapper; 2919 return childWrapper;
2904 }, 2920 },
2905 2921
2906 removeChild: function(childWrapper) { 2922 removeChild: function(childWrapper) {
2907 assertIsNodeWrapper(childWrapper); 2923 assertIsNodeWrapper(childWrapper);
2908 if (childWrapper.parentNode !== this) { 2924 if (childWrapper.parentNode !== this) {
2909 // TODO(arv): DOMException 2925 // IE has invalid DOM trees at times.
2910 throw new Error('NotFoundError'); 2926 var found = false;
2927 var childNodes = this.childNodes;
2928 for (var ieChild = this.firstChild; ieChild;
2929 ieChild = ieChild.nextSibling) {
2930 if (ieChild === childWrapper) {
2931 found = true;
2932 break;
2933 }
2934 }
2935 if (!found) {
2936 // TODO(arv): DOMException
2937 throw new Error('NotFoundError');
2938 }
2911 } 2939 }
2912 2940
2913 var childNode = unwrap(childWrapper); 2941 var childNode = unwrap(childWrapper);
2914 if (this.invalidateShadowRenderer()) { 2942 if (this.invalidateShadowRenderer()) {
2915 2943
2916 // We need to remove the real node from the DOM before updating the 2944 // We need to remove the real node from the DOM before updating the
2917 // pointers. This is so that that mutation event is dispatched before 2945 // pointers. This is so that that mutation event is dispatched before
2918 // the pointers have changed. 2946 // the pointers have changed.
2919 var thisFirstChild = this.firstChild; 2947 var thisFirstChild = this.firstChild;
2920 var thisLastChild = this.lastChild; 2948 var thisLastChild = this.lastChild;
2921 var childWrapperNextSibling = childWrapper.nextSibling; 2949 var childWrapperNextSibling = childWrapper.nextSibling;
2922 var childWrapperPreviousSibling = childWrapper.previousSibling; 2950 var childWrapperPreviousSibling = childWrapper.previousSibling;
2923 2951
2924 var parentNode = childNode.parentNode; 2952 var parentNode = childNode.parentNode;
2925 if (parentNode) 2953 if (parentNode)
2926 originalRemoveChild.call(parentNode, childNode); 2954 removeChildOriginalHelper(parentNode, childNode);
2927 2955
2928 if (thisFirstChild === childWrapper) 2956 if (thisFirstChild === childWrapper)
2929 this.firstChild_ = childWrapperNextSibling; 2957 this.firstChild_ = childWrapperNextSibling;
2930 if (thisLastChild === childWrapper) 2958 if (thisLastChild === childWrapper)
2931 this.lastChild_ = childWrapperPreviousSibling; 2959 this.lastChild_ = childWrapperPreviousSibling;
2932 if (childWrapperPreviousSibling) 2960 if (childWrapperPreviousSibling)
2933 childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling; 2961 childWrapperPreviousSibling.nextSibling_ = childWrapperNextSibling;
2934 if (childWrapperNextSibling) { 2962 if (childWrapperNextSibling) {
2935 childWrapperNextSibling.previousSibling_ = 2963 childWrapperNextSibling.previousSibling_ =
2936 childWrapperPreviousSibling; 2964 childWrapperPreviousSibling;
2937 } 2965 }
2938 2966
2939 childWrapper.previousSibling_ = childWrapper.nextSibling_ = 2967 childWrapper.previousSibling_ = childWrapper.nextSibling_ =
2940 childWrapper.parentNode_ = undefined; 2968 childWrapper.parentNode_ = undefined;
2941 } else { 2969 } else {
2942 originalRemoveChild.call(this.impl, childNode); 2970 removeChildOriginalHelper(this.impl, childNode);
2943 } 2971 }
2944 2972
2945 return childWrapper; 2973 return childWrapper;
2946 }, 2974 },
2947 2975
2948 replaceChild: function(newChildWrapper, oldChildWrapper) { 2976 replaceChild: function(newChildWrapper, oldChildWrapper) {
2949 assertIsNodeWrapper(newChildWrapper); 2977 assertIsNodeWrapper(newChildWrapper);
2950 assertIsNodeWrapper(oldChildWrapper); 2978 assertIsNodeWrapper(oldChildWrapper);
2951 2979
2952 if (oldChildWrapper.parentNode !== this) { 2980 if (oldChildWrapper.parentNode !== this) {
(...skipping 766 matching lines...) Expand 10 before | Expand all | Expand 10 after
3719 registerWrapper(OriginalHTMLImageElement, HTMLImageElement, 3747 registerWrapper(OriginalHTMLImageElement, HTMLImageElement,
3720 document.createElement('img')); 3748 document.createElement('img'));
3721 3749
3722 function Image(width, height) { 3750 function Image(width, height) {
3723 if (!(this instanceof Image)) { 3751 if (!(this instanceof Image)) {
3724 throw new TypeError( 3752 throw new TypeError(
3725 'DOM object constructor cannot be called as a function.'); 3753 'DOM object constructor cannot be called as a function.');
3726 } 3754 }
3727 3755
3728 var node = unwrap(document.createElement('img')); 3756 var node = unwrap(document.createElement('img'));
3757 HTMLElement.call(this, node);
3758 rewrap(node, this);
3759
3729 if (width !== undefined) 3760 if (width !== undefined)
3730 node.width = width; 3761 node.width = width;
3731 if (height !== undefined) 3762 if (height !== undefined)
3732 node.height = height; 3763 node.height = height;
3733 HTMLElement.call(this, node);
3734 rewrap(node, this);
3735 } 3764 }
3736 3765
3737 Image.prototype = HTMLImageElement.prototype; 3766 Image.prototype = HTMLImageElement.prototype;
3738 3767
3739 scope.wrappers.HTMLImageElement = HTMLImageElement; 3768 scope.wrappers.HTMLImageElement = HTMLImageElement;
3740 scope.wrappers.Image = Image; 3769 scope.wrappers.Image = Image;
3741 })(this.ShadowDOMPolyfill); 3770 })(this.ShadowDOMPolyfill);
3742 3771
3743 // Copyright 2013 The Polymer Authors. All rights reserved. 3772 // Copyright 2013 The Polymer Authors. All rights reserved.
3744 // Use of this source code is goverened by a BSD-style 3773 // Use of this source code is goverened by a BSD-style
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after
3851 3880
3852 scope.wrappers.HTMLTemplateElement = HTMLTemplateElement; 3881 scope.wrappers.HTMLTemplateElement = HTMLTemplateElement;
3853 })(this.ShadowDOMPolyfill); 3882 })(this.ShadowDOMPolyfill);
3854 // Copyright 2013 The Polymer Authors. All rights reserved. 3883 // Copyright 2013 The Polymer Authors. All rights reserved.
3855 // Use of this source code is goverened by a BSD-style 3884 // Use of this source code is goverened by a BSD-style
3856 // license that can be found in the LICENSE file. 3885 // license that can be found in the LICENSE file.
3857 3886
3858 (function(scope) { 3887 (function(scope) {
3859 'use strict'; 3888 'use strict';
3860 3889
3890 var HTMLElement = scope.wrappers.HTMLElement;
3891 var registerWrapper = scope.registerWrapper;
3892
3893 var OriginalHTMLMediaElement = window.HTMLMediaElement;
3894
3895 function HTMLMediaElement(node) {
3896 HTMLElement.call(this, node);
3897 }
3898 HTMLMediaElement.prototype = Object.create(HTMLElement.prototype);
3899
3900 registerWrapper(OriginalHTMLMediaElement, HTMLMediaElement,
3901 document.createElement('audio'));
3902
3903 scope.wrappers.HTMLMediaElement = HTMLMediaElement;
3904 })(this.ShadowDOMPolyfill);
3905
3906 // Copyright 2013 The Polymer Authors. All rights reserved.
3907 // Use of this source code is goverened by a BSD-style
3908 // license that can be found in the LICENSE file.
3909
3910 (function(scope) {
3911 'use strict';
3912
3913 var HTMLMediaElement = scope.wrappers.HTMLMediaElement;
3914 var registerWrapper = scope.registerWrapper;
3915 var unwrap = scope.unwrap;
3916 var rewrap = scope.rewrap;
3917
3918 var OriginalHTMLAudioElement = window.HTMLAudioElement;
3919
3920 function HTMLAudioElement(node) {
3921 HTMLMediaElement.call(this, node);
3922 }
3923 HTMLAudioElement.prototype = Object.create(HTMLMediaElement.prototype);
3924
3925 registerWrapper(OriginalHTMLAudioElement, HTMLAudioElement,
3926 document.createElement('audio'));
3927
3928 function Audio(src) {
3929 if (!(this instanceof Audio)) {
3930 throw new TypeError(
3931 'DOM object constructor cannot be called as a function.');
3932 }
3933
3934 var node = unwrap(document.createElement('audio'));
3935 HTMLMediaElement.call(this, node);
3936 rewrap(node, this);
3937
3938 node.setAttribute('preload', 'auto');
3939 if (src !== undefined)
3940 node.setAttribute('src', src);
3941 }
3942
3943 Audio.prototype = HTMLAudioElement.prototype;
3944
3945 scope.wrappers.HTMLAudioElement = HTMLAudioElement;
3946 scope.wrappers.Audio = Audio;
3947 })(this.ShadowDOMPolyfill);
3948
3949 // Copyright 2013 The Polymer Authors. All rights reserved.
3950 // Use of this source code is goverened by a BSD-style
3951 // license that can be found in the LICENSE file.
3952
3953 (function(scope) {
3954 'use strict';
3955
3956 var HTMLElement = scope.wrappers.HTMLElement;
3957 var mixin = scope.mixin;
3958 var registerWrapper = scope.registerWrapper;
3959 var rewrap = scope.rewrap;
3960 var unwrap = scope.unwrap;
3961 var wrap = scope.wrap;
3962
3963 var OriginalHTMLOptionElement = window.HTMLOptionElement;
3964
3965 function trimText(s) {
3966 return s.replace(/\s+/g, ' ').trim();
3967 }
3968
3969 function HTMLOptionElement(node) {
3970 HTMLElement.call(this, node);
3971 }
3972 HTMLOptionElement.prototype = Object.create(HTMLElement.prototype);
3973 mixin(HTMLOptionElement.prototype, {
3974 get text() {
3975 return trimText(this.textContent);
3976 },
3977 set text(value) {
3978 this.textContent = trimText(String(value));
3979 },
3980 get form() {
3981 return wrap(unwrap(this).form);
3982 }
3983 });
3984
3985 registerWrapper(OriginalHTMLOptionElement, HTMLOptionElement,
3986 document.createElement('option'));
3987
3988 function Option(text, value, defaultSelected, selected) {
3989 if (!(this instanceof Option)) {
3990 throw new TypeError(
3991 'DOM object constructor cannot be called as a function.');
3992 }
3993
3994 var node = unwrap(document.createElement('option'));
3995 HTMLElement.call(this, node);
3996 rewrap(node, this);
3997
3998 if (text !== undefined)
3999 node.text = text;
4000 if (value !== undefined)
4001 node.setAttribute('value', value);
4002 if (defaultSelected === true)
4003 node.setAttribute('selected', '');
4004 node.selected = selected === true;
4005 }
4006
4007 Option.prototype = HTMLOptionElement.prototype;
4008
4009 scope.wrappers.HTMLOptionElement = HTMLOptionElement;
4010 scope.wrappers.Option = Option;
4011 })(this.ShadowDOMPolyfill);
4012
4013 // Copyright 2013 The Polymer Authors. All rights reserved.
4014 // Use of this source code is goverened by a BSD-style
4015 // license that can be found in the LICENSE file.
4016
4017 (function(scope) {
4018 'use strict';
4019
3861 var HTMLContentElement = scope.wrappers.HTMLContentElement; 4020 var HTMLContentElement = scope.wrappers.HTMLContentElement;
3862 var HTMLElement = scope.wrappers.HTMLElement; 4021 var HTMLElement = scope.wrappers.HTMLElement;
3863 var HTMLShadowElement = scope.wrappers.HTMLShadowElement; 4022 var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
3864 var HTMLTemplateElement = scope.wrappers.HTMLTemplateElement; 4023 var HTMLTemplateElement = scope.wrappers.HTMLTemplateElement;
3865 var mixin = scope.mixin; 4024 var mixin = scope.mixin;
3866 var registerWrapper = scope.registerWrapper; 4025 var registerWrapper = scope.registerWrapper;
3867 4026
3868 var OriginalHTMLUnknownElement = window.HTMLUnknownElement; 4027 var OriginalHTMLUnknownElement = window.HTMLUnknownElement;
3869 4028
3870 function HTMLUnknownElement(node) { 4029 function HTMLUnknownElement(node) {
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
4030 }, 4189 },
4031 set innerHTML(value) { 4190 set innerHTML(value) {
4032 setInnerHTML(this, value); 4191 setInnerHTML(this, value);
4033 this.invalidateShadowRenderer(); 4192 this.invalidateShadowRenderer();
4034 }, 4193 },
4035 4194
4036 get olderShadowRoot() { 4195 get olderShadowRoot() {
4037 return nextOlderShadowTreeTable.get(this) || null; 4196 return nextOlderShadowTreeTable.get(this) || null;
4038 }, 4197 },
4039 4198
4199 get host() {
4200 return shadowHostTable.get(this) || null;
4201 },
4202
4040 invalidateShadowRenderer: function() { 4203 invalidateShadowRenderer: function() {
4041 return shadowHostTable.get(this).invalidateShadowRenderer(); 4204 return shadowHostTable.get(this).invalidateShadowRenderer();
4042 }, 4205 },
4043 4206
4044 elementFromPoint: function(x, y) { 4207 elementFromPoint: function(x, y) {
4045 return elementFromPoint(this, this.ownerDocument, x, y); 4208 return elementFromPoint(this, this.ownerDocument, x, y);
4046 }, 4209 },
4047 4210
4048 getElementById: function(id) { 4211 getElementById: function(id) {
4049 return this.querySelector('#' + id); 4212 return this.querySelector('#' + id);
4050 } 4213 }
4051 }); 4214 });
4052 4215
4053 scope.wrappers.ShadowRoot = ShadowRoot; 4216 scope.wrappers.ShadowRoot = ShadowRoot;
4054 scope.getHostForShadowRoot = function(node) {
4055 return shadowHostTable.get(node);
4056 };
4057 })(this.ShadowDOMPolyfill); 4217 })(this.ShadowDOMPolyfill);
4058 // Copyright 2013 The Polymer Authors. All rights reserved. 4218 // Copyright 2013 The Polymer Authors. All rights reserved.
4059 // Use of this source code is governed by a BSD-style 4219 // Use of this source code is governed by a BSD-style
4060 // license that can be found in the LICENSE file. 4220 // license that can be found in the LICENSE file.
4061 4221
4062 (function(scope) { 4222 (function(scope) {
4063 'use strict'; 4223 'use strict';
4064 4224
4065 var Element = scope.wrappers.Element; 4225 var Element = scope.wrappers.Element;
4066 var HTMLContentElement = scope.wrappers.HTMLContentElement; 4226 var HTMLContentElement = scope.wrappers.HTMLContentElement;
4067 var HTMLShadowElement = scope.wrappers.HTMLShadowElement; 4227 var HTMLShadowElement = scope.wrappers.HTMLShadowElement;
4068 var Node = scope.wrappers.Node; 4228 var Node = scope.wrappers.Node;
4069 var ShadowRoot = scope.wrappers.ShadowRoot; 4229 var ShadowRoot = scope.wrappers.ShadowRoot;
4070 var assert = scope.assert; 4230 var assert = scope.assert;
4071 var getHostForShadowRoot = scope.getHostForShadowRoot;
4072 var mixin = scope.mixin; 4231 var mixin = scope.mixin;
4073 var muteMutationEvents = scope.muteMutationEvents; 4232 var muteMutationEvents = scope.muteMutationEvents;
4074 var oneOf = scope.oneOf; 4233 var oneOf = scope.oneOf;
4075 var unmuteMutationEvents = scope.unmuteMutationEvents; 4234 var unmuteMutationEvents = scope.unmuteMutationEvents;
4076 var unwrap = scope.unwrap; 4235 var unwrap = scope.unwrap;
4077 var wrap = scope.wrap; 4236 var wrap = scope.wrap;
4078 4237
4079 /** 4238 /**
4080 * Updates the fields of a wrapper to a snapshot of the logical DOM as needed. 4239 * Updates the fields of a wrapper to a snapshot of the logical DOM as needed.
4081 * Up means parentNode 4240 * Up means parentNode
(...skipping 221 matching lines...) Expand 10 before | Expand all | Expand 10 after
4303 4462
4304 function getShadowRootAncestor(node) { 4463 function getShadowRootAncestor(node) {
4305 for (; node; node = node.parentNode) { 4464 for (; node; node = node.parentNode) {
4306 if (node instanceof ShadowRoot) 4465 if (node instanceof ShadowRoot)
4307 return node; 4466 return node;
4308 } 4467 }
4309 return null; 4468 return null;
4310 } 4469 }
4311 4470
4312 function getRendererForShadowRoot(shadowRoot) { 4471 function getRendererForShadowRoot(shadowRoot) {
4313 return getRendererForHost(getHostForShadowRoot(shadowRoot)); 4472 return getRendererForHost(shadowRoot.host);
4314 } 4473 }
4315 4474
4316 var spliceDiff = new ArraySplice(); 4475 var spliceDiff = new ArraySplice();
4317 spliceDiff.equals = function(renderNode, rawNode) { 4476 spliceDiff.equals = function(renderNode, rawNode) {
4318 return unwrap(renderNode.node) === rawNode; 4477 return unwrap(renderNode.node) === rawNode;
4319 }; 4478 };
4320 4479
4321 /** 4480 /**
4322 * RenderNode is used as an in memory "render tree". When we render the 4481 * RenderNode is used as an in memory "render tree". When we render the
4323 * composed tree we create a tree of RenderNodes, then we diff this against 4482 * composed tree we create a tree of RenderNodes, then we diff this against
(...skipping 408 matching lines...) Expand 10 before | Expand all | Expand 10 after
4732 var wrap = scope.wrap; 4891 var wrap = scope.wrap;
4733 4892
4734 var elementsWithFormProperty = [ 4893 var elementsWithFormProperty = [
4735 'HTMLButtonElement', 4894 'HTMLButtonElement',
4736 'HTMLFieldSetElement', 4895 'HTMLFieldSetElement',
4737 'HTMLInputElement', 4896 'HTMLInputElement',
4738 'HTMLKeygenElement', 4897 'HTMLKeygenElement',
4739 'HTMLLabelElement', 4898 'HTMLLabelElement',
4740 'HTMLLegendElement', 4899 'HTMLLegendElement',
4741 'HTMLObjectElement', 4900 'HTMLObjectElement',
4742 'HTMLOptionElement', 4901 // HTMLOptionElement is handled in HTMLOptionElement.js
4743 'HTMLOutputElement', 4902 'HTMLOutputElement',
4744 'HTMLSelectElement', 4903 'HTMLSelectElement',
4745 'HTMLTextAreaElement', 4904 'HTMLTextAreaElement',
4746 ]; 4905 ];
4747 4906
4748 function createWrapperConstructor(name) { 4907 function createWrapperConstructor(name) {
4749 if (!window[name]) 4908 if (!window[name])
4750 return; 4909 return;
4751 4910
4752 // Ensure we are not overriding an already existing constructor. 4911 // Ensure we are not overriding an already existing constructor.
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
4917 'attributeChangedCallback', 5076 'attributeChangedCallback',
4918 ].forEach(function(name) { 5077 ].forEach(function(name) {
4919 var f = prototype[name]; 5078 var f = prototype[name];
4920 if (!f) 5079 if (!f)
4921 return; 5080 return;
4922 newPrototype[name] = function() { 5081 newPrototype[name] = function() {
4923 f.apply(wrap(this), arguments); 5082 f.apply(wrap(this), arguments);
4924 }; 5083 };
4925 }); 5084 });
4926 5085
4927 var nativeConstructor = originalRegister.call(unwrap(this), tagName, 5086 var p = {prototype: newPrototype};
4928 object.extends ? {prototype: newPrototype, extends: object.extends} : 5087 if (object.extends)
4929 {prototype: newPrototype}); 5088 p.extends = object.extends;
5089 var nativeConstructor = originalRegister.call(unwrap(this), tagName, p);
4930 5090
4931 function GeneratedWrapper(node) { 5091 function GeneratedWrapper(node) {
4932 if (!node) 5092 if (!node) {
4933 return document.createElement(tagName); 5093 if (object.extends) {
5094 return document.createElement(object.extends, tagName);
5095 } else {
5096 return document.createElement(tagName);
5097 }
5098 }
4934 this.impl = node; 5099 this.impl = node;
4935 } 5100 }
4936 GeneratedWrapper.prototype = prototype; 5101 GeneratedWrapper.prototype = prototype;
4937 GeneratedWrapper.prototype.constructor = GeneratedWrapper; 5102 GeneratedWrapper.prototype.constructor = GeneratedWrapper;
4938 5103
4939 scope.constructorTable.set(newPrototype, GeneratedWrapper); 5104 scope.constructorTable.set(newPrototype, GeneratedWrapper);
4940 scope.nativePrototypeTable.set(prototype, newPrototype); 5105 scope.nativePrototypeTable.set(prototype, newPrototype);
4941 5106
4942 return GeneratedWrapper; 5107 return GeneratedWrapper;
4943 }; 5108 };
(...skipping 353 matching lines...) Expand 10 before | Expand all | Expand 10 after
5297 'use strict'; 5462 'use strict';
5298 5463
5299 var isWrapperFor = scope.isWrapperFor; 5464 var isWrapperFor = scope.isWrapperFor;
5300 5465
5301 // This is a list of the elements we currently override the global constructor 5466 // This is a list of the elements we currently override the global constructor
5302 // for. 5467 // for.
5303 var elements = { 5468 var elements = {
5304 'a': 'HTMLAnchorElement', 5469 'a': 'HTMLAnchorElement',
5305 'applet': 'HTMLAppletElement', 5470 'applet': 'HTMLAppletElement',
5306 'area': 'HTMLAreaElement', 5471 'area': 'HTMLAreaElement',
5307 'audio': 'HTMLAudioElement',
5308 'br': 'HTMLBRElement', 5472 'br': 'HTMLBRElement',
5309 'base': 'HTMLBaseElement', 5473 'base': 'HTMLBaseElement',
5310 'body': 'HTMLBodyElement', 5474 'body': 'HTMLBodyElement',
5311 'button': 'HTMLButtonElement', 5475 'button': 'HTMLButtonElement',
5312 // 'command': 'HTMLCommandElement', // Not fully implemented in Gecko. 5476 // 'command': 'HTMLCommandElement', // Not fully implemented in Gecko.
5313 'dl': 'HTMLDListElement', 5477 'dl': 'HTMLDListElement',
5314 'datalist': 'HTMLDataListElement', 5478 'datalist': 'HTMLDataListElement',
5315 'data': 'HTMLDataElement', 5479 'data': 'HTMLDataElement',
5316 'dir': 'HTMLDirectoryElement', 5480 'dir': 'HTMLDirectoryElement',
5317 'div': 'HTMLDivElement', 5481 'div': 'HTMLDivElement',
5318 'embed': 'HTMLEmbedElement', 5482 'embed': 'HTMLEmbedElement',
5319 'fieldset': 'HTMLFieldSetElement', 5483 'fieldset': 'HTMLFieldSetElement',
5320 'font': 'HTMLFontElement', 5484 'font': 'HTMLFontElement',
5321 'form': 'HTMLFormElement', 5485 'form': 'HTMLFormElement',
5322 'frame': 'HTMLFrameElement', 5486 'frame': 'HTMLFrameElement',
5323 'frameset': 'HTMLFrameSetElement', 5487 'frameset': 'HTMLFrameSetElement',
5324 'hr': 'HTMLHRElement', 5488 'hr': 'HTMLHRElement',
5325 'head': 'HTMLHeadElement', 5489 'head': 'HTMLHeadElement',
5326 'h1': 'HTMLHeadingElement', 5490 'h1': 'HTMLHeadingElement',
5327 'html': 'HTMLHtmlElement', 5491 'html': 'HTMLHtmlElement',
5328 'iframe': 'HTMLIFrameElement', 5492 'iframe': 'HTMLIFrameElement',
5329 'input': 'HTMLInputElement', 5493 'input': 'HTMLInputElement',
5330 'li': 'HTMLLIElement', 5494 'li': 'HTMLLIElement',
5331 'label': 'HTMLLabelElement', 5495 'label': 'HTMLLabelElement',
5332 'legend': 'HTMLLegendElement', 5496 'legend': 'HTMLLegendElement',
5333 'link': 'HTMLLinkElement', 5497 'link': 'HTMLLinkElement',
5334 'map': 'HTMLMapElement', 5498 'map': 'HTMLMapElement',
5335 'marquee': 'HTMLMarqueeElement', 5499 'marquee': 'HTMLMarqueeElement',
5336 // 'media', Covered by audio and video
5337 'menu': 'HTMLMenuElement', 5500 'menu': 'HTMLMenuElement',
5338 'menuitem': 'HTMLMenuItemElement', 5501 'menuitem': 'HTMLMenuItemElement',
5339 'meta': 'HTMLMetaElement', 5502 'meta': 'HTMLMetaElement',
5340 'meter': 'HTMLMeterElement', 5503 'meter': 'HTMLMeterElement',
5341 'del': 'HTMLModElement', 5504 'del': 'HTMLModElement',
5342 'ol': 'HTMLOListElement', 5505 'ol': 'HTMLOListElement',
5343 'object': 'HTMLObjectElement', 5506 'object': 'HTMLObjectElement',
5344 'optgroup': 'HTMLOptGroupElement', 5507 'optgroup': 'HTMLOptGroupElement',
5345 'option': 'HTMLOptionElement', 5508 'option': 'HTMLOptionElement',
5346 'output': 'HTMLOutputElement', 5509 'output': 'HTMLOutputElement',
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
5470 5633
5471 /* 5634 /*
5472 * Copyright 2012 The Polymer Authors. All rights reserved. 5635 * Copyright 2012 The Polymer Authors. All rights reserved.
5473 * Use of this source code is governed by a BSD-style 5636 * Use of this source code is governed by a BSD-style
5474 * license that can be found in the LICENSE file. 5637 * license that can be found in the LICENSE file.
5475 */ 5638 */
5476 5639
5477 /* 5640 /*
5478 This is a limited shim for ShadowDOM css styling. 5641 This is a limited shim for ShadowDOM css styling.
5479 https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#style s 5642 https://dvcs.w3.org/hg/webcomponents/raw-file/tip/spec/shadow/index.html#style s
5480 5643
5481 The intention here is to support only the styling features which can be 5644 The intention here is to support only the styling features which can be
5482 relatively simply implemented. The goal is to allow users to avoid the 5645 relatively simply implemented. The goal is to allow users to avoid the
5483 most obvious pitfalls and do so without compromising performance significantly . 5646 most obvious pitfalls and do so without compromising performance significantly .
5484 For ShadowDOM styling that's not covered here, a set of best practices 5647 For ShadowDOM styling that's not covered here, a set of best practices
5485 can be provided that should allow users to accomplish more complex styling. 5648 can be provided that should allow users to accomplish more complex styling.
5486 5649
5487 The following is a list of specific ShadowDOM styling features and a brief 5650 The following is a list of specific ShadowDOM styling features and a brief
5488 discussion of the approach used to shim. 5651 discussion of the approach used to shim.
5489 5652
5490 Shimmed features: 5653 Shimmed features:
5491 5654
5492 * @host: ShadowDOM allows styling of the shadowRoot's host element using the 5655 * @host: ShadowDOM allows styling of the shadowRoot's host element using the
5493 @host rule. To shim this feature, the @host styles are reformatted and 5656 @host rule. To shim this feature, the @host styles are reformatted and
5494 prefixed with a given scope name and promoted to a document level stylesheet. 5657 prefixed with a given scope name and promoted to a document level stylesheet.
5495 For example, given a scope name of .foo, a rule like this: 5658 For example, given a scope name of .foo, a rule like this:
5496 5659
5497 @host { 5660 @host {
5498 * { 5661 * {
5499 background: red; 5662 background: red;
5500 } 5663 }
5501 } 5664 }
5502 5665
5503 becomes: 5666 becomes:
5504 5667
5505 .foo { 5668 .foo {
5506 background: red; 5669 background: red;
5507 } 5670 }
5508 5671
5509 * encapsultion: Styles defined within ShadowDOM, apply only to 5672 * encapsultion: Styles defined within ShadowDOM, apply only to
5510 dom inside the ShadowDOM. Polymer uses one of two techniques to imlement 5673 dom inside the ShadowDOM. Polymer uses one of two techniques to imlement
5511 this feature. 5674 this feature.
5512 5675
5513 By default, rules are prefixed with the host element tag name 5676 By default, rules are prefixed with the host element tag name
5514 as a descendant selector. This ensures styling does not leak out of the 'top' 5677 as a descendant selector. This ensures styling does not leak out of the 'top'
5515 of the element's ShadowDOM. For example, 5678 of the element's ShadowDOM. For example,
5516 5679
5517 div { 5680 div {
5518 font-weight: bold; 5681 font-weight: bold;
5519 } 5682 }
5520 5683
5521 becomes: 5684 becomes:
5522 5685
5523 x-foo div { 5686 x-foo div {
5524 font-weight: bold; 5687 font-weight: bold;
5525 } 5688 }
5526 5689
5527 becomes: 5690 becomes:
5528 5691
5529 5692
5530 Alternatively, if Platform.ShadowCSS.strictStyling is set to true then 5693 Alternatively, if Platform.ShadowCSS.strictStyling is set to true then
5531 selectors are scoped by adding an attribute selector suffix to each 5694 selectors are scoped by adding an attribute selector suffix to each
5532 simple selector that contains the host element tag name. Each element 5695 simple selector that contains the host element tag name. Each element
5533 in the element's ShadowDOM template is also given the scope attribute. 5696 in the element's ShadowDOM template is also given the scope attribute.
5534 Thus, these rules match only elements that have the scope attribute. 5697 Thus, these rules match only elements that have the scope attribute.
5535 For example, given a scope name of x-foo, a rule like this: 5698 For example, given a scope name of x-foo, a rule like this:
5536 5699
5537 div { 5700 div {
5538 font-weight: bold; 5701 font-weight: bold;
5539 } 5702 }
5540 5703
5541 becomes: 5704 becomes:
5542 5705
5543 div[x-foo] { 5706 div[x-foo] {
5544 font-weight: bold; 5707 font-weight: bold;
5545 } 5708 }
5546 5709
5547 Note that elements that are dynamically added to a scope must have the scope 5710 Note that elements that are dynamically added to a scope must have the scope
5548 selector added to them manually. 5711 selector added to them manually.
5549 5712
5550 * ::pseudo: These rules are converted to rules that take advantage of the 5713 * ::pseudo: These rules are converted to rules that take advantage of the
5551 pseudo attribute. For example, a shadowRoot like this inside an x-foo 5714 pseudo attribute. For example, a shadowRoot like this inside an x-foo
5552 5715
(...skipping 11 matching lines...) Expand all
5564 part attribute. For example, a shadowRoot like this inside an x-foo 5727 part attribute. For example, a shadowRoot like this inside an x-foo
5565 5728
5566 <div part="special">Special</div> 5729 <div part="special">Special</div>
5567 5730
5568 with a rule like this: 5731 with a rule like this:
5569 5732
5570 x-foo::part(special) { ... } 5733 x-foo::part(special) { ... }
5571 5734
5572 becomes: 5735 becomes:
5573 5736
5574 x-foo [part=special] { ... } 5737 x-foo [part=special] { ... }
5575 5738
5576 Unaddressed ShadowDOM styling features: 5739 Unaddressed ShadowDOM styling features:
5577 5740
5578 * upper/lower bound encapsulation: Styles which are defined outside a 5741 * upper/lower bound encapsulation: Styles which are defined outside a
5579 shadowRoot should not cross the ShadowDOM boundary and should not apply 5742 shadowRoot should not cross the ShadowDOM boundary and should not apply
5580 inside a shadowRoot. 5743 inside a shadowRoot.
5581 5744
5582 This styling behavior is not emulated. Some possible ways to do this that 5745 This styling behavior is not emulated. Some possible ways to do this that
5583 were rejected due to complexity and/or performance concerns include: (1) reset 5746 were rejected due to complexity and/or performance concerns include: (1) reset
5584 every possible property for every possible selector for a given scope name; 5747 every possible property for every possible selector for a given scope name;
5585 (2) re-implement css in javascript. 5748 (2) re-implement css in javascript.
5586 5749
5587 As an alternative, users should make sure to use selectors 5750 As an alternative, users should make sure to use selectors
5588 specific to the scope in which they are working. 5751 specific to the scope in which they are working.
5589 5752
5590 * ::distributed: This behavior is not emulated. It's often not necessary 5753 * ::distributed: This behavior is not emulated. It's often not necessary
5591 to style the contents of a specific insertion point and instead, descendants 5754 to style the contents of a specific insertion point and instead, descendants
5592 of the host element can be styled selectively. Users can also create an 5755 of the host element can be styled selectively. Users can also create an
5593 extra node around an insertion point and style that node's contents 5756 extra node around an insertion point and style that node's contents
5594 via descendent selectors. For example, with a shadowRoot like this: 5757 via descendent selectors. For example, with a shadowRoot like this:
5595 5758
5596 <style> 5759 <style>
5597 content::-webkit-distributed(div) { 5760 content::-webkit-distributed(div) {
5598 background: red; 5761 background: red;
5599 } 5762 }
5600 </style> 5763 </style>
5601 <content></content> 5764 <content></content>
5602 5765
5603 could become: 5766 could become:
5604 5767
5605 <style> 5768 <style>
5606 / *@polyfill .content-container div * / 5769 / *@polyfill .content-container div * /
5607 content::-webkit-distributed(div) { 5770 content::-webkit-distributed(div) {
5608 background: red; 5771 background: red;
5609 } 5772 }
5610 </style> 5773 </style>
5611 <div class="content-container"> 5774 <div class="content-container">
5612 <content></content> 5775 <content></content>
5613 </div> 5776 </div>
5614 5777
5615 Note the use of @polyfill in the comment above a ShadowDOM specific style 5778 Note the use of @polyfill in the comment above a ShadowDOM specific style
5616 declaration. This is a directive to the styling shim to use the selector 5779 declaration. This is a directive to the styling shim to use the selector
5617 in comments in lieu of the next selector when running under polyfill. 5780 in comments in lieu of the next selector when running under polyfill.
5618 */ 5781 */
5619 (function(scope) { 5782 (function(scope) {
5620 5783
5621 var ShadowCSS = { 5784 var ShadowCSS = {
5622 strictStyling: false, 5785 strictStyling: false,
5623 registry: {}, 5786 registry: {},
5624 // Shim styles for a given root associated with a name and extendsName 5787 // Shim styles for a given root associated with a name and extendsName
5625 // 1. cache root styles by name 5788 // 1. cache root styles by name
5626 // 2. optionally tag root nodes with scope name 5789 // 2. optionally tag root nodes with scope name
(...skipping 15 matching lines...) Expand all
5642 var cssText = this.stylesToShimmedCssText(def.scopeStyles, name, 5805 var cssText = this.stylesToShimmedCssText(def.scopeStyles, name,
5643 typeExtension); 5806 typeExtension);
5644 // note: we only need to do rootStyles since these are unscoped. 5807 // note: we only need to do rootStyles since these are unscoped.
5645 cssText += this.extractPolyfillUnscopedRules(def.rootStyles); 5808 cssText += this.extractPolyfillUnscopedRules(def.rootStyles);
5646 // provide shimmedStyle for user extensibility 5809 // provide shimmedStyle for user extensibility
5647 def.shimmedStyle = cssTextToStyle(cssText); 5810 def.shimmedStyle = cssTextToStyle(cssText);
5648 if (root) { 5811 if (root) {
5649 root.shimmedStyle = def.shimmedStyle; 5812 root.shimmedStyle = def.shimmedStyle;
5650 } 5813 }
5651 // remove existing style elements 5814 // remove existing style elements
5652 for (var i=0, l=def.rootStyles.length, s; (i<l) && (s=def.rootStyles[i]); 5815 for (var i=0, l=def.rootStyles.length, s; (i<l) && (s=def.rootStyles[i]);
5653 i++) { 5816 i++) {
5654 s.parentNode.removeChild(s); 5817 s.parentNode.removeChild(s);
5655 } 5818 }
5656 // add style to document 5819 // add style to document
5657 addCssToDocument(cssText); 5820 addCssToDocument(cssText);
5658 }, 5821 },
5659 registerDefinition: function(root, name, extendsName) { 5822 registerDefinition: function(root, name, extendsName) {
5660 var def = this.registry[name] = { 5823 var def = this.registry[name] = {
5661 root: root, 5824 root: root,
5662 name: name, 5825 name: name,
(...skipping 23 matching lines...) Expand all
5686 Array.prototype.forEach.call(root.querySelectorAll('template'), 5849 Array.prototype.forEach.call(root.querySelectorAll('template'),
5687 function(template) { 5850 function(template) {
5688 this.applyScopeToContent(template.content, name); 5851 this.applyScopeToContent(template.content, name);
5689 }, 5852 },
5690 this); 5853 this);
5691 } 5854 }
5692 }, 5855 },
5693 /* 5856 /*
5694 * Process styles to convert native ShadowDOM rules that will trip 5857 * Process styles to convert native ShadowDOM rules that will trip
5695 * up the css parser; we rely on decorating the stylesheet with comments. 5858 * up the css parser; we rely on decorating the stylesheet with comments.
5696 * 5859 *
5697 * For example, we convert this rule: 5860 * For example, we convert this rule:
5698 * 5861 *
5699 * (comment start) @polyfill :host menu-item (comment end) 5862 * (comment start) @polyfill :host menu-item (comment end)
5700 * shadow::-webkit-distributed(menu-item) { 5863 * shadow::-webkit-distributed(menu-item) {
5701 * 5864 *
5702 * to this: 5865 * to this:
5703 * 5866 *
5704 * scopeName menu-item { 5867 * scopeName menu-item {
5705 * 5868 *
5706 **/ 5869 **/
5707 insertPolyfillDirectives: function(styles) { 5870 insertPolyfillDirectives: function(styles) {
5708 if (styles) { 5871 if (styles) {
5709 Array.prototype.forEach.call(styles, function(s) { 5872 Array.prototype.forEach.call(styles, function(s) {
5710 s.textContent = this.insertPolyfillDirectivesInCssText(s.textContent); 5873 s.textContent = this.insertPolyfillDirectivesInCssText(s.textContent);
5711 }, this); 5874 }, this);
5712 } 5875 }
5713 }, 5876 },
5714 insertPolyfillDirectivesInCssText: function(cssText) { 5877 insertPolyfillDirectivesInCssText: function(cssText) {
5715 return cssText.replace(cssPolyfillCommentRe, function(match, p1) { 5878 return cssText.replace(cssPolyfillCommentRe, function(match, p1) {
5716 // remove end comment delimiter and add block start 5879 // remove end comment delimiter and add block start
5717 return p1.slice(0, -2) + '{'; 5880 return p1.slice(0, -2) + '{';
5718 }); 5881 });
5719 }, 5882 },
5720 /* 5883 /*
5721 * Process styles to add rules which will only apply under the polyfill 5884 * Process styles to add rules which will only apply under the polyfill
5722 * 5885 *
5723 * For example, we convert this rule: 5886 * For example, we convert this rule:
5724 * 5887 *
5725 * (comment start) @polyfill-rule :host menu-item { 5888 * (comment start) @polyfill-rule :host menu-item {
5726 * ... } (comment end) 5889 * ... } (comment end)
5727 * 5890 *
5728 * to this: 5891 * to this:
5729 * 5892 *
5730 * scopeName menu-item {...} 5893 * scopeName menu-item {...}
5731 * 5894 *
5732 **/ 5895 **/
5733 insertPolyfillRules: function(styles) { 5896 insertPolyfillRules: function(styles) {
5734 if (styles) { 5897 if (styles) {
5735 Array.prototype.forEach.call(styles, function(s) { 5898 Array.prototype.forEach.call(styles, function(s) {
5736 s.textContent = this.insertPolyfillRulesInCssText(s.textContent); 5899 s.textContent = this.insertPolyfillRulesInCssText(s.textContent);
5737 }, this); 5900 }, this);
5738 } 5901 }
5739 }, 5902 },
5740 insertPolyfillRulesInCssText: function(cssText) { 5903 insertPolyfillRulesInCssText: function(cssText) {
5741 return cssText.replace(cssPolyfillRuleCommentRe, function(match, p1) { 5904 return cssText.replace(cssPolyfillRuleCommentRe, function(match, p1) {
5742 // remove end comment delimiter 5905 // remove end comment delimiter
5743 return p1.slice(0, -1); 5906 return p1.slice(0, -1);
5744 }); 5907 });
5745 }, 5908 },
5746 /* 5909 /*
5747 * Process styles to add rules which will only apply under the polyfill 5910 * Process styles to add rules which will only apply under the polyfill
5748 * and do not process via CSSOM. (CSSOM is destructive to rules on rare 5911 * and do not process via CSSOM. (CSSOM is destructive to rules on rare
5749 * occasions, e.g. -webkit-calc on Safari.) 5912 * occasions, e.g. -webkit-calc on Safari.)
5750 * For example, we convert this rule: 5913 * For example, we convert this rule:
5751 * 5914 *
5752 * (comment start) @polyfill-unscoped-rule menu-item { 5915 * (comment start) @polyfill-unscoped-rule menu-item {
5753 * ... } (comment end) 5916 * ... } (comment end)
5754 * 5917 *
5755 * to this: 5918 * to this:
5756 * 5919 *
5757 * menu-item {...} 5920 * menu-item {...}
5758 * 5921 *
5759 **/ 5922 **/
5760 extractPolyfillUnscopedRules: function(styles) { 5923 extractPolyfillUnscopedRules: function(styles) {
5761 var cssText = ''; 5924 var cssText = '';
5762 if (styles) { 5925 if (styles) {
5763 Array.prototype.forEach.call(styles, function(s) { 5926 Array.prototype.forEach.call(styles, function(s) {
5764 cssText += this.extractPolyfillUnscopedRulesFromCssText( 5927 cssText += this.extractPolyfillUnscopedRulesFromCssText(
5765 s.textContent) + '\n\n'; 5928 s.textContent) + '\n\n';
5766 }, this); 5929 }, this);
(...skipping 18 matching lines...) Expand all
5785 if (styles) { 5948 if (styles) {
5786 return this.convertAtHostStyles(styles, name, typeExtension); 5949 return this.convertAtHostStyles(styles, name, typeExtension);
5787 } 5950 }
5788 }, 5951 },
5789 convertAtHostStyles: function(styles, name, typeExtension) { 5952 convertAtHostStyles: function(styles, name, typeExtension) {
5790 var cssText = stylesToCssText(styles), self = this; 5953 var cssText = stylesToCssText(styles), self = this;
5791 cssText = cssText.replace(hostRuleRe, function(m, p1) { 5954 cssText = cssText.replace(hostRuleRe, function(m, p1) {
5792 return self.scopeHostCss(p1, name, typeExtension); 5955 return self.scopeHostCss(p1, name, typeExtension);
5793 }); 5956 });
5794 cssText = rulesToCss(this.findAtHostRules(cssToRules(cssText), 5957 cssText = rulesToCss(this.findAtHostRules(cssToRules(cssText),
5795 new RegExp('^' + name + selectorReSuffix, 'm'))); 5958 this.makeScopeMatcher(name, typeExtension)));
5796 return cssText; 5959 return cssText;
5797 }, 5960 },
5798 scopeHostCss: function(cssText, name, typeExtension) { 5961 scopeHostCss: function(cssText, name, typeExtension) {
5799 var self = this; 5962 var self = this;
5800 return cssText.replace(selectorRe, function(m, p1, p2) { 5963 return cssText.replace(selectorRe, function(m, p1, p2) {
5801 return self.scopeHostSelector(p1, name, typeExtension) + ' ' + p2 + '\n\t' ; 5964 return self.scopeHostSelector(p1, name, typeExtension) + ' ' + p2 + '\n\t' ;
5802 }); 5965 });
5803 }, 5966 },
5804 // supports scopig by name and [is=name] syntax 5967 // supports scopig by name and [is=name] syntax
5805 scopeHostSelector: function(selector, name, typeExtension) { 5968 scopeHostSelector: function(selector, name, typeExtension) {
5806 var r = [], parts = selector.split(','), is = '[is=' + name + ']'; 5969 var r = [], parts = selector.split(','), is = '[is=' + name + ']';
5807 parts.forEach(function(p) { 5970 parts.forEach(function(p) {
5808 p = p.trim(); 5971 p = p.trim();
5809 // selector: *|:scope -> name 5972 // selector: *|:scope -> name
5810 if (p.match(hostElementRe)) { 5973 if (p.match(hostElementRe)) {
5811 p = p.replace(hostElementRe, typeExtension ? is + '$1$3' : 5974 p = p.replace(hostElementRe, typeExtension ? is + '$1$3' :
5812 name + '$1$3'); 5975 name + '$1$3');
5813 // selector: .foo -> name.foo (OR) [bar] -> name[bar] 5976 // selector: .foo -> name.foo (OR) [bar] -> name[bar]
5814 } else if (p.match(hostFixableRe)) { 5977 } else if (p.match(hostFixableRe)) {
5815 p = typeExtension ? is + p : name + p; 5978 p = typeExtension ? is + p : name + p;
5816 } 5979 }
5817 r.push(p); 5980 r.push(p);
5818 }, this); 5981 }, this);
5819 return r.join(', '); 5982 return r.join(', ');
5820 }, 5983 },
5821 // consider styles that do not include component name in the selector to be 5984 // consider styles that do not include component name in the selector to be
5822 // unscoped and in need of promotion; 5985 // unscoped and in need of promotion;
5823 // for convenience, also consider keyframe rules this way. 5986 // for convenience, also consider keyframe rules this way.
5824 findAtHostRules: function(cssRules, matcher) { 5987 findAtHostRules: function(cssRules, matcher) {
5825 return Array.prototype.filter.call(cssRules, 5988 return Array.prototype.filter.call(cssRules,
5826 this.isHostRule.bind(this, matcher)); 5989 this.isHostRule.bind(this, matcher));
5827 }, 5990 },
5828 isHostRule: function(matcher, cssRule) { 5991 isHostRule: function(matcher, cssRule) {
5829 return (cssRule.selectorText && cssRule.selectorText.match(matcher)) || 5992 return (cssRule.selectorText && cssRule.selectorText.match(matcher)) ||
5830 (cssRule.cssRules && this.findAtHostRules(cssRule.cssRules, matcher).lengt h) || 5993 (cssRule.cssRules && this.findAtHostRules(cssRule.cssRules, matcher).lengt h) ||
5831 (cssRule.type == CSSRule.WEBKIT_KEYFRAMES_RULE); 5994 (cssRule.type == CSSRule.WEBKIT_KEYFRAMES_RULE);
5832 }, 5995 },
5833 /* Ensure styles are scoped. Pseudo-scoping takes a rule like: 5996 /* Ensure styles are scoped. Pseudo-scoping takes a rule like:
5834 * 5997 *
5835 * .foo {... } 5998 * .foo {... }
5836 * 5999 *
5837 * and converts this to 6000 * and converts this to
5838 * 6001 *
5839 * scopeName .foo { ... } 6002 * scopeName .foo { ... }
5840 */ 6003 */
5841 shimScoping: function(styles, name, typeExtension) { 6004 shimScoping: function(styles, name, typeExtension) {
5842 if (styles) { 6005 if (styles) {
5843 return this.convertScopedStyles(styles, name, typeExtension); 6006 return this.convertScopedStyles(styles, name, typeExtension);
5844 } 6007 }
5845 }, 6008 },
5846 convertScopedStyles: function(styles, name, typeExtension) { 6009 convertScopedStyles: function(styles, name, typeExtension) {
5847 var cssText = stylesToCssText(styles).replace(hostRuleRe, ''); 6010 var cssText = stylesToCssText(styles).replace(hostRuleRe, '');
5848 cssText = this.insertPolyfillHostInCssText(cssText); 6011 cssText = this.insertPolyfillHostInCssText(cssText);
(...skipping 10 matching lines...) Expand all
5859 }, 6022 },
5860 convertParts: function(cssText) { 6023 convertParts: function(cssText) {
5861 return cssText.replace(cssPartRe, ' [part=$1]'); 6024 return cssText.replace(cssPartRe, ' [part=$1]');
5862 }, 6025 },
5863 /* 6026 /*
5864 * convert a rule like :host(.foo) > .bar { } 6027 * convert a rule like :host(.foo) > .bar { }
5865 * 6028 *
5866 * to 6029 * to
5867 * 6030 *
5868 * scopeName.foo > .bar, .foo scopeName > .bar { } 6031 * scopeName.foo > .bar, .foo scopeName > .bar { }
5869 * TODO(sorvell): file bug since native impl does not do the former yet. 6032 *
5870 * http://jsbin.com/OganOCI/2/edit 6033 * and
6034 *
6035 * :host(.foo:host) .bar { ... }
6036 *
6037 * to
6038 *
6039 * scopeName.foo .bar { ... }
5871 */ 6040 */
5872 convertColonHost: function(cssText) { 6041 convertColonHost: function(cssText) {
5873 // p1 = :host, p2 = contents of (), p3 rest of rule 6042 // p1 = :host, p2 = contents of (), p3 rest of rule
5874 return cssText.replace(cssColonHostRe, function(m, p1, p2, p3) { 6043 return cssText.replace(cssColonHostRe, function(m, p1, p2, p3) {
5875 return p2 ? polyfillHostNoCombinator + p2 + p3 + ', ' 6044 p1 = polyfillHostNoCombinator;
5876 + p2 + ' ' + p1 + p3 : 6045 if (p2) {
5877 p1 + p3; 6046 if (p2.match(polyfillHost)) {
6047 return p1 + p2.replace(polyfillHost, '') + p3;
6048 } else {
6049 return p1 + p2 + p3 + ', ' + p2 + ' ' + p1 + p3;
6050 }
6051 } else {
6052 return p1 + p3;
6053 }
5878 }); 6054 });
5879 }, 6055 },
5880 /* 6056 /*
5881 * Convert ^ and ^^ combinators by replacing with space. 6057 * Convert ^ and ^^ combinators by replacing with space.
5882 */ 6058 */
5883 convertCombinators: function(cssText) { 6059 convertCombinators: function(cssText) {
5884 return cssText.replace('^^', ' ').replace('^', ' '); 6060 return cssText.replace('^^', ' ').replace('^', ' ');
5885 }, 6061 },
5886 // change a selector like 'div' to 'name div' 6062 // change a selector like 'div' to 'name div'
5887 scopeRules: function(cssRules, name, typeExtension) { 6063 scopeRules: function(cssRules, name, typeExtension) {
5888 var cssText = ''; 6064 var cssText = '';
5889 Array.prototype.forEach.call(cssRules, function(rule) { 6065 Array.prototype.forEach.call(cssRules, function(rule) {
5890 if (rule.selectorText && (rule.style && rule.style.cssText)) { 6066 if (rule.selectorText && (rule.style && rule.style.cssText)) {
5891 cssText += this.scopeSelector(rule.selectorText, name, typeExtension, 6067 cssText += this.scopeSelector(rule.selectorText, name, typeExtension,
5892 this.strictStyling) + ' {\n\t'; 6068 this.strictStyling) + ' {\n\t';
5893 cssText += this.propertiesFromRule(rule) + '\n}\n\n'; 6069 cssText += this.propertiesFromRule(rule) + '\n}\n\n';
5894 } else if (rule.media) { 6070 } else if (rule.media) {
5895 cssText += '@media ' + rule.media.mediaText + ' {\n'; 6071 cssText += '@media ' + rule.media.mediaText + ' {\n';
5896 cssText += this.scopeRules(rule.cssRules, name); 6072 cssText += this.scopeRules(rule.cssRules, name);
5897 cssText += '\n}\n\n'; 6073 cssText += '\n}\n\n';
5898 } else if (rule.cssText) { 6074 } else if (rule.cssText) {
5899 cssText += rule.cssText + '\n\n'; 6075 cssText += rule.cssText + '\n\n';
5900 } 6076 }
5901 }, this); 6077 }, this);
5902 return cssText; 6078 return cssText;
5903 }, 6079 },
5904 scopeSelector: function(selector, name, typeExtension, strict) { 6080 scopeSelector: function(selector, name, typeExtension, strict) {
5905 var r = [], parts = selector.split(','); 6081 var r = [], parts = selector.split(',');
5906 parts.forEach(function(p) { 6082 parts.forEach(function(p) {
5907 p = p.trim(); 6083 p = p.trim();
5908 if (this.selectorNeedsScoping(p, name, typeExtension)) { 6084 if (this.selectorNeedsScoping(p, name, typeExtension)) {
5909 p = strict ? this.applyStrictSelectorScope(p, name) : 6085 p = strict ? this.applyStrictSelectorScope(p, name) :
5910 this.applySimpleSelectorScope(p, name, typeExtension); 6086 this.applySimpleSelectorScope(p, name, typeExtension);
5911 } 6087 }
5912 r.push(p); 6088 r.push(p);
5913 }, this); 6089 }, this);
5914 return r.join(', '); 6090 return r.join(', ');
5915 }, 6091 },
5916 selectorNeedsScoping: function(selector, name, typeExtension) { 6092 selectorNeedsScoping: function(selector, name, typeExtension) {
5917 var matchScope = typeExtension ? name : '\\[is=' + name + '\\]'; 6093 var re = this.makeScopeMatcher(name, typeExtension);
5918 var re = new RegExp('^(' + matchScope + ')' + selectorReSuffix, 'm');
5919 return !selector.match(re); 6094 return !selector.match(re);
5920 }, 6095 },
6096 makeScopeMatcher: function(name, typeExtension) {
6097 var matchScope = typeExtension ? '\\[is=[\'"]?' + name + '[\'"]?\\]' : name;
6098 return new RegExp('^(' + matchScope + ')' + selectorReSuffix, 'm');
6099 },
5921 // scope via name and [is=name] 6100 // scope via name and [is=name]
5922 applySimpleSelectorScope: function(selector, name, typeExtension) { 6101 applySimpleSelectorScope: function(selector, name, typeExtension) {
5923 var scoper = typeExtension ? '[is=' + name + ']' : name; 6102 var scoper = typeExtension ? '[is=' + name + ']' : name;
5924 if (selector.match(polyfillHostRe)) { 6103 if (selector.match(polyfillHostRe)) {
5925 selector = selector.replace(polyfillHostNoCombinator, scoper); 6104 selector = selector.replace(polyfillHostNoCombinator, scoper);
5926 return selector.replace(polyfillHostRe, scoper + ' '); 6105 return selector.replace(polyfillHostRe, scoper + ' ');
5927 } else { 6106 } else {
5928 return scoper + ' ' + selector; 6107 return scoper + ' ' + selector;
5929 } 6108 }
5930 }, 6109 },
(...skipping 18 matching lines...) Expand all
5949 }, 6128 },
5950 insertPolyfillHostInCssText: function(selector) { 6129 insertPolyfillHostInCssText: function(selector) {
5951 return selector.replace(hostRe, polyfillHost).replace(colonHostRe, 6130 return selector.replace(hostRe, polyfillHost).replace(colonHostRe,
5952 polyfillHost); 6131 polyfillHost);
5953 }, 6132 },
5954 propertiesFromRule: function(rule) { 6133 propertiesFromRule: function(rule) {
5955 var properties = rule.style.cssText; 6134 var properties = rule.style.cssText;
5956 // TODO(sorvell): Chrome cssom incorrectly removes quotes from the content 6135 // TODO(sorvell): Chrome cssom incorrectly removes quotes from the content
5957 // property. (https://code.google.com/p/chromium/issues/detail?id=247231) 6136 // property. (https://code.google.com/p/chromium/issues/detail?id=247231)
5958 if (rule.style.content && !rule.style.content.match(/['"]+/)) { 6137 if (rule.style.content && !rule.style.content.match(/['"]+/)) {
5959 properties = 'content: \'' + rule.style.content + '\';\n' + 6138 properties = 'content: \'' + rule.style.content + '\';\n' +
5960 rule.style.cssText.replace(/content:[^;]*;/g, ''); 6139 rule.style.cssText.replace(/content:[^;]*;/g, '');
5961 } 6140 }
5962 return properties; 6141 return properties;
5963 } 6142 }
5964 }; 6143 };
5965 6144
5966 var hostRuleRe = /@host[^{]*{(([^}]*?{[^{]*?}[\s\S]*?)+)}/gim, 6145 var hostRuleRe = /@host[^{]*{(([^}]*?{[^{]*?}[\s\S]*?)+)}/gim,
5967 selectorRe = /([^{]*)({[\s\S]*?})/gim, 6146 selectorRe = /([^{]*)({[\s\S]*?})/gim,
5968 hostElementRe = /(.*)((?:\*)|(?:\:scope))(.*)/, 6147 hostElementRe = /(.*)((?:\*)|(?:\:scope))(.*)/,
5969 hostFixableRe = /^[.\[:]/, 6148 hostFixableRe = /^[.\[:]/,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
6035 if (window.ShadowDOMPolyfill) { 6214 if (window.ShadowDOMPolyfill) {
6036 addCssToDocument('style { display: none !important; }\n'); 6215 addCssToDocument('style { display: none !important; }\n');
6037 var head = document.querySelector('head'); 6216 var head = document.querySelector('head');
6038 head.insertBefore(getSheet(), head.childNodes[0]); 6217 head.insertBefore(getSheet(), head.childNodes[0]);
6039 } 6218 }
6040 6219
6041 // exports 6220 // exports
6042 scope.ShadowCSS = ShadowCSS; 6221 scope.ShadowCSS = ShadowCSS;
6043 6222
6044 })(window.Platform); 6223 })(window.Platform);
6045
6046 } 6224 }
OLDNEW
« no previous file with comments | « dart/pkg/polymer/test/build/script_compactor_test.dart ('k') | dart/pkg/shadow_dom/lib/shadow_dom.min.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698