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

Side by Side Diff: third_party/polymer/v0_8/components/polymer/src/lib/style-transformer.html

Issue 1082403004: Import Polymer 0.8 and several key elements. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Also remove polymer/explainer Created 5 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 <!--
2 @license
3 Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
4 This code may only be used under the BSD style license found at http://polymer.g ithub.io/LICENSE.txt
5 The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt
6 The complete set of contributors may be found at http://polymer.github.io/CONTRI BUTORS.txt
7 Code distributed by Google as part of the polymer project is also
8 subject to an additional IP rights grant found at http://polymer.github.io/PATEN TS.txt
9 -->
10
11 <link rel="import" href="style-util.html">
12
13 <script>
14
15 (function() {
16
17 /* Transforms ShadowDOM styling into ShadyDOM styling
18
19 * scoping:
20
21 * elements in scope get scoping selector class="x-foo-scope"
22 * selectors re-written as follows:
23
24 div button -> div.x-foo-scope button.x-foo-scope
25
26 * :host -> scopeName
27
28 * :host(...) -> scopeName...
29
30 * ::content -> ' ' NOTE: requires use of scoping selector and selectors
31 cannot otherwise be scoped:
32 e.g. :host ::content > .bar -> x-foo > .bar
33
34 * ::shadow, /deep/: processed simimlar to ::content
35
36 * :host-context(...): NOT SUPPORTED
37
38 */
39
40 // Given a node and scope name, add a scoping class to each node
41 // in the tree. This facilitates transforming css into scoped rules.
42 function transformDom(node, scope, useAttr, shouldRemoveScope) {
43 _transformDom(node, scope || '', useAttr, shouldRemoveScope);
44 }
45
46 function _transformDom(node, selector, useAttr, shouldRemoveScope) {
47 if (node.setAttribute) {
48 transformElement(node, selector, useAttr, shouldRemoveScope);
49 }
50 var c$ = Polymer.dom(node).childNodes;
51 for (var i=0; i<c$.length; i++) {
52 _transformDom(c$[i], selector, useAttr, shouldRemoveScope);
53 }
54 }
55
56 function transformElement(element, scope, useAttr, shouldRemoveScope) {
57 if (useAttr) {
58 if (shouldRemoveScope) {
59 element.removeAttribute(SCOPE_NAME);
60 } else {
61 element.setAttribute(SCOPE_NAME, scope);
62 }
63 } else {
64 // note: if using classes, we add both the general 'style-scope' class
65 // as well as the specific scope. This enables easy filtering of all
66 // `style-scope` elements
67 if (scope) {
68 if (shouldRemoveScope) {
69 element.classList.remove(SCOPE_NAME, scope);
70 } else {
71 element.classList.add(SCOPE_NAME, scope);
72 }
73 }
74 }
75 }
76
77 function transformHost(host, scope) {
78 }
79
80 // Given a string of cssText and a scoping string (scope), returns
81 // a string of scoped css where each selector is transformed to include
82 // a class created from the scope. ShadowDOM selectors are also transformed
83 // (e.g. :host) to use the scoping selector.
84 function transformCss(rules, scope, ext, callback, useAttr) {
85 var hostScope = calcHostScope(scope, ext);
86 scope = calcElementScope(scope, useAttr);
87 return Polymer.StyleUtil.toCssText(rules, function(rule) {
88 transformRule(rule, scope, hostScope);
89 if (callback) {
90 callback(rule, scope, hostScope);
91 }
92 });
93 }
94
95 function calcElementScope(scope, useAttr) {
96 if (scope) {
97 return useAttr ?
98 CSS_ATTR_PREFIX + scope + CSS_ATTR_SUFFIX :
99 CSS_CLASS_PREFIX + scope;
100 } else {
101 return '';
102 }
103 }
104
105 function calcHostScope(scope, ext) {
106 return ext ? '[is=' + scope + ']' : scope;
107 }
108
109 function transformRule(rule, scope, hostScope) {
110 _transformRule(rule, transformComplexSelector,
111 scope, hostScope);
112 }
113
114 // transforms a css rule to a scoped rule.
115 function _transformRule(rule, transformer, scope, hostScope) {
116 var p$ = rule.selector.split(COMPLEX_SELECTOR_SEP);
117 for (var i=0, l=p$.length, p; (i<l) && (p=p$[i]); i++) {
118 p$[i] = transformer(p, scope, hostScope);
119 }
120 rule.selector = p$.join(COMPLEX_SELECTOR_SEP);
121 }
122
123 function transformComplexSelector(selector, scope, hostScope) {
124 var stop = false;
125 selector = selector.replace(SIMPLE_SELECTOR_SEP, function(m, c, s) {
126 if (!stop) {
127 var o = transformCompoundSelector(s, c, scope, hostScope);
128 if (o.stop) {
129 stop = true;
130 }
131 c = o.combinator;
132 s = o.value;
133 }
134 return c + s;
135 });
136 return selector;
137 }
138
139 function transformCompoundSelector(selector, combinator, scope, hostScope) {
140 // replace :host with host scoping class
141 var jumpIndex = selector.search(SCOPE_JUMP);
142 if (selector.indexOf(HOST) >=0) {
143 // :host(...)
144 selector = selector.replace(HOST_PAREN, function(m, host, paren) {
145 return hostScope + paren;
146 });
147 // now normal :host
148 selector = selector.replace(HOST, hostScope);
149 // replace other selectors with scoping class
150 } else if (jumpIndex !== 0) {
151 selector = scope ? transformSimpleSelector(selector, scope) : selector;
152 }
153 // remove left-side combinator when dealing with ::content.
154 if (selector.indexOf(CONTENT) >= 0) {
155 combinator = '';
156 }
157 // process scope jumping selectors up to the scope jump and then stop
158 // e.g. .zonk ::content > .foo ==> .zonk.scope > .foo
159 var stop;
160 if (jumpIndex >= 0) {
161 selector = selector.replace(SCOPE_JUMP, ' ');
162 stop = true;
163 }
164 return {value: selector, combinator: combinator, stop: stop};
165 }
166
167 function transformSimpleSelector(selector, scope) {
168 var p$ = selector.split(PSEUDO_PREFIX);
169 p$[0] += scope;
170 return p$.join(PSEUDO_PREFIX);
171 }
172
173 function transformRootRule(rule) {
174 _transformRule(rule, transformRootSelector);
175 }
176
177 function transformRootSelector(selector) {
178 return selector.match(SCOPE_JUMP) ?
179 transformComplexSelector(selector) :
180 selector.trim() + SCOPE_ROOT_SELECTOR;
181 }
182
183 var SCOPE_NAME = 'style-scope';
184 var SCOPE_ROOT_SELECTOR = ':not([' + SCOPE_NAME + '])' +
185 ':not(.' + SCOPE_NAME + ')';
186 var COMPLEX_SELECTOR_SEP = ',';
187 var SIMPLE_SELECTOR_SEP = /(^|[\s>+~]+)([^\s>+~]+)/g;
188 var HOST = ':host';
189 // NOTE: this supports 1 nested () pair for things like
190 // :host(:not([selected]), more general support requires
191 // parsing which seems like overkill
192 var HOST_PAREN = /(\:host)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g;
193 var CONTENT = '::content';
194 var SCOPE_JUMP = /\:\:content|\:\:shadow|\/deep\//;
195 var CSS_CLASS_PREFIX = '.';
196 var CSS_ATTR_PREFIX = '[' + SCOPE_NAME + '~=';
197 var CSS_ATTR_SUFFIX = ']';
198 var PSEUDO_PREFIX = ':';
199
200 // exports
201 Polymer.StyleTransformer = {
202 element: transformElement,
203 dom: transformDom,
204 host: transformHost,
205 css: transformCss,
206 rule: transformRule,
207 rootRule: transformRootRule,
208 SCOPE_NAME: SCOPE_NAME
209 };
210
211 })();
212
213 </script>
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698