Repository navigation
Expand file tree
/
Copy pathstyles.js
More file actions
117 lines (105 loc) · 3.97 KB
/
Copy pathstyles.js
File metadata and controls
117 lines (105 loc) · 3.97 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
/*
* Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
* This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt
* The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
* The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt
* Code distributed by Google as part of the polymer project is also
* subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt
*/
(function(scope) {
// imports
var log = window.WebComponents ? WebComponents.flags.log : {};
var hasShadowDOMPolyfill = window.ShadowDOMPolyfill;
// magic words
var STYLE_SCOPE_ATTRIBUTE = 'element';
var STYLE_CONTROLLER_SCOPE = 'controller';
var styles = {
STYLE_SCOPE_ATTRIBUTE: STYLE_SCOPE_ATTRIBUTE,
/**
* Installs external stylesheets and <style> elements with the attribute
* polymer-scope='controller' into the scope of element. This is intended
* to be a called during custom element construction.
*/
installControllerStyles: function() {
// apply controller styles, but only if they are not yet applied
var scope = this.findStyleScope();
if (scope && !this.scopeHasNamedStyle(scope, this.localName)) {
// allow inherited controller styles
var proto = getPrototypeOf(this), cssText = '';
while (proto && proto.element) {
cssText += proto.element.cssTextForScope(STYLE_CONTROLLER_SCOPE);
proto = getPrototypeOf(proto);
}
if (cssText) {
this.installScopeCssText(cssText, scope);
}
}
},
installScopeStyle: function(style, name, scope) {
var scope = scope || this.findStyleScope(), name = name || '';
if (scope && !this.scopeHasNamedStyle(scope, this.localName + name)) {
var cssText = '';
if (style instanceof Array) {
for (var i=0, l=style.length, s; (i<l) && (s=style[i]); i++) {
cssText += s.textContent + '\n\n';
}
} else {
cssText = style.textContent;
}
this.installScopeCssText(cssText, scope, name);
}
},
installScopeCssText: function(cssText, scope, name) {
scope = scope || this.findStyleScope();
name = name || '';
if (!scope) {
return;
}
if (hasShadowDOMPolyfill) {
cssText = shimCssText(cssText, scope.host);
}
var style = this.element.cssTextToScopeStyle(cssText,
STYLE_CONTROLLER_SCOPE);
Polymer.applyStyleToScope(style, scope);
// cache that this style has been applied
this.styleCacheForScope(scope)[this.localName + name] = true;
},
findStyleScope: function(node) {
// find the shadow root that contains this element
var n = node || this;
while (n.parentNode) {
n = n.parentNode;
}
return n;
},
scopeHasNamedStyle: function(scope, name) {
var cache = this.styleCacheForScope(scope);
return cache[name];
},
styleCacheForScope: function(scope) {
if (hasShadowDOMPolyfill) {
var scopeName = scope.host ? scope.host.localName : scope.localName;
return polyfillScopeStyleCache[scopeName] || (polyfillScopeStyleCache[scopeName] = {});
} else {
return scope._scopeStyles = (scope._scopeStyles || {});
}
}
};
var polyfillScopeStyleCache = {};
// NOTE: use raw prototype traversal so that we ensure correct traversal
// on platforms where the protoype chain is simulated via __proto__ (IE10)
function getPrototypeOf(prototype) {
return prototype.__proto__;
}
function shimCssText(cssText, host) {
var name = '', is = false;
if (host) {
name = host.localName;
is = host.hasAttribute('is');
}
var selector = WebComponents.ShadowCSS.makeScopeSelector(name, is);
return WebComponents.ShadowCSS.shimCssText(cssText, selector);
}
// exports
scope.api.instance.styles = styles;
})(Polymer);