From 7f535a891d8fee1ae0963241dca98c359fe65ccf Mon Sep 17 00:00:00 2001 From: Matthew Dean Date: Tue, 26 Jan 2016 16:54:51 -0800 Subject: [PATCH 1/7] Allow root functions defined via @plugin --- lib/less/parser/parser.js | 46 ++++++++++++++++++++---- lib/less/tree/call.js | 2 +- lib/less/visitors/to-css-visitor.js | 24 +++++++++---- test/css/plugin.css | 4 +++ test/less/errors/detached-ruleset-3.txt | 2 +- test/less/errors/plugin-undefined-1.less | 1 + test/less/errors/plugin-undefined-1.txt | 2 ++ test/less/errors/plugin-undefined-2.less | 2 ++ test/less/errors/plugin-undefined-2.txt | 3 ++ test/less/errors/property-in-root.txt | 2 +- test/less/errors/property-in-root2.txt | 2 +- test/less/errors/property-in-root3.txt | 2 +- test/less/plugin.less | 6 ++++ test/less/plugin/plugin-root.js | 11 ++++++ 14 files changed, 91 insertions(+), 18 deletions(-) create mode 100644 test/less/errors/plugin-undefined-1.less create mode 100644 test/less/errors/plugin-undefined-1.txt create mode 100644 test/less/errors/plugin-undefined-2.less create mode 100644 test/less/errors/plugin-undefined-2.txt create mode 100644 test/less/plugin/plugin-root.js diff --git a/lib/less/parser/parser.js b/lib/less/parser/parser.js index e6656dd55..82bf12c74 100644 --- a/lib/less/parser/parser.js +++ b/lib/less/parser/parser.js @@ -261,7 +261,7 @@ var Parser = function Parser(context, imports, fileInfo) { } node = mixin.definition() || this.rule() || this.ruleset() || - mixin.call() || this.rulesetCall() || this.directive(); + mixin.call() || this.rulesetCall() || this.entities.call() || this.directive(); if (node) { root.push(node); } else { @@ -390,19 +390,51 @@ var Parser = function Parser(context, imports, fileInfo) { return new(tree.Call)(name, args, index, fileInfo); }, arguments: function () { - var args = [], arg; + var argsSemiColon = [], argsComma = [], + expressions = [], + isSemiColonSeparated, value, arg; + + parserInput.save(); while (true) { - arg = this.assignment() || parsers.expression(); + + arg = parsers.detachedRuleset() || this.assignment() || parsers.expression(); + if (!arg) { break; } - args.push(arg); - if (! parserInput.$char(',')) { - break; + + value = arg; + + if (arg.value && arg.value.length == 1) { + value = arg.value[0]; + } + + if (value) { + expressions.push(value); + } + + argsComma.push(value); + + if (parserInput.$char(',')) { + continue; + } + + if (parserInput.$char(';') || isSemiColonSeparated) { + + isSemiColonSeparated = true; + + if (expressions.length > 1) { + value = new(tree.Value)(expressions); + } + argsSemiColon.push(value); + + expressions = []; } } - return args; + + parserInput.forget(); + return isSemiColonSeparated ? argsSemiColon : argsComma; }, literal: function () { return this.dimension() || diff --git a/lib/less/tree/call.js b/lib/less/tree/call.js index 279b6fa52..e98b4dc47 100644 --- a/lib/less/tree/call.js +++ b/lib/less/tree/call.js @@ -31,7 +31,7 @@ Call.prototype.eval = function (context) { var args = this.args.map(function (a) { return a.eval(context); }), result, funcCaller = new FunctionCaller(this.name, context, this.index, this.currentFileInfo); - if (funcCaller.isValid()) { // 1. + if (funcCaller.isValid()) { try { result = funcCaller.call(args); if (result != null) { diff --git a/lib/less/visitors/to-css-visitor.js b/lib/less/visitors/to-css-visitor.js index cc90cdd88..69ab14c5e 100644 --- a/lib/less/visitors/to-css-visitor.js +++ b/lib/less/visitors/to-css-visitor.js @@ -199,12 +199,24 @@ ToCSSVisitor.prototype = { return directiveNode; }, - checkPropertiesInRoot: function(rules) { + checkValidNodes: function(rules, isRoot) { + if (!rules || !rules.length) { + return; + } + var ruleNode; for (var i = 0; i < rules.length; i++) { ruleNode = rules[i]; - if (ruleNode instanceof tree.Rule && !ruleNode.variable) { - throw { message: "properties must be inside selector blocks, they cannot be in the root.", + if (isRoot && ruleNode instanceof tree.Rule && !ruleNode.variable) { + throw { message: "Properties must be inside selector blocks. They cannot be in the root.", + index: ruleNode.index, filename: ruleNode.currentFileInfo ? ruleNode.currentFileInfo.filename : null}; + } + if (ruleNode instanceof tree.Call) { + throw { message: "Custom function '" + ruleNode.name + "' is not registered.", + index: ruleNode.index, filename: ruleNode.currentFileInfo ? ruleNode.currentFileInfo.filename : null}; + } + if (ruleNode instanceof tree.Color) { + throw { message: "Invalid value in a ruleset or root node.", index: ruleNode.index, filename: ruleNode.currentFileInfo ? ruleNode.currentFileInfo.filename : null}; } } @@ -213,9 +225,9 @@ ToCSSVisitor.prototype = { visitRuleset: function (rulesetNode, visitArgs) { //at this point rulesets are nested into each other var rule, rulesets = []; - if (rulesetNode.firstRoot) { - this.checkPropertiesInRoot(rulesetNode.rules); - } + + this.checkValidNodes(rulesetNode.rules, rulesetNode.firstRoot); + if (! rulesetNode.root) { //remove invisible paths this._compileRulesetPaths(rulesetNode); diff --git a/test/css/plugin.css b/test/css/plugin.css index b837dc63e..5cb79c620 100644 --- a/test/css/plugin.css +++ b/test/css/plugin.css @@ -1,3 +1,4 @@ +@charset "utf-8"; .other { trans: transitive; } @@ -42,3 +43,6 @@ result: local; } } +.root { + prop: value; +} diff --git a/test/less/errors/detached-ruleset-3.txt b/test/less/errors/detached-ruleset-3.txt index 15d281fa3..637bf30b7 100644 --- a/test/less/errors/detached-ruleset-3.txt +++ b/test/less/errors/detached-ruleset-3.txt @@ -1,4 +1,4 @@ -SyntaxError: properties must be inside selector blocks, they cannot be in the root. in {path}detached-ruleset-3.less on line 2, column 3: +SyntaxError: Properties must be inside selector blocks. They cannot be in the root. in {path}detached-ruleset-3.less on line 2, column 3: 1 @a: { 2 b: 1; 3 }; diff --git a/test/less/errors/plugin-undefined-1.less b/test/less/errors/plugin-undefined-1.less new file mode 100644 index 000000000..e5bacda6b --- /dev/null +++ b/test/less/errors/plugin-undefined-1.less @@ -0,0 +1 @@ +func(); \ No newline at end of file diff --git a/test/less/errors/plugin-undefined-1.txt b/test/less/errors/plugin-undefined-1.txt new file mode 100644 index 000000000..1808d76ee --- /dev/null +++ b/test/less/errors/plugin-undefined-1.txt @@ -0,0 +1,2 @@ +SyntaxError: Custom function 'func' is not registered. in {path}plugin-undefined-1.less on line 1, column 1: +1 func(); diff --git a/test/less/errors/plugin-undefined-2.less b/test/less/errors/plugin-undefined-2.less new file mode 100644 index 000000000..daf06ea1d --- /dev/null +++ b/test/less/errors/plugin-undefined-2.less @@ -0,0 +1,2 @@ +@plugin "../plugin/plugin-root.js"; +test-undefined(); \ No newline at end of file diff --git a/test/less/errors/plugin-undefined-2.txt b/test/less/errors/plugin-undefined-2.txt new file mode 100644 index 000000000..4d380ff97 --- /dev/null +++ b/test/less/errors/plugin-undefined-2.txt @@ -0,0 +1,3 @@ +SyntaxError: Custom function 'test-undefined' is not registered. in {path}plugin-undefined-2.less on line 2, column 1: +1 @plugin "../plugin/plugin-root.js"; +2 test-undefined(); diff --git a/test/less/errors/property-in-root.txt b/test/less/errors/property-in-root.txt index 04b277660..e22f435f5 100644 --- a/test/less/errors/property-in-root.txt +++ b/test/less/errors/property-in-root.txt @@ -1,4 +1,4 @@ -SyntaxError: properties must be inside selector blocks, they cannot be in the root. in {path}property-in-root.less on line 2, column 3: +SyntaxError: Properties must be inside selector blocks. They cannot be in the root. in {path}property-in-root.less on line 2, column 3: 1 .a() { 2 prop:1; 3 } diff --git a/test/less/errors/property-in-root2.txt b/test/less/errors/property-in-root2.txt index 04b277660..e22f435f5 100644 --- a/test/less/errors/property-in-root2.txt +++ b/test/less/errors/property-in-root2.txt @@ -1,4 +1,4 @@ -SyntaxError: properties must be inside selector blocks, they cannot be in the root. in {path}property-in-root.less on line 2, column 3: +SyntaxError: Properties must be inside selector blocks. They cannot be in the root. in {path}property-in-root.less on line 2, column 3: 1 .a() { 2 prop:1; 3 } diff --git a/test/less/errors/property-in-root3.txt b/test/less/errors/property-in-root3.txt index 68ef9454d..b211fa346 100644 --- a/test/less/errors/property-in-root3.txt +++ b/test/less/errors/property-in-root3.txt @@ -1,3 +1,3 @@ -SyntaxError: properties must be inside selector blocks, they cannot be in the root. in {path}property-in-root3.less on line 1, column 1: +SyntaxError: Properties must be inside selector blocks. They cannot be in the root. in {path}property-in-root3.less on line 1, column 1: 1 prop:1; 2 .a { diff --git a/test/less/plugin.less b/test/less/plugin.less index 17524a400..4d198cdc3 100644 --- a/test/less/plugin.less +++ b/test/less/plugin.less @@ -81,5 +81,11 @@ } } +@plugin "./plugin/plugin-root"; +@ruleset2: test-detached-ruleset(); +.root { + @ruleset2(); +} +test-directive(); diff --git a/test/less/plugin/plugin-root.js b/test/less/plugin/plugin-root.js new file mode 100644 index 000000000..4f08b06b5 --- /dev/null +++ b/test/less/plugin/plugin-root.js @@ -0,0 +1,11 @@ +functions.addMultiple({ + "test-detached-ruleset" : function() { + var rule = new tree.Rule('prop', new tree.Anonymous('value')); + return new tree.DetachedRuleset(new tree.Ruleset("", [ rule ])); + }, + "test-directive": function() { + return new tree.Directive("@charset", new tree.Anonymous('"utf-8"')); + }, + // Functions must return something. Must 'return true' if they produce no output. + "test-undefined": function() { } +}); \ No newline at end of file From 87f8b2d43e0964c17e1c494d5cba33b069922578 Mon Sep 17 00:00:00 2001 From: Matthew Dean Date: Tue, 26 Jan 2016 17:10:15 -0800 Subject: [PATCH 2/7] Add test demonstrating arguments and semi-colon separators --- test/less/plugin.less | 2 +- test/less/plugin/plugin-root.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/test/less/plugin.less b/test/less/plugin.less index 4d198cdc3..3414d4974 100644 --- a/test/less/plugin.less +++ b/test/less/plugin.less @@ -87,5 +87,5 @@ @ruleset2(); } -test-directive(); +test-directive("@charset"; "utf-8"); diff --git a/test/less/plugin/plugin-root.js b/test/less/plugin/plugin-root.js index 4f08b06b5..8c4be52d7 100644 --- a/test/less/plugin/plugin-root.js +++ b/test/less/plugin/plugin-root.js @@ -3,8 +3,8 @@ functions.addMultiple({ var rule = new tree.Rule('prop', new tree.Anonymous('value')); return new tree.DetachedRuleset(new tree.Ruleset("", [ rule ])); }, - "test-directive": function() { - return new tree.Directive("@charset", new tree.Anonymous('"utf-8"')); + "test-directive": function(arg1, arg2) { + return new tree.Directive(arg1.value, new tree.Anonymous('"' + arg2.value + '"')); }, // Functions must return something. Must 'return true' if they produce no output. "test-undefined": function() { } From a58bb76e4c5a769c3a9c1c6d419315a2442626fd Mon Sep 17 00:00:00 2001 From: Max Mikhailov Date: Fri, 29 Jan 2016 02:20:40 +0300 Subject: [PATCH 3/7] polish "root func" error handling --- lib/less/tree/call.js | 9 ++++--- lib/less/visitors/to-css-visitor.js | 26 ++++++++++++------- test/less/errors/detached-ruleset-3.txt | 2 +- test/less/errors/plugin-undefined-1.txt | 2 -- test/less/errors/plugin-undefined-2.txt | 3 --- test/less/errors/property-in-root.txt | 2 +- test/less/errors/property-in-root2.txt | 2 +- test/less/errors/property-in-root3.txt | 2 +- ...ined-1.less => root-func-undefined-1.less} | 0 test/less/errors/root-func-undefined-1.txt | 2 ++ ...ined-2.less => root-func-undefined-2.less} | 0 test/less/errors/root-func-undefined-2.txt | 3 +++ 12 files changed, 31 insertions(+), 22 deletions(-) delete mode 100644 test/less/errors/plugin-undefined-1.txt delete mode 100644 test/less/errors/plugin-undefined-2.txt rename test/less/errors/{plugin-undefined-1.less => root-func-undefined-1.less} (100%) create mode 100644 test/less/errors/root-func-undefined-1.txt rename test/less/errors/{plugin-undefined-2.less => root-func-undefined-2.less} (100%) create mode 100644 test/less/errors/root-func-undefined-2.txt diff --git a/lib/less/tree/call.js b/lib/less/tree/call.js index e98b4dc47..12e183747 100644 --- a/lib/less/tree/call.js +++ b/lib/less/tree/call.js @@ -34,15 +34,18 @@ Call.prototype.eval = function (context) { if (funcCaller.isValid()) { try { result = funcCaller.call(args); - if (result != null) { - return result; - } } catch (e) { throw { type: e.type || "Runtime", message: "error evaluating function `" + this.name + "`" + (e.message ? ': ' + e.message : ''), index: this.index, filename: this.currentFileInfo.filename }; } + + if (result != null) { + result.index = this.index; + result.currentFileInfo = this.currentFileInfo; + return result; + } } return new Call(this.name, args, this.index, this.currentFileInfo); diff --git a/lib/less/visitors/to-css-visitor.js b/lib/less/visitors/to-css-visitor.js index 69ab14c5e..8d700b709 100644 --- a/lib/less/visitors/to-css-visitor.js +++ b/lib/less/visitors/to-css-visitor.js @@ -200,24 +200,30 @@ ToCSSVisitor.prototype = { }, checkValidNodes: function(rules, isRoot) { - if (!rules || !rules.length) { + if (!rules) { return; } - var ruleNode; for (var i = 0; i < rules.length; i++) { - ruleNode = rules[i]; + var ruleNode = rules[i]; if (isRoot && ruleNode instanceof tree.Rule && !ruleNode.variable) { - throw { message: "Properties must be inside selector blocks. They cannot be in the root.", - index: ruleNode.index, filename: ruleNode.currentFileInfo ? ruleNode.currentFileInfo.filename : null}; + throw { message: "Properties must be inside selector blocks. They cannot be in the root", + index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename}; } if (ruleNode instanceof tree.Call) { - throw { message: "Custom function '" + ruleNode.name + "' is not registered.", - index: ruleNode.index, filename: ruleNode.currentFileInfo ? ruleNode.currentFileInfo.filename : null}; + throw { message: "Function '" + ruleNode.name + "' is undefined", + index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename}; } - if (ruleNode instanceof tree.Color) { - throw { message: "Invalid value in a ruleset or root node.", - index: ruleNode.index, filename: ruleNode.currentFileInfo ? ruleNode.currentFileInfo.filename : null}; + if (!ruleNode.isRulesetLike && + (ruleNode.type !== "Rule") && + (ruleNode.type !== "Comment") && + (ruleNode.type !== "Extend") && + (ruleNode.type !== "Import")) { + // I'm not quite sure about message, but considering these values can be here only + // as result of a "root-funtion" call, something close to + // "A value returned by function is unexpected here" or so could be more friendly + throw { message: "Invalid '" + ruleNode.type + "' value in a ruleset or root node", + index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename}; } } }, diff --git a/test/less/errors/detached-ruleset-3.txt b/test/less/errors/detached-ruleset-3.txt index 637bf30b7..ad43ab46a 100644 --- a/test/less/errors/detached-ruleset-3.txt +++ b/test/less/errors/detached-ruleset-3.txt @@ -1,4 +1,4 @@ -SyntaxError: Properties must be inside selector blocks. They cannot be in the root. in {path}detached-ruleset-3.less on line 2, column 3: +SyntaxError: Properties must be inside selector blocks. They cannot be in the root in {path}detached-ruleset-3.less on line 2, column 3: 1 @a: { 2 b: 1; 3 }; diff --git a/test/less/errors/plugin-undefined-1.txt b/test/less/errors/plugin-undefined-1.txt deleted file mode 100644 index 1808d76ee..000000000 --- a/test/less/errors/plugin-undefined-1.txt +++ /dev/null @@ -1,2 +0,0 @@ -SyntaxError: Custom function 'func' is not registered. in {path}plugin-undefined-1.less on line 1, column 1: -1 func(); diff --git a/test/less/errors/plugin-undefined-2.txt b/test/less/errors/plugin-undefined-2.txt deleted file mode 100644 index 4d380ff97..000000000 --- a/test/less/errors/plugin-undefined-2.txt +++ /dev/null @@ -1,3 +0,0 @@ -SyntaxError: Custom function 'test-undefined' is not registered. in {path}plugin-undefined-2.less on line 2, column 1: -1 @plugin "../plugin/plugin-root.js"; -2 test-undefined(); diff --git a/test/less/errors/property-in-root.txt b/test/less/errors/property-in-root.txt index e22f435f5..10c985344 100644 --- a/test/less/errors/property-in-root.txt +++ b/test/less/errors/property-in-root.txt @@ -1,4 +1,4 @@ -SyntaxError: Properties must be inside selector blocks. They cannot be in the root. in {path}property-in-root.less on line 2, column 3: +SyntaxError: Properties must be inside selector blocks. They cannot be in the root in {path}property-in-root.less on line 2, column 3: 1 .a() { 2 prop:1; 3 } diff --git a/test/less/errors/property-in-root2.txt b/test/less/errors/property-in-root2.txt index e22f435f5..10c985344 100644 --- a/test/less/errors/property-in-root2.txt +++ b/test/less/errors/property-in-root2.txt @@ -1,4 +1,4 @@ -SyntaxError: Properties must be inside selector blocks. They cannot be in the root. in {path}property-in-root.less on line 2, column 3: +SyntaxError: Properties must be inside selector blocks. They cannot be in the root in {path}property-in-root.less on line 2, column 3: 1 .a() { 2 prop:1; 3 } diff --git a/test/less/errors/property-in-root3.txt b/test/less/errors/property-in-root3.txt index b211fa346..13a49052e 100644 --- a/test/less/errors/property-in-root3.txt +++ b/test/less/errors/property-in-root3.txt @@ -1,3 +1,3 @@ -SyntaxError: Properties must be inside selector blocks. They cannot be in the root. in {path}property-in-root3.less on line 1, column 1: +SyntaxError: Properties must be inside selector blocks. They cannot be in the root in {path}property-in-root3.less on line 1, column 1: 1 prop:1; 2 .a { diff --git a/test/less/errors/plugin-undefined-1.less b/test/less/errors/root-func-undefined-1.less similarity index 100% rename from test/less/errors/plugin-undefined-1.less rename to test/less/errors/root-func-undefined-1.less diff --git a/test/less/errors/root-func-undefined-1.txt b/test/less/errors/root-func-undefined-1.txt new file mode 100644 index 000000000..a07480e61 --- /dev/null +++ b/test/less/errors/root-func-undefined-1.txt @@ -0,0 +1,2 @@ +SyntaxError: Function 'func' is undefined in {path}root-func-undefined-1.less on line 1, column 1: +1 func(); diff --git a/test/less/errors/plugin-undefined-2.less b/test/less/errors/root-func-undefined-2.less similarity index 100% rename from test/less/errors/plugin-undefined-2.less rename to test/less/errors/root-func-undefined-2.less diff --git a/test/less/errors/root-func-undefined-2.txt b/test/less/errors/root-func-undefined-2.txt new file mode 100644 index 000000000..525851d33 --- /dev/null +++ b/test/less/errors/root-func-undefined-2.txt @@ -0,0 +1,3 @@ +SyntaxError: Function 'test-undefined' is undefined in {path}root-func-undefined-2.less on line 2, column 1: +1 @plugin "../plugin/plugin-root.js"; +2 test-undefined(); From b67403d3413eefe0d53535ca75f430c6331939cf Mon Sep 17 00:00:00 2001 From: Matthew Dean Date: Mon, 1 Feb 2016 19:49:20 -0800 Subject: [PATCH 4/7] Add allowRoot property to nodes that can be returned by a function into root or ruleset --- lib/less/tree/comment.js | 1 + lib/less/tree/directive.js | 1 + lib/less/tree/extend.js | 3 ++- lib/less/tree/import.js | 1 + lib/less/tree/media.js | 1 + lib/less/tree/mixin-call.js | 1 + lib/less/tree/mixin-definition.js | 1 + lib/less/tree/rule.js | 1 + lib/less/tree/ruleset-call.js | 1 + lib/less/tree/ruleset.js | 1 + lib/less/visitors/to-css-visitor.js | 11 ++--------- 11 files changed, 13 insertions(+), 10 deletions(-) diff --git a/lib/less/tree/comment.js b/lib/less/tree/comment.js index 6983c6300..6566950c9 100644 --- a/lib/less/tree/comment.js +++ b/lib/less/tree/comment.js @@ -5,6 +5,7 @@ var Comment = function (value, isLineComment, index, currentFileInfo) { this.value = value; this.isLineComment = isLineComment; this.currentFileInfo = currentFileInfo; + this.allowRoot = true; }; Comment.prototype = new Node(); Comment.prototype.type = "Comment"; diff --git a/lib/less/tree/directive.js b/lib/less/tree/directive.js index 3e754d435..70be82c73 100644 --- a/lib/less/tree/directive.js +++ b/lib/less/tree/directive.js @@ -23,6 +23,7 @@ var Directive = function (name, value, rules, index, currentFileInfo, debugInfo, this.debugInfo = debugInfo; this.isRooted = isRooted || false; this.copyVisibilityInfo(visibilityInfo); + this.allowRoot = true; }; Directive.prototype = new Node(); diff --git a/lib/less/tree/extend.js b/lib/less/tree/extend.js index e51604243..c0661334f 100644 --- a/lib/less/tree/extend.js +++ b/lib/less/tree/extend.js @@ -9,7 +9,8 @@ var Extend = function Extend(selector, option, index, currentFileInfo, visibilit this.parent_ids = [this.object_id]; this.currentFileInfo = currentFileInfo || {}; this.copyVisibilityInfo(visibilityInfo); - + this.allowRoot = true; + switch(option) { case "all": this.allowBefore = true; diff --git a/lib/less/tree/import.js b/lib/less/tree/import.js index 57be4a75f..3787b052b 100644 --- a/lib/less/tree/import.js +++ b/lib/less/tree/import.js @@ -23,6 +23,7 @@ var Import = function (path, features, options, index, currentFileInfo, visibili this.path = path; this.features = features; this.currentFileInfo = currentFileInfo; + this.allowRoot = true; if (this.options.less !== undefined || this.options.inline) { this.css = !this.options.less || this.options.inline; diff --git a/lib/less/tree/media.js b/lib/less/tree/media.js index 436f6f14f..0bbd23a65 100644 --- a/lib/less/tree/media.js +++ b/lib/less/tree/media.js @@ -15,6 +15,7 @@ var Media = function (value, features, index, currentFileInfo, visibilityInfo) { this.rules = [new Ruleset(selectors, value)]; this.rules[0].allowImports = true; this.copyVisibilityInfo(visibilityInfo); + this.allowRoot = true; }; Media.prototype = new Directive(); Media.prototype.type = "Media"; diff --git a/lib/less/tree/mixin-call.js b/lib/less/tree/mixin-call.js index 254514524..5864a0c36 100644 --- a/lib/less/tree/mixin-call.js +++ b/lib/less/tree/mixin-call.js @@ -9,6 +9,7 @@ var MixinCall = function (elements, args, index, currentFileInfo, important) { this.index = index; this.currentFileInfo = currentFileInfo; this.important = important; + this.allowRoot = true; }; MixinCall.prototype = new Node(); MixinCall.prototype.type = "MixinCall"; diff --git a/lib/less/tree/mixin-definition.js b/lib/less/tree/mixin-definition.js index e7d1e0899..0477a8647 100644 --- a/lib/less/tree/mixin-definition.js +++ b/lib/less/tree/mixin-definition.js @@ -27,6 +27,7 @@ var Definition = function (name, params, rules, condition, variadic, frames, vis this.optionalParameters = optionalParameters; this.frames = frames; this.copyVisibilityInfo(visibilityInfo); + this.allowRoot = true; }; Definition.prototype = new Ruleset(); Definition.prototype.type = "MixinDefinition"; diff --git a/lib/less/tree/rule.js b/lib/less/tree/rule.js index c4318a964..99d168cff 100644 --- a/lib/less/tree/rule.js +++ b/lib/less/tree/rule.js @@ -12,6 +12,7 @@ var Rule = function (name, value, important, merge, index, currentFileInfo, inli this.inline = inline || false; this.variable = (variable !== undefined) ? variable : (name.charAt && (name.charAt(0) === '@')); + this.allowRoot = true; }; function evalName(context, name) { diff --git a/lib/less/tree/ruleset-call.js b/lib/less/tree/ruleset-call.js index 7a62c14dd..d271c8ddd 100644 --- a/lib/less/tree/ruleset-call.js +++ b/lib/less/tree/ruleset-call.js @@ -3,6 +3,7 @@ var Node = require("./node"), var RulesetCall = function (variable) { this.variable = variable; + this.allowRoot = true; }; RulesetCall.prototype = new Node(); RulesetCall.prototype.type = "RulesetCall"; diff --git a/lib/less/tree/ruleset.js b/lib/less/tree/ruleset.js index 92282e43a..c55370a9a 100644 --- a/lib/less/tree/ruleset.js +++ b/lib/less/tree/ruleset.js @@ -14,6 +14,7 @@ var Ruleset = function (selectors, rules, strictImports, visibilityInfo) { this._lookups = {}; this.strictImports = strictImports; this.copyVisibilityInfo(visibilityInfo); + this.allowRoot = true; }; Ruleset.prototype = new Node(); Ruleset.prototype.type = "Ruleset"; diff --git a/lib/less/visitors/to-css-visitor.js b/lib/less/visitors/to-css-visitor.js index 8d700b709..39474c09b 100644 --- a/lib/less/visitors/to-css-visitor.js +++ b/lib/less/visitors/to-css-visitor.js @@ -214,15 +214,8 @@ ToCSSVisitor.prototype = { throw { message: "Function '" + ruleNode.name + "' is undefined", index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename}; } - if (!ruleNode.isRulesetLike && - (ruleNode.type !== "Rule") && - (ruleNode.type !== "Comment") && - (ruleNode.type !== "Extend") && - (ruleNode.type !== "Import")) { - // I'm not quite sure about message, but considering these values can be here only - // as result of a "root-funtion" call, something close to - // "A value returned by function is unexpected here" or so could be more friendly - throw { message: "Invalid '" + ruleNode.type + "' value in a ruleset or root node", + if (!ruleNode.isRulesetLike && !ruleNode.allowRoot) { + throw { message: ruleNode.type + " returned by a function is not valid here.", index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename}; } } From 6e97db84b3c5668238b961215da806528c515ab2 Mon Sep 17 00:00:00 2001 From: Matthew Dean Date: Fri, 4 Mar 2016 14:10:53 -0700 Subject: [PATCH 5/7] Tests passing for creating directives --- lib/less/tree/extend.js | 2 +- test/css/plugin.css | 1 + test/less/plugin.less | 4 +++- test/less/plugin/plugin-root.js | 2 +- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/less/tree/extend.js b/lib/less/tree/extend.js index c0661334f..e91fbf77d 100644 --- a/lib/less/tree/extend.js +++ b/lib/less/tree/extend.js @@ -10,7 +10,7 @@ var Extend = function Extend(selector, option, index, currentFileInfo, visibilit this.currentFileInfo = currentFileInfo || {}; this.copyVisibilityInfo(visibilityInfo); this.allowRoot = true; - + switch(option) { case "all": this.allowBefore = true; diff --git a/test/css/plugin.css b/test/css/plugin.css index 5cb79c620..0b6910754 100644 --- a/test/css/plugin.css +++ b/test/css/plugin.css @@ -46,3 +46,4 @@ .root { prop: value; } +@arbitrary value after (); diff --git a/test/less/plugin.less b/test/less/plugin.less index 3414d4974..069165bee 100644 --- a/test/less/plugin.less +++ b/test/less/plugin.less @@ -87,5 +87,7 @@ @ruleset2(); } -test-directive("@charset"; "utf-8"); +test-directive("@charset"; '"utf-8"'); +test-directive("@arbitrary"; "value after ()"); + diff --git a/test/less/plugin/plugin-root.js b/test/less/plugin/plugin-root.js index 8c4be52d7..360125d6d 100644 --- a/test/less/plugin/plugin-root.js +++ b/test/less/plugin/plugin-root.js @@ -4,7 +4,7 @@ functions.addMultiple({ return new tree.DetachedRuleset(new tree.Ruleset("", [ rule ])); }, "test-directive": function(arg1, arg2) { - return new tree.Directive(arg1.value, new tree.Anonymous('"' + arg2.value + '"')); + return new tree.Directive(arg1.value, new tree.Anonymous(arg2.value)); }, // Functions must return something. Must 'return true' if they produce no output. "test-undefined": function() { } From d061bdb2f1b8794c17b9f4d1d0343fd997d6b2d5 Mon Sep 17 00:00:00 2001 From: Matthew Dean Date: Sat, 5 Mar 2016 14:31:13 -0700 Subject: [PATCH 6/7] Added tests for valid and invalid nodes returned by functions --- lib/less/tree/anonymous.js | 2 +- lib/less/visitors/to-css-visitor.js | 4 +- test/less/errors/functions-1.less | 2 + test/less/errors/functions-1.txt | 3 + test/less/errors/functions-10-keyword.less | 2 + test/less/errors/functions-10-keyword.txt | 3 + test/less/errors/functions-11-operation.less | 2 + test/less/errors/functions-11-operation.txt | 3 + test/less/errors/functions-12-quoted.less | 2 + test/less/errors/functions-12-quoted.txt | 3 + test/less/errors/functions-13-selector.less | 2 + test/less/errors/functions-13-selector.txt | 3 + test/less/errors/functions-14-url.less | 2 + test/less/errors/functions-14-url.txt | 3 + test/less/errors/functions-15-value.less | 2 + test/less/errors/functions-15-value.txt | 3 + test/less/errors/functions-2-alpha.less | 2 + test/less/errors/functions-2-alpha.txt | 3 + test/less/errors/functions-3-assignment.less | 2 + test/less/errors/functions-3-assignment.txt | 3 + test/less/errors/functions-4-call.less | 2 + test/less/errors/functions-4-call.txt | 3 + test/less/errors/functions-5-color-2.less | 1 + test/less/errors/functions-5-color-2.txt | 2 + test/less/errors/functions-5-color.less | 2 + test/less/errors/functions-5-color.txt | 3 + test/less/errors/functions-6-condition.less | 2 + test/less/errors/functions-6-condition.txt | 3 + test/less/errors/functions-7-dimension.less | 2 + test/less/errors/functions-7-dimension.txt | 3 + test/less/errors/functions-8-element.less | 2 + test/less/errors/functions-8-element.txt | 3 + test/less/errors/functions-9-expression.less | 2 + test/less/errors/functions-9-expression.txt | 3 + test/less/errors/root-func-undefined-2.less | 2 +- test/less/errors/root-func-undefined-2.txt | 2 +- test/less/plugin.less | 2 +- test/less/plugin/plugin-root.js | 11 --- test/less/plugin/plugin-tree-nodes.js | 80 ++++++++++++++++++++ 39 files changed, 164 insertions(+), 17 deletions(-) create mode 100644 test/less/errors/functions-1.less create mode 100644 test/less/errors/functions-1.txt create mode 100644 test/less/errors/functions-10-keyword.less create mode 100644 test/less/errors/functions-10-keyword.txt create mode 100644 test/less/errors/functions-11-operation.less create mode 100644 test/less/errors/functions-11-operation.txt create mode 100644 test/less/errors/functions-12-quoted.less create mode 100644 test/less/errors/functions-12-quoted.txt create mode 100644 test/less/errors/functions-13-selector.less create mode 100644 test/less/errors/functions-13-selector.txt create mode 100644 test/less/errors/functions-14-url.less create mode 100644 test/less/errors/functions-14-url.txt create mode 100644 test/less/errors/functions-15-value.less create mode 100644 test/less/errors/functions-15-value.txt create mode 100644 test/less/errors/functions-2-alpha.less create mode 100644 test/less/errors/functions-2-alpha.txt create mode 100644 test/less/errors/functions-3-assignment.less create mode 100644 test/less/errors/functions-3-assignment.txt create mode 100644 test/less/errors/functions-4-call.less create mode 100644 test/less/errors/functions-4-call.txt create mode 100644 test/less/errors/functions-5-color-2.less create mode 100644 test/less/errors/functions-5-color-2.txt create mode 100644 test/less/errors/functions-5-color.less create mode 100644 test/less/errors/functions-5-color.txt create mode 100644 test/less/errors/functions-6-condition.less create mode 100644 test/less/errors/functions-6-condition.txt create mode 100644 test/less/errors/functions-7-dimension.less create mode 100644 test/less/errors/functions-7-dimension.txt create mode 100644 test/less/errors/functions-8-element.less create mode 100644 test/less/errors/functions-8-element.txt create mode 100644 test/less/errors/functions-9-expression.less create mode 100644 test/less/errors/functions-9-expression.txt delete mode 100644 test/less/plugin/plugin-root.js create mode 100644 test/less/plugin/plugin-tree-nodes.js diff --git a/lib/less/tree/anonymous.js b/lib/less/tree/anonymous.js index d3da585ad..ec4f31304 100644 --- a/lib/less/tree/anonymous.js +++ b/lib/less/tree/anonymous.js @@ -6,7 +6,7 @@ var Anonymous = function (value, index, currentFileInfo, mapLines, rulesetLike, this.mapLines = mapLines; this.currentFileInfo = currentFileInfo; this.rulesetLike = (typeof rulesetLike === 'undefined') ? false : rulesetLike; - + this.allowRoot = true; this.copyVisibilityInfo(visibilityInfo); }; Anonymous.prototype = new Node(); diff --git a/lib/less/visitors/to-css-visitor.js b/lib/less/visitors/to-css-visitor.js index 39474c09b..9dc755f98 100644 --- a/lib/less/visitors/to-css-visitor.js +++ b/lib/less/visitors/to-css-visitor.js @@ -214,8 +214,8 @@ ToCSSVisitor.prototype = { throw { message: "Function '" + ruleNode.name + "' is undefined", index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename}; } - if (!ruleNode.isRulesetLike && !ruleNode.allowRoot) { - throw { message: ruleNode.type + " returned by a function is not valid here.", + if (!ruleNode.allowRoot) { + throw { message: ruleNode.type + " node returned by a function is not valid here", index: ruleNode.index, filename: ruleNode.currentFileInfo && ruleNode.currentFileInfo.filename}; } } diff --git a/test/less/errors/functions-1.less b/test/less/errors/functions-1.less new file mode 100644 index 000000000..f502aa276 --- /dev/null +++ b/test/less/errors/functions-1.less @@ -0,0 +1,2 @@ +@plugin "../plugin/plugin-tree-nodes"; +test-undefined(); \ No newline at end of file diff --git a/test/less/errors/functions-1.txt b/test/less/errors/functions-1.txt new file mode 100644 index 000000000..abeb4bda5 --- /dev/null +++ b/test/less/errors/functions-1.txt @@ -0,0 +1,3 @@ +SyntaxError: Function 'test-undefined' is undefined in {path}functions-1.less on line 2, column 1: +1 @plugin "../plugin/plugin-tree-nodes"; +2 test-undefined(); diff --git a/test/less/errors/functions-10-keyword.less b/test/less/errors/functions-10-keyword.less new file mode 100644 index 000000000..16d0b9858 --- /dev/null +++ b/test/less/errors/functions-10-keyword.less @@ -0,0 +1,2 @@ +@plugin "../plugin/plugin-tree-nodes"; +test-keyword(); \ No newline at end of file diff --git a/test/less/errors/functions-10-keyword.txt b/test/less/errors/functions-10-keyword.txt new file mode 100644 index 000000000..dabe839d6 --- /dev/null +++ b/test/less/errors/functions-10-keyword.txt @@ -0,0 +1,3 @@ +SyntaxError: Keyword node returned by a function is not valid here in {path}functions-10-keyword.less on line 2, column 1: +1 @plugin "../plugin/plugin-tree-nodes"; +2 test-keyword(); diff --git a/test/less/errors/functions-11-operation.less b/test/less/errors/functions-11-operation.less new file mode 100644 index 000000000..5695bdb91 --- /dev/null +++ b/test/less/errors/functions-11-operation.less @@ -0,0 +1,2 @@ +@plugin "../plugin/plugin-tree-nodes"; +test-operation(); \ No newline at end of file diff --git a/test/less/errors/functions-11-operation.txt b/test/less/errors/functions-11-operation.txt new file mode 100644 index 000000000..27287179c --- /dev/null +++ b/test/less/errors/functions-11-operation.txt @@ -0,0 +1,3 @@ +SyntaxError: Operation node returned by a function is not valid here in {path}functions-11-operation.less on line 2, column 1: +1 @plugin "../plugin/plugin-tree-nodes"; +2 test-operation(); diff --git a/test/less/errors/functions-12-quoted.less b/test/less/errors/functions-12-quoted.less new file mode 100644 index 000000000..d35be8710 --- /dev/null +++ b/test/less/errors/functions-12-quoted.less @@ -0,0 +1,2 @@ +@plugin "../plugin/plugin-tree-nodes"; +test-quoted(); \ No newline at end of file diff --git a/test/less/errors/functions-12-quoted.txt b/test/less/errors/functions-12-quoted.txt new file mode 100644 index 000000000..45c62ea64 --- /dev/null +++ b/test/less/errors/functions-12-quoted.txt @@ -0,0 +1,3 @@ +SyntaxError: Quoted node returned by a function is not valid here in {path}functions-12-quoted.less on line 2, column 1: +1 @plugin "../plugin/plugin-tree-nodes"; +2 test-quoted(); diff --git a/test/less/errors/functions-13-selector.less b/test/less/errors/functions-13-selector.less new file mode 100644 index 000000000..2fd879c60 --- /dev/null +++ b/test/less/errors/functions-13-selector.less @@ -0,0 +1,2 @@ +@plugin "../plugin/plugin-tree-nodes"; +test-selector(); \ No newline at end of file diff --git a/test/less/errors/functions-13-selector.txt b/test/less/errors/functions-13-selector.txt new file mode 100644 index 000000000..2f4b097f2 --- /dev/null +++ b/test/less/errors/functions-13-selector.txt @@ -0,0 +1,3 @@ +SyntaxError: Selector node returned by a function is not valid here in {path}functions-13-selector.less on line 2, column 1: +1 @plugin "../plugin/plugin-tree-nodes"; +2 test-selector(); diff --git a/test/less/errors/functions-14-url.less b/test/less/errors/functions-14-url.less new file mode 100644 index 000000000..bed6dabff --- /dev/null +++ b/test/less/errors/functions-14-url.less @@ -0,0 +1,2 @@ +@plugin "../plugin/plugin-tree-nodes"; +test-url(); \ No newline at end of file diff --git a/test/less/errors/functions-14-url.txt b/test/less/errors/functions-14-url.txt new file mode 100644 index 000000000..aeb275cab --- /dev/null +++ b/test/less/errors/functions-14-url.txt @@ -0,0 +1,3 @@ +SyntaxError: Url node returned by a function is not valid here in {path}functions-14-url.less on line 2, column 1: +1 @plugin "../plugin/plugin-tree-nodes"; +2 test-url(); diff --git a/test/less/errors/functions-15-value.less b/test/less/errors/functions-15-value.less new file mode 100644 index 000000000..189ce1967 --- /dev/null +++ b/test/less/errors/functions-15-value.less @@ -0,0 +1,2 @@ +@plugin "../plugin/plugin-tree-nodes"; +test-value(); \ No newline at end of file diff --git a/test/less/errors/functions-15-value.txt b/test/less/errors/functions-15-value.txt new file mode 100644 index 000000000..41f6e6a17 --- /dev/null +++ b/test/less/errors/functions-15-value.txt @@ -0,0 +1,3 @@ +SyntaxError: Value node returned by a function is not valid here in {path}functions-15-value.less on line 2, column 1: +1 @plugin "../plugin/plugin-tree-nodes"; +2 test-value(); diff --git a/test/less/errors/functions-2-alpha.less b/test/less/errors/functions-2-alpha.less new file mode 100644 index 000000000..f00da0788 --- /dev/null +++ b/test/less/errors/functions-2-alpha.less @@ -0,0 +1,2 @@ +@plugin "../plugin/plugin-tree-nodes"; +test-alpha(); \ No newline at end of file diff --git a/test/less/errors/functions-2-alpha.txt b/test/less/errors/functions-2-alpha.txt new file mode 100644 index 000000000..38a172731 --- /dev/null +++ b/test/less/errors/functions-2-alpha.txt @@ -0,0 +1,3 @@ +SyntaxError: Alpha node returned by a function is not valid here in {path}functions-2-alpha.less on line 2, column 1: +1 @plugin "../plugin/plugin-tree-nodes"; +2 test-alpha(); diff --git a/test/less/errors/functions-3-assignment.less b/test/less/errors/functions-3-assignment.less new file mode 100644 index 000000000..fe7f5ade4 --- /dev/null +++ b/test/less/errors/functions-3-assignment.less @@ -0,0 +1,2 @@ +@plugin "../plugin/plugin-tree-nodes"; +test-assignment(); \ No newline at end of file diff --git a/test/less/errors/functions-3-assignment.txt b/test/less/errors/functions-3-assignment.txt new file mode 100644 index 000000000..35c199265 --- /dev/null +++ b/test/less/errors/functions-3-assignment.txt @@ -0,0 +1,3 @@ +SyntaxError: Assignment node returned by a function is not valid here in {path}functions-3-assignment.less on line 2, column 1: +1 @plugin "../plugin/plugin-tree-nodes"; +2 test-assignment(); diff --git a/test/less/errors/functions-4-call.less b/test/less/errors/functions-4-call.less new file mode 100644 index 000000000..6b55c88a7 --- /dev/null +++ b/test/less/errors/functions-4-call.less @@ -0,0 +1,2 @@ +@plugin "../plugin/plugin-tree-nodes"; +test-call(); \ No newline at end of file diff --git a/test/less/errors/functions-4-call.txt b/test/less/errors/functions-4-call.txt new file mode 100644 index 000000000..338582d7c --- /dev/null +++ b/test/less/errors/functions-4-call.txt @@ -0,0 +1,3 @@ +SyntaxError: Function 'foo' is undefined in {path}functions-4-call.less on line 2, column 1: +1 @plugin "../plugin/plugin-tree-nodes"; +2 test-call(); diff --git a/test/less/errors/functions-5-color-2.less b/test/less/errors/functions-5-color-2.less new file mode 100644 index 000000000..4839416b0 --- /dev/null +++ b/test/less/errors/functions-5-color-2.less @@ -0,0 +1 @@ +rgba(0,0,0,0); \ No newline at end of file diff --git a/test/less/errors/functions-5-color-2.txt b/test/less/errors/functions-5-color-2.txt new file mode 100644 index 000000000..8b36fd985 --- /dev/null +++ b/test/less/errors/functions-5-color-2.txt @@ -0,0 +1,2 @@ +SyntaxError: Color node returned by a function is not valid here in {path}functions-5-color-2.less on line 1, column 1: +1 rgba(0,0,0,0); diff --git a/test/less/errors/functions-5-color.less b/test/less/errors/functions-5-color.less new file mode 100644 index 000000000..700ec5b92 --- /dev/null +++ b/test/less/errors/functions-5-color.less @@ -0,0 +1,2 @@ +@plugin "../plugin/plugin-tree-nodes"; +test-color(); \ No newline at end of file diff --git a/test/less/errors/functions-5-color.txt b/test/less/errors/functions-5-color.txt new file mode 100644 index 000000000..fdcd1a08a --- /dev/null +++ b/test/less/errors/functions-5-color.txt @@ -0,0 +1,3 @@ +SyntaxError: Color node returned by a function is not valid here in {path}functions-5-color.less on line 2, column 1: +1 @plugin "../plugin/plugin-tree-nodes"; +2 test-color(); diff --git a/test/less/errors/functions-6-condition.less b/test/less/errors/functions-6-condition.less new file mode 100644 index 000000000..db1000b83 --- /dev/null +++ b/test/less/errors/functions-6-condition.less @@ -0,0 +1,2 @@ +@plugin "../plugin/plugin-tree-nodes"; +test-condition(); \ No newline at end of file diff --git a/test/less/errors/functions-6-condition.txt b/test/less/errors/functions-6-condition.txt new file mode 100644 index 000000000..421bba5f5 --- /dev/null +++ b/test/less/errors/functions-6-condition.txt @@ -0,0 +1,3 @@ +SyntaxError: Condition node returned by a function is not valid here in {path}functions-6-condition.less on line 2, column 1: +1 @plugin "../plugin/plugin-tree-nodes"; +2 test-condition(); diff --git a/test/less/errors/functions-7-dimension.less b/test/less/errors/functions-7-dimension.less new file mode 100644 index 000000000..c399d33e2 --- /dev/null +++ b/test/less/errors/functions-7-dimension.less @@ -0,0 +1,2 @@ +@plugin "../plugin/plugin-tree-nodes"; +test-dimension(); \ No newline at end of file diff --git a/test/less/errors/functions-7-dimension.txt b/test/less/errors/functions-7-dimension.txt new file mode 100644 index 000000000..3b1b7026c --- /dev/null +++ b/test/less/errors/functions-7-dimension.txt @@ -0,0 +1,3 @@ +SyntaxError: Dimension node returned by a function is not valid here in {path}functions-7-dimension.less on line 2, column 1: +1 @plugin "../plugin/plugin-tree-nodes"; +2 test-dimension(); diff --git a/test/less/errors/functions-8-element.less b/test/less/errors/functions-8-element.less new file mode 100644 index 000000000..c762aad81 --- /dev/null +++ b/test/less/errors/functions-8-element.less @@ -0,0 +1,2 @@ +@plugin "../plugin/plugin-tree-nodes"; +test-element(); \ No newline at end of file diff --git a/test/less/errors/functions-8-element.txt b/test/less/errors/functions-8-element.txt new file mode 100644 index 000000000..b505d9543 --- /dev/null +++ b/test/less/errors/functions-8-element.txt @@ -0,0 +1,3 @@ +SyntaxError: Element node returned by a function is not valid here in {path}functions-8-element.less on line 2, column 1: +1 @plugin "../plugin/plugin-tree-nodes"; +2 test-element(); diff --git a/test/less/errors/functions-9-expression.less b/test/less/errors/functions-9-expression.less new file mode 100644 index 000000000..5f0bf46c4 --- /dev/null +++ b/test/less/errors/functions-9-expression.less @@ -0,0 +1,2 @@ +@plugin "../plugin/plugin-tree-nodes"; +test-expression(); \ No newline at end of file diff --git a/test/less/errors/functions-9-expression.txt b/test/less/errors/functions-9-expression.txt new file mode 100644 index 000000000..224db785e --- /dev/null +++ b/test/less/errors/functions-9-expression.txt @@ -0,0 +1,3 @@ +SyntaxError: Expression node returned by a function is not valid here in {path}functions-9-expression.less on line 2, column 1: +1 @plugin "../plugin/plugin-tree-nodes"; +2 test-expression(); diff --git a/test/less/errors/root-func-undefined-2.less b/test/less/errors/root-func-undefined-2.less index daf06ea1d..ee34616e1 100644 --- a/test/less/errors/root-func-undefined-2.less +++ b/test/less/errors/root-func-undefined-2.less @@ -1,2 +1,2 @@ -@plugin "../plugin/plugin-root.js"; +@plugin "../plugin/plugin-tree-nodes.js"; test-undefined(); \ No newline at end of file diff --git a/test/less/errors/root-func-undefined-2.txt b/test/less/errors/root-func-undefined-2.txt index 525851d33..031385d01 100644 --- a/test/less/errors/root-func-undefined-2.txt +++ b/test/less/errors/root-func-undefined-2.txt @@ -1,3 +1,3 @@ SyntaxError: Function 'test-undefined' is undefined in {path}root-func-undefined-2.less on line 2, column 1: -1 @plugin "../plugin/plugin-root.js"; +1 @plugin "../plugin/plugin-tree-nodes.js"; 2 test-undefined(); diff --git a/test/less/plugin.less b/test/less/plugin.less index 069165bee..66775ea9f 100644 --- a/test/less/plugin.less +++ b/test/less/plugin.less @@ -81,7 +81,7 @@ } } -@plugin "./plugin/plugin-root"; +@plugin "./plugin/plugin-tree-nodes"; @ruleset2: test-detached-ruleset(); .root { @ruleset2(); diff --git a/test/less/plugin/plugin-root.js b/test/less/plugin/plugin-root.js deleted file mode 100644 index 360125d6d..000000000 --- a/test/less/plugin/plugin-root.js +++ /dev/null @@ -1,11 +0,0 @@ -functions.addMultiple({ - "test-detached-ruleset" : function() { - var rule = new tree.Rule('prop', new tree.Anonymous('value')); - return new tree.DetachedRuleset(new tree.Ruleset("", [ rule ])); - }, - "test-directive": function(arg1, arg2) { - return new tree.Directive(arg1.value, new tree.Anonymous(arg2.value)); - }, - // Functions must return something. Must 'return true' if they produce no output. - "test-undefined": function() { } -}); \ No newline at end of file diff --git a/test/less/plugin/plugin-tree-nodes.js b/test/less/plugin/plugin-tree-nodes.js new file mode 100644 index 000000000..442352d7f --- /dev/null +++ b/test/less/plugin/plugin-tree-nodes.js @@ -0,0 +1,80 @@ +functions.addMultiple({ + + "test-comment": function() { + return new tree.Combinator(' '); + }, + "test-directive": function(arg1, arg2) { + return new tree.Directive(arg1.value, new tree.Anonymous(arg2.value)); + }, + "test-extend": function() { + //TODO + }, + "test-import": function() { + //TODO + }, + "test-media": function() { + //TODO + }, + "test-mixin-call": function() { + //TODO + }, + "test-mixin-definition": function() { + //TODO + }, + "test-ruleset-call": function() { + return new tree.Combinator(' '); + }, + // Functions must return something. Must 'return true' if they produce no output. + "test-undefined": function() { }, + + // These cause root errors + "test-alpha": function() { + return new tree.Alpha(30); + }, + "test-assignment": function() { + return new tree.Assignment("bird", "robin"); + }, + "test-attribute": function() { + return new tree.Attribute("foo", "=", "bar"); + }, + "test-call": function() { + return new tree.Call("foo"); + }, + "test-color": function() { + return new tree.Color([50, 50, 50]); + }, + "test-condition": function() { + return new tree.Condition('<', new tree.Value([0]), new tree.Value([1])); + }, + "test-detached-ruleset" : function() { + var rule = new tree.Rule('prop', new tree.Anonymous('value')); + return new tree.DetachedRuleset(new tree.Ruleset("", [ rule ])); + }, + "test-dimension": function() { + return new tree.Dimension(1, 'px'); + }, + "test-element": function() { + return new tree.Element('+', 'a'); + }, + "test-expression": function() { + return new tree.Expression([1, 2, 3]); + }, + "test-keyword": function() { + return new tree.Keyword('foo'); + }, + "test-operation": function() { + return new tree.Operation('+', [1, 2]); + }, + "test-quoted": function() { + return new tree.Quoted('"', 'foo'); + }, + "test-selector": function() { + return new tree.Selector([new tree.Element('a')]); + }, + "test-url": function() { + return new tree.URL('http://google.com'); + }, + "test-value": function() { + return new tree.Value([1]); + } +}); \ No newline at end of file From 87d59fabd6468a5e01daf8aefb0df1a3387d6d8f Mon Sep 17 00:00:00 2001 From: Matthew Dean Date: Tue, 15 Mar 2016 09:42:34 -0700 Subject: [PATCH 7/7] Fix attempt for Travis build --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index 1457ce05b..b71e6844e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,6 +4,11 @@ node_js: - "4.0.0" - "0.12" - "0.10" +before_install: + - mkdir travis-phantomjs + - wget https://bitbucket.org/ariya/phantomjs/downloads/phantomjs-2.1.1-linux-x86_64.tar.bz2 -O $PWD/travis-phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2 + - tar -xvf $PWD/travis-phantomjs/phantomjs-2.1.1-linux-x86_64.tar.bz2 -C $PWD/travis-phantomjs + - export PATH=$PWD/travis-phantomjs/phantomjs-2.1.1-linux-x86_64/bin:$PATH install: - npm install -g grunt-cli - npm install