From f0ff70db324f14ebf01f93be03b20af7a951efcd Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Wed, 29 Nov 2017 11:05:43 -0800 Subject: [PATCH] Make `:dir` more robust Fixes #4952 --- src/lib/style-transformer.html | 45 ++++++++++++++++++------------- test/smoke/dir.html | 49 ++++++++++++++++++++++++++++++++++ test/unit/dir.html | 34 +++++++++++++++++++++++ 3 files changed, 109 insertions(+), 19 deletions(-) create mode 100644 test/smoke/dir.html diff --git a/src/lib/style-transformer.html b/src/lib/style-transformer.html index ee27292c40..d33ef27afe 100644 --- a/src/lib/style-transformer.html +++ b/src/lib/style-transformer.html @@ -37,7 +37,7 @@ * :host-context(...): scopeName..., ... scopeName - * ...:dir(ltr|rtl) -> [dir="ltr|rtl"] ..., ...[dir="ltr|rtl"] + * ...:dir(ltr|rtl) -> :host-context([dir]) -> [dir="ltr|rtl"] scopeName ..., scopeName[dir="ltr|rtl"] ... * :host(:dir[rtl]) -> scopeName:dir(rtl) -> [dir="rtl"] scopeName, scopeName[dir="rtl"] @@ -189,6 +189,17 @@ return p$.join(COMPLEX_SELECTOR_SEP); }, + // make sure `:dir() {` acts as `*:dir() {` + // otherwise, it would transform to `:host-context([dir="rtl"])` and apply incorrectly to the host + // so make it `:host-context([dir="rtl"]) *` + _ensureScopedDir: function(s) { + var m = s.match(DIR_PAREN); + if (m && m[1] === '' && m[0].length === s.length) { + s = '*' + s; + } + return s; + }, + _transformComplexSelector: function(selector, scope, hostScope) { var stop = false; var hostContext = false; @@ -197,6 +208,7 @@ selector = this._slottedToContent(selector); selector = selector.replace(ROOT, ':host > *'); selector = selector.replace(CONTENT_START, HOST + ' $1'); + selector = this._ensureScopedDir(selector); selector = selector.replace(SIMPLE_SELECTOR_SEP, function(m, c, s) { if (!stop) { var info = self._transformCompoundSelector(s, c, scope, hostScope); @@ -219,10 +231,19 @@ return selector; }, + _transformDir: function (s) { + // replaces :host(:dir(rtl)) with :host-context([dir="rtl"]) + s = s.replace(HOST_DIR, HOST_DIR_REPLACE); + // replaces `.foo :dir(rtl)` with `:host-context([dir="rtl") .foo` + s = s.replace(DIR_PAREN, DIR_REPLACE); + return s; + }, + _transformCompoundSelector: function(selector, combinator, scope, hostScope) { // replace :host with host scoping class var jumpIndex = selector.search(SCOPE_JUMP); var hostContext = false; + selector = this._transformDir(selector); if (selector.indexOf(HOST_CONTEXT) >=0) { hostContext = true; } else if (selector.indexOf(HOST) >=0) { @@ -243,7 +264,6 @@ selector = selector.replace(SCOPE_JUMP, ' '); stop = true; } - selector = selector.replace(DIR_PAREN, DIR_REPLACE); return {value: selector, combinator: combinator, stop: stop, hostContext: hostContext}; }, @@ -318,21 +338,9 @@ _dirShadowTransform: function(selector) { return selector.split(',').map(function(s) { - // replaces :host(:dir(rtl)) with :host-context([dir="rtl"]) - s = s.replace(HOST_DIR, HOST_DIR_REPLACE); - var m; - if ((m = s.match(DIR_PAREN))) { - // replaces `.foo :dir(rtl)` with `:host-context([dir="rtl") .foo` - s = s.replace(DIR_PAREN, SHADOW_DIR_REPLACE); - // make sure `:dir() {` acts as `*:dir() {` - // otherwise, it would transform to `:host-context([dir="rtl"])` and apply incorrectly to the host - // so make it `:host-context([dir="rtl"]) *` - if (!m[1] || m[1].match(/^\s*$/)) { - s = s + '*'; - } - } - return s; - }).join(','); + s = this._ensureScopedDir(s); + return this._transformDir(s); + }, this).join(','); }, SCOPE_NAME: 'style-scope' @@ -364,8 +372,7 @@ var SLOTTED_PAREN = /(?:::slotted)(?:\(((?:\([^)(]*\)|[^)(]*)+?)\))/g; var HOST_OR_HOST_GT_STAR = /:host(?:\s*>\s*\*)?/; var DIR_PAREN = /(.*):dir\((ltr|rtl)\)/; - var DIR_REPLACE = '[dir="$2"] $1, $1[dir="$2"]'; - var SHADOW_DIR_REPLACE = ':host-context([dir="$2"]) $1'; + var DIR_REPLACE = ':host-context([dir="$2"]) $1'; var HOST_DIR = /:host\(:dir\((rtl|ltr)\)\)/g; var HOST_DIR_REPLACE = ':host-context([dir="$1"])'; diff --git a/test/smoke/dir.html b/test/smoke/dir.html new file mode 100644 index 0000000000..3e3b151ed3 --- /dev/null +++ b/test/smoke/dir.html @@ -0,0 +1,49 @@ + + + + + + + + + Polymer + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/unit/dir.html b/test/unit/dir.html index 110a37195c..7840593c6b 100644 --- a/test/unit/dir.html +++ b/test/unit/dir.html @@ -109,6 +109,28 @@ + + + + + + + + +