From fd1182bd697c86005761f9bb3cd8bccc53a11b65 Mon Sep 17 00:00:00 2001 From: seven-phases-max Date: Thu, 3 Oct 2013 10:04:23 +0400 Subject: [PATCH] Added `length` function (#1542). Added scalar value handling for `extract` and `length` (#1576). --- lib/less/functions.js | 13 ++- test/css/extract-and-length.css | 133 ++++++++++++++++++++++++++++++ test/css/functions.css | 5 +- test/less/extract-and-length.less | 133 ++++++++++++++++++++++++++++++ test/less/functions.less | 5 +- 5 files changed, 282 insertions(+), 7 deletions(-) create mode 100644 test/css/extract-and-length.css create mode 100644 test/less/extract-and-length.less diff --git a/lib/less/functions.js b/lib/less/functions.js index 0a12b9853..1f63993b1 100644 --- a/lib/less/functions.js +++ b/lib/less/functions.js @@ -432,10 +432,17 @@ tree.functions = { }, shade: function(color, amount) { return this.mix(this.rgb(0, 0, 0), color, amount); - }, + }, extract: function(values, index) { - index = index.value - 1; // (1-based index) - return values.value[index]; + index = index.value - 1; // (1-based index) + // handle non-array values as an array of length 1 + // return 'undefined' if index is invalid + return Array.isArray(values.value) + ? values.value[index] : Array(values)[index]; + }, + length: function(values) { + var n = Array.isArray(values.value) ? values.value.length : 1; + return new tree.Dimension(n); }, "data-uri": function(mimetypeNode, filePathNode) { diff --git a/test/css/extract-and-length.css b/test/css/extract-and-length.css new file mode 100644 index 000000000..f550e201b --- /dev/null +++ b/test/css/extract-and-length.css @@ -0,0 +1,133 @@ +.multiunit { + length: 6; + extract: abc "abc" 1 1px 1% #112233; +} +.incorrect-index { + v1: extract(a b c, 5); + v2: extract(a, b, c, -2); +} +.scalar { + var-value: variable; + var-length: 1; + ill-index: extract(variable, 2); + name-value: name; + string-value: "string"; + number-value: 12345678; + color-value: #0000ff; + rgba-value: rgba(80, 160, 240, 0.67); + empty-value: ; + name-length: 1; + string-length: 1; + number-length: 1; + color-length: 1; + rgba-length: 1; + empty-length: 1; +} +.mixin-arguments-1 { + length: 4; + extract: c | b | a; +} +.mixin-arguments-2 { + length: 4; + extract: c | b | a; +} +.mixin-arguments-3 { + length: 4; + extract: c | b | a; +} +.mixin-arguments-4 { + length: 0; + extract: extract(, 2) | extract(, 1); +} +.mixin-arguments-2 { + length: 4; + extract: c | b | a; +} +.mixin-arguments-3 { + length: 4; + extract: c | b | a; +} +.mixin-arguments-4 { + length: 3; + extract: c | b; +} +.mixin-arguments-2 { + length: 4; + extract: 3 | 2 | 1; +} +.mixin-arguments-3 { + length: 4; + extract: 3 | 2 | 1; +} +.mixin-arguments-4 { + length: 3; + extract: 3 | 2; +} +.md-space-comma { + length-1: 3; + extract-1: 1 2 3; + length-2: 3; + extract-2: 2; +} +.md-space-comma-as-args-2 { + length: 3; + extract: "x" "y" "z" | 1 2 3 | a b c; +} +.md-space-comma-as-args-3 { + length: 3; + extract: "x" "y" "z" | 1 2 3 | a b c; +} +.md-space-comma-as-args-4 { + length: 2; + extract: "x" "y" "z" | 1 2 3; +} +.md-cat-space-comma { + length-1: 3; + extract-1: 1 2 3; + length-2: 3; + extract-2: 2; +} +.md-cat-space-comma-as-args-2 { + length: 3; + extract: "x" "y" "z" | 1 2 3 | a b c; +} +.md-cat-space-comma-as-args-3 { + length: 3; + extract: "x" "y" "z" | 1 2 3 | a b c; +} +.md-cat-space-comma-as-args-4 { + length: 2; + extract: "x" "y" "z" | 1 2 3; +} +.md-cat-comma-space { + length-1: 3; + extract-1: 1, 2, 3; + length-2: 3; + extract-2: 2; +} +.md-cat-comma-space-as-args-1 { + length: 3; + extract: "x", "y", "z" | 1, 2, 3 | a, b, c; +} +.md-cat-comma-space-as-args-2 { + length: 3; + extract: "x", "y", "z" | 1, 2, 3 | a, b, c; +} +.md-cat-comma-space-as-args-3 { + length: 3; + extract: "x", "y", "z" | 1, 2, 3 | a, b, c; +} +.md-cat-comma-space-as-args-4 { + length: 0; + extract: extract(, 2) | extract(, 1); +} +.md-3D { + length-1: 2; + extract-1: a b c d, 1 2 3 4; + length-2: 2; + extract-2: 5 6 7 8; + length-3: 4; + extract-3: 7; + length-4: 1; + extract-4: 8; +} diff --git a/test/css/functions.css b/test/css/functions.css index b4ea3c866..9694a7a3b 100644 --- a/test/css/functions.css +++ b/test/css/functions.css @@ -133,6 +133,7 @@ average: #7b007b; negation: #d73131; } -#extract { - result: 3 2 1 C B A; +#extract-and-length { + extract: 3 2 1 C B A; + length: 6; } diff --git a/test/less/extract-and-length.less b/test/less/extract-and-length.less new file mode 100644 index 000000000..d81e118f5 --- /dev/null +++ b/test/less/extract-and-length.less @@ -0,0 +1,133 @@ + +// simple array/list: + +.multiunit { + @v: abc "abc" 1 1px 1% #123; + length: length(@v); + extract: extract(@v, 1) extract(@v, 2) extract(@v, 3) extract(@v, 4) extract(@v, 5) extract(@v, 6); +} + +.incorrect-index { + @v1: a b c; + @v2: a, b, c; + v1: extract(@v1, 5); + v2: extract(@v2, -2); +} + +.scalar { + @var: variable; + var-value: extract(@var, 1); + var-length: length(@var); + ill-index: extract(@var, 2); + + name-value: extract(name, 1); + string-value: extract("string", 1); + number-value: extract(12345678, 1); + color-value: extract(blue, 1); + rgba-value: extract(rgba(80, 160, 240, 0.67), 1); + empty-value: extract(~'', 1); + + name-length: length(name); + string-length: length("string"); + number-length: length(12345678); + color-length: length(blue); + rgba-length: length(rgba(80, 160, 240, 0.67)); + empty-length: length(~''); +} + +.mixin-arguments { + .mixin-args(a b c d); + .mixin-args(a, b, c, d); + .mixin-args(1; 2; 3; 4); +} + +.mixin-args(@value) { + &-1 { + length: length(@value); + extract: extract(@value, 3) ~"|" extract(@value, 2) ~"|" extract(@value, 1); + } +} + +.mixin-args(...) { + &-2 { + length: length(@arguments); + extract: extract(@arguments, 3) ~"|" extract(@arguments, 2) ~"|" extract(@arguments, 1); + } +} + +.mixin-args(@values...) { + &-3 { + length: length(@values); + extract: extract(@values, 3) ~"|" extract(@values, 2) ~"|" extract(@values, 1); + } +} + +.mixin-args(@head, @tail...) { + &-4 { + length: length(@tail); + extract: extract(@tail, 2) ~"|" extract(@tail, 1); + } +} + +// "multidimensional" array/list + +.md-space-comma { + @v: a b c, 1 2 3, "x" "y" "z"; + length-1: length(@v); + extract-1: extract(@v, 2); + length-2: length(extract(@v, 2)); + extract-2: extract(extract(@v, 2), 2); + + &-as-args {.mixin-args(a b c, 1 2 3, "x" "y" "z")} +} + +.md-cat-space-comma { + @a: a b c; + @b: 1 2 3; + @c: "x" "y" "z"; + @v: @a, @b, @c; + length-1: length(@v); + extract-1: extract(@v, 2); + length-2: length(extract(@v, 2)); + extract-2: extract(extract(@v, 2), 2); + + &-as-args {.mixin-args(@a, @b, @c)} +} + +.md-cat-comma-space { + @a: a, b, c; + @b: 1, 2, 3; + @c: "x", "y", "z"; + @v: @a @b @c; + length-1: length(@v); + extract-1: extract(@v, 2); + length-2: length(extract(@v, 2)); + extract-2: extract(extract(@v, 2), 2); + + &-as-args {.mixin-args(@a @b @c)} +} + +.md-3D { + @a: a b c d, 1 2 3 4; + @b: 5 6 7 8, e f g h; + .3D(@a, @b); + + .3D(...) { + + @v1: @arguments; + length-1: length(@v1); + extract-1: extract(@v1, 1); + + @v2: extract(@v1, 2); + length-2: length(@v2); + extract-2: extract(@v2, 1); + + @v3: extract(@v2, 1); + length-3: length(@v3); + extract-3: extract(@v3, 3); + + @v4: extract(@v3, 4); + length-4: length(@v4); + extract-4: extract(@v4, 1); + } +} diff --git a/test/less/functions.less b/test/less/functions.less index aa4c040bb..b50a0da58 100644 --- a/test/less/functions.less +++ b/test/less/functions.less @@ -146,7 +146,8 @@ negation: negation(#f60000, #313131); } -#extract { +#extract-and-length { @anon: A B C 1 2 3; - result: extract(@anon, 6) extract(@anon, 5) extract(@anon, 4) extract(@anon, 3) extract(@anon, 2) extract(@anon, 1); + extract: extract(@anon, 6) extract(@anon, 5) extract(@anon, 4) extract(@anon, 3) extract(@anon, 2) extract(@anon, 1); + length: length(@anon); }