From 2da9bb5b4d25ecf31194cd7c69f8448d0b03adfd Mon Sep 17 00:00:00 2001 From: "alexander.akait" Date: Tue, 23 May 2023 00:58:11 +0300 Subject: [PATCH] fix: do no handle identifier in nested functions --- src/index.js | 58 +++++++++++++++++++++++----------------------- test/index.test.js | 37 ++++++++++++++++++++++++++++- 2 files changed, 65 insertions(+), 30 deletions(-) diff --git a/src/index.js b/src/index.js index f9293d3..459a55d 100644 --- a/src/index.js +++ b/src/index.js @@ -302,15 +302,6 @@ function localizeDeclNode(node, context) { return node; } -function isWordAFunctionArgument(wordNode, functionNode) { - return functionNode - ? functionNode.nodes.some( - (functionNodeChild) => - functionNodeChild.sourceIndex === wordNode.sourceIndex - ) - : false; -} - // `none` is special value, other is global values const specialKeywords = [ "none", @@ -373,51 +364,59 @@ function localizeDeclaration(declaration, context) { animation name of infinite from the second. */ const animationKeywords = { + // animation-direction + $normal: 1, + $reverse: 1, $alternate: 1, "$alternate-reverse": 1, + // animation-fill-mode + $forwards: 1, $backwards: 1, $both: 1, + // animation-iteration-count + $infinite: 1, + // animation-play-state + $paused: 1, + $running: 1, + // animation-timing-function $ease: 1, "$ease-in": 1, - "$ease-in-out": 1, "$ease-out": 1, - $forwards: 1, - $infinite: 1, + "$ease-in-out": 1, $linear: 1, - $none: Infinity, // No matter how many times you write none, it will never be an animation name - $normal: 1, - $paused: 1, - $reverse: 1, - $running: 1, "$step-end": 1, "$step-start": 1, + // Special + $none: Infinity, // No matter how many times you write none, it will never be an animation name + // Global values $initial: Infinity, $inherit: Infinity, $unset: Infinity, $revert: Infinity, "$revert-layer": Infinity, }; - - const didParseAnimationName = false; let parsedAnimationKeywords = {}; - let stepsFunctionNode = null; const valueNodes = valueParser(declaration.value).walk((node) => { - /* If div-token appeared (represents as comma ','), a possibility of an animation-keywords should be reflesh. */ + // If div-token appeared (represents as comma ','), a possibility of an animation-keywords should be reflesh. if (node.type === "div") { parsedAnimationKeywords = {}; + + return; + } + // Do not handle nested functions + else if (node.type === "function") { + return false; } - if (node.type === "function" && node.value.toLowerCase() === "steps") { - stepsFunctionNode = node; + // Ignore all except word + else if (node.type !== "word") { + return; } - const value = - node.type === "word" && - !isWordAFunctionArgument(node, stepsFunctionNode) - ? node.value.toLowerCase() - : null; + + const value = node.type === "word" ? node.value.toLowerCase() : null; let shouldParseAnimationName = false; - if (!didParseAnimationName && value && validIdent.test(value)) { + if (value && validIdent.test(value)) { if ("$" + value in animationKeywords) { parsedAnimationKeywords["$" + value] = "$" + value in parsedAnimationKeywords @@ -438,6 +437,7 @@ function localizeDeclaration(declaration, context) { localizeNextItem: shouldParseAnimationName && !context.global, localAliasMap: context.localAliasMap, }; + return localizeDeclNode(node, subContext); }); diff --git a/test/index.test.js b/test/index.test.js index ca07bf7..193e6f5 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -250,16 +250,51 @@ const tests = [ input: ".foo { animation: --foo; }", expected: ":local(.foo) { animation: :local(--foo); }", }, + { + name: "not localize name in nested function", + input: ".foo { animation: fade .2s var(--easeOutQuart) .1s forwards }", + expected: + ":local(.foo) { animation: :local(fade) .2s var(--easeOutQuart) .1s forwards }", + }, + { + name: "not localize name in nested function #2", + input: ".foo { animation: fade .2s env(FOO_BAR) .1s forwards, name }", + expected: + ":local(.foo) { animation: :local(fade) .2s env(FOO_BAR) .1s forwards, :local(name) }", + }, + { + name: "not localize name in nested function #3", + input: ".foo { animation: var(--foo-bar) .1s forwards, name }", + expected: + ":local(.foo) { animation: var(--foo-bar) .1s forwards, :local(name) }", + }, + { + name: "not localize name in nested function #3", + input: ".foo { animation: var(--foo-bar) .1s forwards name, name }", + expected: + ":local(.foo) { animation: var(--foo-bar) .1s forwards :local(name), :local(name) }", + }, { name: "localize animation", input: ".foo { animation: a; }", expected: ":local(.foo) { animation: :local(a); }", }, { - name: "localize animation", + name: "localize animation #2", input: ".foo { animation: bar 5s, foobar; }", expected: ":local(.foo) { animation: :local(bar) 5s, :local(foobar); }", }, + { + name: "localize animation #3", + input: ".foo { animation: ease ease; }", + expected: ":local(.foo) { animation: ease :local(ease); }", + }, + { + name: "localize animation #4", + input: ".foo { animation: 0s ease 0s 1 normal none test running; }", + expected: + ":local(.foo) { animation: 0s ease 0s 1 normal none :local(test) running; }", + }, { name: "localize animation with vendor prefix", input: ".foo { -webkit-animation: bar; animation: bar; }",