|
37 | 37 |
|
38 | 38 | * :host-context(...): scopeName..., ... scopeName |
39 | 39 |
|
40 | | - * ...:dir(ltr|rtl) -> [dir="ltr|rtl"] ..., ...[dir="ltr|rtl"] |
| 40 | + * ...:dir(ltr|rtl) -> :host-context([dir]) -> [dir="ltr|rtl"] scopeName ..., scopeName[dir="ltr|rtl"] ... |
41 | 41 |
|
42 | 42 | * :host(:dir[rtl]) -> scopeName:dir(rtl) -> [dir="rtl"] scopeName, scopeName[dir="rtl"] |
43 | 43 |
|
|
189 | 189 | return p$.join(COMPLEX_SELECTOR_SEP); |
190 | 190 | }, |
191 | 191 |
|
| 192 | + // make sure `:dir() {` acts as `*:dir() {` |
| 193 | + // otherwise, it would transform to `:host-context([dir="rtl"])` and apply incorrectly to the host |
| 194 | + // so make it `:host-context([dir="rtl"]) *` |
| 195 | + _ensureScopedDir: function(s) { |
| 196 | + var m = s.match(DIR_PAREN); |
| 197 | + if (m && m[1] === '' && m[0].length === s.length) { |
| 198 | + s = '*' + s; |
| 199 | + } |
| 200 | + return s; |
| 201 | + }, |
| 202 | + |
192 | 203 | _transformComplexSelector: function(selector, scope, hostScope) { |
193 | 204 | var stop = false; |
194 | 205 | var hostContext = false; |
|
197 | 208 | selector = this._slottedToContent(selector); |
198 | 209 | selector = selector.replace(ROOT, ':host > *'); |
199 | 210 | selector = selector.replace(CONTENT_START, HOST + ' $1'); |
| 211 | + selector = this._ensureScopedDir(selector); |
200 | 212 | selector = selector.replace(SIMPLE_SELECTOR_SEP, function(m, c, s) { |
201 | 213 | if (!stop) { |
202 | 214 | var info = self._transformCompoundSelector(s, c, scope, hostScope); |
|
219 | 231 | return selector; |
220 | 232 | }, |
221 | 233 |
|
| 234 | + _transformDir: function (s) { |
| 235 | + // replaces :host(:dir(rtl)) with :host-context([dir="rtl"]) |
| 236 | + s = s.replace(HOST_DIR, HOST_DIR_REPLACE); |
| 237 | + // replaces `.foo :dir(rtl)` with `:host-context([dir="rtl") .foo` |
| 238 | + s = s.replace(DIR_PAREN, DIR_REPLACE); |
| 239 | + return s; |
| 240 | + }, |
| 241 | + |
222 | 242 | _transformCompoundSelector: function(selector, combinator, scope, hostScope) { |
223 | 243 | // replace :host with host scoping class |
224 | 244 | var jumpIndex = selector.search(SCOPE_JUMP); |
225 | 245 | var hostContext = false; |
| 246 | + selector = this._transformDir(selector); |
226 | 247 | if (selector.indexOf(HOST_CONTEXT) >=0) { |
227 | 248 | hostContext = true; |
228 | 249 | } else if (selector.indexOf(HOST) >=0) { |
|
243 | 264 | selector = selector.replace(SCOPE_JUMP, ' '); |
244 | 265 | stop = true; |
245 | 266 | } |
246 | | - selector = selector.replace(DIR_PAREN, DIR_REPLACE); |
247 | 267 | return {value: selector, combinator: combinator, stop: stop, |
248 | 268 | hostContext: hostContext}; |
249 | 269 | }, |
|
318 | 338 |
|
319 | 339 | _dirShadowTransform: function(selector) { |
320 | 340 | return selector.split(',').map(function(s) { |
321 | | - // replaces :host(:dir(rtl)) with :host-context([dir="rtl"]) |
322 | | - s = s.replace(HOST_DIR, HOST_DIR_REPLACE); |
323 | | - var m; |
324 | | - if ((m = s.match(DIR_PAREN))) { |
325 | | - // replaces `.foo :dir(rtl)` with `:host-context([dir="rtl") .foo` |
326 | | - s = s.replace(DIR_PAREN, SHADOW_DIR_REPLACE); |
327 | | - // make sure `:dir() {` acts as `*:dir() {` |
328 | | - // otherwise, it would transform to `:host-context([dir="rtl"])` and apply incorrectly to the host |
329 | | - // so make it `:host-context([dir="rtl"]) *` |
330 | | - if (!m[1] || m[1].match(/^\s*$/)) { |
331 | | - s = s + '*'; |
332 | | - } |
333 | | - } |
334 | | - return s; |
335 | | - }).join(','); |
| 341 | + s = this._ensureScopedDir(s); |
| 342 | + return this._transformDir(s); |
| 343 | + }, this).join(','); |
336 | 344 | }, |
337 | 345 |
|
338 | 346 | SCOPE_NAME: 'style-scope' |
|
364 | 372 | var SLOTTED_PAREN = /(?:::slotted)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g; |
365 | 373 | var HOST_OR_HOST_GT_STAR = /:host(?:\s*>\s*\*)?/; |
366 | 374 | var DIR_PAREN = /(.*):dir\((ltr|rtl)\)/; |
367 | | - var DIR_REPLACE = '[dir="$2"] $1, $1[dir="$2"]'; |
368 | | - var SHADOW_DIR_REPLACE = ':host-context([dir="$2"]) $1'; |
| 375 | + var DIR_REPLACE = ':host-context([dir="$2"]) $1'; |
369 | 376 | var HOST_DIR = /:host\(:dir\((rtl|ltr)\)\)/g; |
370 | 377 | var HOST_DIR_REPLACE = ':host-context([dir="$1"])'; |
371 | 378 |
|
|
0 commit comments