From 7f0a0bff42d6b0f9dd973b5c8bfc83ddbb0a47e3 Mon Sep 17 00:00:00 2001 From: Annamalai Date: Tue, 5 Jul 2016 00:07:23 +0530 Subject: [PATCH 1/2] Resolve `var` usage in fallbacks --- lib/resolve-value.js | 8 +++++++- .../missing-variable-should-fallback-calc.css | 7 +++++++ ...issing-variable-should-fallback-calc.expected.css | 3 +++ .../missing-variable-should-fallback-nested.css | 8 ++++++++ ...sing-variable-should-fallback-nested.expected.css | 3 +++ .../missing-variable-should-fallback-var.css | 12 ++++++++++++ ...missing-variable-should-fallback-var.expected.css | 7 +++++++ test/fixtures/missing-variable-should-fallback.css | 7 +------ .../missing-variable-should-fallback.expected.css | 5 +---- test/test.js | 3 +++ 10 files changed, 52 insertions(+), 11 deletions(-) create mode 100644 test/fixtures/missing-variable-should-fallback-calc.css create mode 100644 test/fixtures/missing-variable-should-fallback-calc.expected.css create mode 100644 test/fixtures/missing-variable-should-fallback-nested.css create mode 100644 test/fixtures/missing-variable-should-fallback-nested.expected.css create mode 100644 test/fixtures/missing-variable-should-fallback-var.css create mode 100644 test/fixtures/missing-variable-should-fallback-var.expected.css diff --git a/lib/resolve-value.js b/lib/resolve-value.js index 3752c5b..b58cd20 100644 --- a/lib/resolve-value.js +++ b/lib/resolve-value.js @@ -61,8 +61,14 @@ var resolveValue = function(decl, map, /*optional*/ignorePseudoScope, /*internal } }); + var fallbackValue; + if(fallback) { + var cloneDecl = Object.assign({},decl,{value:fallback}); + fallbackValue = resolveValue(cloneDecl, map, false,true).value; + } + // Default to the calculatedInPlaceValue which might be a previous fallback, then try this declarations fallback - var replaceValue = (matchingVarDeclMapItem || {}).calculatedInPlaceValue || fallback; + var replaceValue = (matchingVarDeclMapItem || {}).calculatedInPlaceValue || fallbackValue; // Otherwise if the dependency health is good(no circular or self references), dive deeper and resolve if(matchingVarDeclMapItem !== undefined && !gatherVariableDependencies(variablesUsedInValue, map).hasCircularOrSelfReference) { // Splice the declaration parent onto the matching entry diff --git a/test/fixtures/missing-variable-should-fallback-calc.css b/test/fixtures/missing-variable-should-fallback-calc.css new file mode 100644 index 0000000..6eb804d --- /dev/null +++ b/test/fixtures/missing-variable-should-fallback-calc.css @@ -0,0 +1,7 @@ +:root { + --foo1: 150px; +} + +.box-bar { + width: var(--missing,calc(var(--foo1) + 100px)); +} diff --git a/test/fixtures/missing-variable-should-fallback-calc.expected.css b/test/fixtures/missing-variable-should-fallback-calc.expected.css new file mode 100644 index 0000000..1fdc6e1 --- /dev/null +++ b/test/fixtures/missing-variable-should-fallback-calc.expected.css @@ -0,0 +1,3 @@ +.box-bar { + width: calc(150px + 100px); +} \ No newline at end of file diff --git a/test/fixtures/missing-variable-should-fallback-nested.css b/test/fixtures/missing-variable-should-fallback-nested.css new file mode 100644 index 0000000..b3dc9cc --- /dev/null +++ b/test/fixtures/missing-variable-should-fallback-nested.css @@ -0,0 +1,8 @@ +:root { + --foo1: 100px; + --foo2: 150px; +} + +.box-bar { + width: var(--missing, var(--missing, var(--foo1))); +} \ No newline at end of file diff --git a/test/fixtures/missing-variable-should-fallback-nested.expected.css b/test/fixtures/missing-variable-should-fallback-nested.expected.css new file mode 100644 index 0000000..e67e2db --- /dev/null +++ b/test/fixtures/missing-variable-should-fallback-nested.expected.css @@ -0,0 +1,3 @@ +.box-bar { + width: 100px; +} \ No newline at end of file diff --git a/test/fixtures/missing-variable-should-fallback-var.css b/test/fixtures/missing-variable-should-fallback-var.css new file mode 100644 index 0000000..a1ba533 --- /dev/null +++ b/test/fixtures/missing-variable-should-fallback-var.css @@ -0,0 +1,12 @@ +:root { + --foo-default: 100px; + --foo-width: 150px; +} + +.box-foo { + width: var(--missing); +} + +.box-bar { + width: var(--missing, var(--foo-default)); +} \ No newline at end of file diff --git a/test/fixtures/missing-variable-should-fallback-var.expected.css b/test/fixtures/missing-variable-should-fallback-var.expected.css new file mode 100644 index 0000000..693f012 --- /dev/null +++ b/test/fixtures/missing-variable-should-fallback-var.expected.css @@ -0,0 +1,7 @@ +.box-foo { + width: undefined; +} + +.box-bar { + width: 100px; +} \ No newline at end of file diff --git a/test/fixtures/missing-variable-should-fallback.css b/test/fixtures/missing-variable-should-fallback.css index 585d503..e942782 100644 --- a/test/fixtures/missing-variable-should-fallback.css +++ b/test/fixtures/missing-variable-should-fallback.css @@ -1,11 +1,6 @@ :root { --foo-width: 150px; } - -.box-foo { - width: var(--missing); -} - .box-bar { width: var(--missing, 30px); -} \ No newline at end of file +} diff --git a/test/fixtures/missing-variable-should-fallback.expected.css b/test/fixtures/missing-variable-should-fallback.expected.css index 896da59..8a8f78e 100644 --- a/test/fixtures/missing-variable-should-fallback.expected.css +++ b/test/fixtures/missing-variable-should-fallback.expected.css @@ -1,7 +1,4 @@ -.box-foo { - width: undefined; -} .box-bar { width: 30px; -} \ No newline at end of file +} diff --git a/test/test.js b/test/test.js index 61101f4..48167e8 100644 --- a/test/test.js +++ b/test/test.js @@ -204,6 +204,9 @@ describe('postcss-css-variables', function() { }); }); }); + test('should use fallback variable if provided with missing variables', 'missing-variable-should-fallback-var'); + test('should use fallback variable if provided with missing variables calc', 'missing-variable-should-fallback-calc'); + test('should use fallback variable if provided with missing variables nested', 'missing-variable-should-fallback-nested'); }); it('should not parse malformed var() declarations', function() { From daedabbea0e1adcb4a5011a85e566c5978cd2645 Mon Sep 17 00:00:00 2001 From: Mark Lu Date: Tue, 14 Feb 2017 11:57:08 -0800 Subject: [PATCH 2/2] Avoid using Object.assign() directly to clone declaration --- lib/resolve-value.js | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/lib/resolve-value.js b/lib/resolve-value.js index b58cd20..d1ad2e9 100644 --- a/lib/resolve-value.js +++ b/lib/resolve-value.js @@ -61,10 +61,11 @@ var resolveValue = function(decl, map, /*optional*/ignorePseudoScope, /*internal } }); - var fallbackValue; + // Resolve values in fallback + var fallbackValue = fallback; if(fallback) { - var cloneDecl = Object.assign({},decl,{value:fallback}); - fallbackValue = resolveValue(cloneDecl, map, false,true).value; + var fallbackDecl = decl.clone({ parent: decl.parent, value: fallback }); + fallbackValue = resolveValue(fallbackDecl, map, false, true).value; } // Default to the calculatedInPlaceValue which might be a previous fallback, then try this declarations fallback