From 6fc6dc2301b36889b756d69372cd74e02c210daa Mon Sep 17 00:00:00 2001 From: Luke Page Date: Tue, 19 Mar 2013 15:20:46 +0000 Subject: [PATCH] Add import inline option. Fixes #1209 --- lib/less/browser.js | 2 ++ lib/less/import-visitor.js | 21 +++++++++++++-------- lib/less/parser.js | 31 +++++++++++-------------------- lib/less/tree/import.js | 13 +++++++++---- test/css/import-inline.css | 3 +++ test/less/import-inline.less | 2 ++ test/less/import/invalid-css.less | 1 + 7 files changed, 41 insertions(+), 32 deletions(-) create mode 100644 test/css/import-inline.css create mode 100644 test/less/import-inline.less create mode 100644 test/less/import/invalid-css.less diff --git a/lib/less/browser.js b/lib/less/browser.js index 0be96213..27e400dd 100644 --- a/lib/less/browser.js +++ b/lib/less/browser.js @@ -339,6 +339,8 @@ function loadFile(originalHref, currentFileInfo, callback, env) { }); } +less.Parser.fileLoader = loadFile; + function extractId(href) { return href.replace(/^[a-z-]+:\/+?[^\/]+/, '' ) // Remove protocol & domain .replace(/^\//, '' ) // Remove root / diff --git a/lib/less/import-visitor.js b/lib/less/import-visitor.js index 5548430e..ac37f51c 100644 --- a/lib/less/import-visitor.js +++ b/lib/less/import-visitor.js @@ -27,9 +27,10 @@ }, visitImport: function (importNode, visitArgs) { var importVisitor = this, - evaldImportNode; + evaldImportNode, + inlineCSS = importNode.options.inline; - if (!importNode.css) { + if (!importNode.css || inlineCSS) { try { evaldImportNode = importNode.evalForImport(this.env); @@ -41,11 +42,12 @@ importNode.error = e; } - if (evaldImportNode && !evaldImportNode.css) { + if (evaldImportNode && (!evaldImportNode.css || inlineCSS)) { importNode = evaldImportNode; this.importCount++; var env = new tree.evalEnv(this.env, this.env.frames.slice(0)); - this._importer.push(importNode.getPath(), importNode.currentFileInfo, function (e, root, imported) { + + this._importer.push(importNode.getPath(), importNode.currentFileInfo, inlineCSS, function (e, root, imported) { if (e && !e.filename) { e.index = importNode.index; e.filename = importNode.currentFileInfo.filename; } if (imported && !importNode.options.multiple) { importNode.skip = imported; } @@ -59,11 +61,14 @@ if (root) { importNode.root = root; - new(tree.importVisitor)(importVisitor._importer, subFinish, env) - .run(root); - } else { - subFinish(); + if (!inlineCSS) { + new(tree.importVisitor)(importVisitor._importer, subFinish, env) + .run(root); + return; + } } + + subFinish(); }); } } diff --git a/lib/less/parser.js b/lib/less/parser.js index 2f919f09..40d8e425 100644 --- a/lib/less/parser.js +++ b/lib/less/parser.js @@ -78,20 +78,20 @@ less.Parser = function Parser(env) { contents: env.contents, // Holds the imported file contents mime: env.mime, // MIME type of .less files error: null, // Error in parsing/evaluating an import - push: function (path, currentFileInfo, callback) { + push: function (path, currentFileInfo, inlineCSS, callback) { var parserImports = this; this.queue.push(path); var fileParsedFunc = function (e, root, fullPath) { parserImports.queue.splice(parserImports.queue.indexOf(path), 1); // Remove the path from the queue - var imported = fullPath in parserImports.files; + var importedPreviously = fullPath in parserImports.files; parserImports.files[fullPath] = root; // Store the root if (e && !parserImports.error) { parserImports.error = e; } - callback(e, root, imported); + callback(e, root, importedPreviously); }; if (less.Parser.importer) { @@ -106,9 +106,13 @@ less.Parser = function Parser(env) { newEnv.processImports = false; newEnv.contents[fullPath] = contents; - new(less.Parser)(newEnv).parse(contents, function (e, root) { - fileParsedFunc(e, root, fullPath); - }); + if (inlineCSS) { + fileParsedFunc(null, contents, fullPath); + } else { + new(less.Parser)(newEnv).parse(contents, function (e, root) { + fileParsedFunc(e, root, fullPath); + }); + } }, env) } } @@ -1303,7 +1307,7 @@ less.Parser = function Parser(env) { }, importOption: function() { - var opt = $(/^(less|css|multiple|once)/); + var opt = $(/^(less|css|multiple|once|inline)/); if (opt) { return opt[1]; } @@ -1602,16 +1606,3 @@ less.Parser = function Parser(env) { }; }; -if (less.mode === 'browser' || less.mode === 'rhino') { - // - // Used by `@import` directives - // - less.Parser.fileLoader = function (path, currentFileInfo, callback, env) { - - loadFile(path, currentFileInfo, - function (e, data, path, newFileInfo) { - callback(e, data, path, newFileInfo); - }, env); - }; -} - diff --git a/lib/less/tree/import.js b/lib/less/tree/import.js index 9a93baaf..f81b09c0 100644 --- a/lib/less/tree/import.js +++ b/lib/less/tree/import.js @@ -20,8 +20,8 @@ tree.Import = function (path, features, options, index, currentFileInfo) { this.features = features; this.currentFileInfo = currentFileInfo; - if (this.options.less !== undefined) { - this.css = !this.options.less; + if (this.options.less !== undefined || this.options.inline) { + this.css = !this.options.less || this.options.inline; } else { var pathValue = this.getPath(); if (pathValue && /css([\?;].*)?$/.test(pathValue)) { @@ -44,7 +44,9 @@ tree.Import.prototype = { accept: function (visitor) { this.features = visitor.visit(this.features); this.path = visitor.visit(this.path); - this.root = visitor.visit(this.root); + if (!this.options.inline) { + this.root = visitor.visit(this.root); + } }, toCSS: function (env) { var features = this.features ? ' ' + this.features.toCSS(env) : ''; @@ -84,7 +86,10 @@ tree.Import.prototype = { if (this.skip) { return []; } - if (this.css) { + if (this.options.inline) { + var contents = new(tree.Anonymous)(this.root); + return this.features ? new(tree.Media)([contents], this.features.value) : [contents]; + } else if (this.css) { var newImport = new(tree.Import)(this.evalPath(env), features, this.options, this.index); if (!newImport.css && this.error) { throw this.error; diff --git a/test/css/import-inline.css b/test/css/import-inline.css new file mode 100644 index 00000000..1c17ab2a --- /dev/null +++ b/test/css/import-inline.css @@ -0,0 +1,3 @@ +this isn't very valid CSS. @media (min-width: 600px) { + #css { color: yellow; } +} diff --git a/test/less/import-inline.less b/test/less/import-inline.less new file mode 100644 index 00000000..95a11896 --- /dev/null +++ b/test/less/import-inline.less @@ -0,0 +1,2 @@ +@import (inline) url("import/import-test-d.css") (min-width:600px); +@import (inline, css) url("import/invalid-css.less"); \ No newline at end of file diff --git a/test/less/import/invalid-css.less b/test/less/import/invalid-css.less new file mode 100644 index 00000000..b7cad97b --- /dev/null +++ b/test/less/import/invalid-css.less @@ -0,0 +1 @@ +this isn't very valid CSS. \ No newline at end of file