From e82536bfcac5d573b2eb508eb4069481366b9744 Mon Sep 17 00:00:00 2001 From: Luke Page Date: Tue, 19 Mar 2013 13:54:08 +0000 Subject: [PATCH] Simplify more of loadFile and make more of the env creation common between node and browser --- lib/less/browser.js | 78 +++++++++++++++++++++------------------------ lib/less/env.js | 1 + lib/less/index.js | 1 - lib/less/parser.js | 15 ++++----- 4 files changed, 44 insertions(+), 51 deletions(-) diff --git a/lib/less/browser.js b/lib/less/browser.js index 168a1e9b..0d777fd4 100644 --- a/lib/less/browser.js +++ b/lib/less/browser.js @@ -251,14 +251,30 @@ function loadStyleSheet(sheet, callback, reload, remaining) { var env = new less.tree.parseEnv(less); env.mime = sheet.type; - env.currentFileInfo = null; - loadFile(sheet, env, function(e, data, sheet, webInfo, path, env) { + loadFile(sheet, env, null, function(e, data, sheet, webInfo, path, newFileInfo) { if (webInfo) { webInfo.remaining = remaining; + + var css = cache && cache.getItem(path), + timestamp = cache && cache.getItem(path + ':timestamp'); + + if (!reload && timestamp && webInfo.lastModified && + (new(Date)(webInfo.lastModified).valueOf() === + new(Date)(timestamp).valueOf())) { + // Use local copy + createCSS(css, sheet); + webInfo.local = true; + callback(null, null, data, sheet, webInfo, path); + return; + } } + //TODO add tests around how this behaves when reloading + removeNode(document.getElementById('less-error-message:' + extractId(path))); + if (data) { + env.currentFileInfo = newFileInfo; new(less.Parser)(env).parse(data, function (e, root) { if (e) { return callback(e, null, null, sheet); } try { @@ -273,37 +289,36 @@ function loadStyleSheet(sheet, callback, reload, remaining) { }, reload); } -function loadFile(sheet, env, callback, reload) { +function loadFile(sheet, env, currentFileInfo, callback) { + + if (currentFileInfo && currentFileInfo.currentDirectory && !/^([a-z-]+:)?\//.test(sheet.href)) { + sheet.href = currentFileInfo.currentDirectory + sheet.href; + } // sheet may be set to the stylesheet for the initial load or a collection of properties including // some env variables for imports var hrefParts = extractUrlParts(sheet.href, window.location.href); var href = hrefParts.url; - var css = cache && cache.getItem(href); - var timestamp = cache && cache.getItem(href + ':timestamp'); - var styles = { css: css, timestamp: timestamp }; var newFileInfo = { - relativeUrls: less.relativeUrls, currentDirectory: hrefParts.path, filename: href }; - if (env.currentFileInfo) { - env = new less.tree.parseEnv(env); - newFileInfo.entryPath = env.currentFileInfo.entryPath; - newFileInfo.rootpath = env.currentFileInfo.rootpath; - newFileInfo.rootFilename = env.currentFileInfo.rootFilename; + if (currentFileInfo) { + newFileInfo.entryPath = currentFileInfo.entryPath; + newFileInfo.rootpath = currentFileInfo.rootpath; + newFileInfo.rootFilename = currentFileInfo.rootFilename; + newFileInfo.relativeUrls = currentFileInfo.relativeUrls; } else { newFileInfo.entryPath = hrefParts.path; newFileInfo.rootpath = less.rootpath || hrefParts.path; newFileInfo.rootFilename = href; + newFileInfo.relativeUrls = env.relativeUrls; } - if (env.relativeUrls) { - //todo - this relies on option being set on less object rather than being passed in as an option - // - need an originalRootpath - if (less.rootpath) { - newFileInfo.rootpath = extractUrlParts(less.rootpath + pathDiff(hrefParts.path, newFileInfo.entryPath)).path; + if (newFileInfo.relativeUrls) { + if (env.rootpath) { + newFileInfo.rootpath = extractUrlParts(env.rootpath + pathDiff(hrefParts.path, newFileInfo.entryPath)).path; } else { newFileInfo.rootpath = hrefParts.path; } @@ -313,30 +328,11 @@ function loadFile(sheet, env, callback, reload) { // Store data this session session_cache += data.replace(/@import .+?;/ig, ''); - if (!reload && styles && lastModified && - (new(Date)(lastModified).valueOf() === - new(Date)(styles.timestamp).valueOf())) { - // Use local copy - createCSS(styles.css, sheet); - callback(null, data, sheet, { local: true }, href); - } else { - // Use remote copy (re-parse) - try { - env.contents[href] = data; // Updating content cache - env.paths = [hrefParts.path]; - env.currentFileInfo = newFileInfo; - - //TODO - there must be a better way? A generic less-to-css function that can both call error - //and removeNode where appropriate - //should also add tests - if (newFileInfo.rootFilename === href) { - removeNode(document.getElementById('less-error-message:' + extractId(href))); - } - - callback(null, data, sheet, { local: false, lastModified: lastModified }, href, env) - } catch (e) { - callback(e, null, sheet); - } + // Use remote copy (re-parse) + try { + callback(null, data, sheet, { lastModified: lastModified }, href, newFileInfo) + } catch (e) { + callback(e, null, sheet); } }, function (status, url) { callback({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")" }, null, sheet); diff --git a/lib/less/env.js b/lib/less/env.js index 6d46f393..35bc0a6a 100644 --- a/lib/less/env.js +++ b/lib/less/env.js @@ -6,6 +6,7 @@ 'files', // list of files that have been imported, used for import-once 'contents', // browser-only, contents of all the files 'relativeUrls', // option - whether to adjust URL's to be relative + 'rootpath', // option - rootpath to append to URL's 'strictImports', // option - 'dumpLineNumbers', // option - whether to dump line numbers 'compress', // option - whether to compress diff --git a/lib/less/index.js b/lib/less/index.js index 0207f4c1..3d4a32d2 100644 --- a/lib/less/index.js +++ b/lib/less/index.js @@ -131,7 +131,6 @@ less.Parser.fileLoader = function (file, currentFileInfo, callback, env) { newFileInfo.currentDirectory = pathname.replace(/[^\\\/]*$/, ""); newFileInfo.filename = pathname; - env.contents[pathname] = data; // Updating top importing parser content cache. env.currentFileInfo = newFileInfo; callback(null, data, pathname, env); diff --git a/lib/less/parser.js b/lib/less/parser.js index f3c5e186..21b68ae5 100644 --- a/lib/less/parser.js +++ b/lib/less/parser.js @@ -101,6 +101,7 @@ less.Parser = function Parser(env) { if (e) {fileParsedFunc(e); return;} env.processImports = false; + env.contents[fullPath] = contents; new(less.Parser)(env).parse(contents, function (e, root) { fileParsedFunc(e, root, fullPath); @@ -1603,17 +1604,13 @@ if (less.mode === 'browser' || less.mode === 'rhino') { // Used by `@import` directives // less.Parser.fileLoader = function (path, currentFileInfo, callback, env) { - if (!/^([a-z-]+:)?\//.test(path) && currentFileInfo.currentDirectory) { - path = currentFileInfo.currentDirectory + path; - } - // We pass `true` as 3rd argument, to force the reload of the import. - // This is so we can get the syntax tree as opposed to just the CSS output, - // as we need this to evaluate the current stylesheet. - loadFile({href: path, type: env.mime }, env, - function (e, data, sheet, webInfo, path, env) { + loadFile({href: path, type: env.mime }, env, currentFileInfo, + function (e, data, sheet, webInfo, path, newFileInfo) { + env = new less.tree.parseEnv(env); + env.currentFileInfo = newFileInfo; callback(e, data, path, env); - }, true); + }); }; }