From c7571e5c33357183f7ee1e2896c8aef3d8aa91f0 Mon Sep 17 00:00:00 2001 From: Daniel Freedman Date: Thu, 28 Jul 2016 14:19:46 -0700 Subject: [PATCH] Handle mixins with property values of inherit and initial Fixes #3818 --- src/lib/apply-shim.html | 35 +++++++++- test/unit/styling-cross-scope-apply.html | 88 ++++++++++++++++++++++++ 2 files changed, 122 insertions(+), 1 deletion(-) diff --git a/src/lib/apply-shim.html b/src/lib/apply-shim.html index 33caafff4a..3f3c5f6f0f 100644 --- a/src/lib/apply-shim.html +++ b/src/lib/apply-shim.html @@ -80,6 +80,7 @@ // match var(--a, --b) to make var(--a, var(--b)); var BAD_VAR = /var\(\s*(--[^,]*),\s*(--[^)]*)\)/g; var APPLY_NAME_CLEAN = /;\s*/m; + var INITIAL_INHERIT = /^\s*(initial)|(inherit)\s*$/; // separator used between mixin-name and mixin-property-name when producing properties // NOTE: plain '-' may cause collisions in user styles @@ -102,10 +103,40 @@ return mixinMap[name]; } + var measureElement; + function getInitialValueForProperty(property) { + if (!measureElement) { + measureElement = document.createElement('meta'); + measureElement.style.all = 'initial'; + document.head.appendChild(measureElement); + } + return window.getComputedStyle(measureElement).getPropertyValue(property); + } + + function replaceInitialOrInherit(property, value) { + var match = INITIAL_INHERIT.exec(value); + if (match) { + if (match[1]) { + // initial + // replace `initial` with the concrete initial value for this property + value = getInitialValueForProperty(property); + } else { + // inherit + // with this purposfully illegal value, the variable will be invalid at + // compute time (https://www.w3.org/TR/css-variables/#invalid-at-computed-value-time) + // and for inheriting values, will behave similarly + // we cannot support the same behavior for non inheriting values like 'border' + value = 'apply-shim-inherit'; + } + } + return value; + } + // "parse" a mixin definition into a map of properties and values // cssTextToMap('border: 2px solid black') -> ('border', '2px solid black') function cssTextToMap(text) { var props = text.split(';'); + var property, value; var out = {}; for (var i = 0, p, sp; i < props.length; i++) { p = props[i]; @@ -113,8 +144,10 @@ sp = p.split(':'); // ignore lines that aren't definitions like @media if (sp.length > 1) { + property = sp[0].trim(); // some properties may have ':' in the value, like data urls - out[sp[0].trim()] = sp.slice(1).join(':'); + value = replaceInitialOrInherit(property, sp.slice(1).join(':')); + out[property] = value; } } } diff --git a/test/unit/styling-cross-scope-apply.html b/test/unit/styling-cross-scope-apply.html index 615153e173..3ce6f97eff 100644 --- a/test/unit/styling-cross-scope-apply.html +++ b/test/unit/styling-cross-scope-apply.html @@ -591,6 +591,71 @@ + + + + + + + + + + + + + + +