[Pkg-javascript-commits] [less.js] 156/285: Seperate browser a bit more
Jonas Smedegaard
dr at jones.dk
Mon Oct 26 23:23:49 UTC 2015
This is an automated email from the git hooks/post-receive script.
js pushed a commit to annotated tag v2.0.0
in repository less.js.
commit cd0cf0e24353d6de9d687e146a2293d0fbc36a34
Author: Luke Page <luke.a.page at gmail.com>
Date: Tue Oct 7 21:47:35 2014 +0100
Seperate browser a bit more
---
Gruntfile.js | 3 +
lib/less-browser/browser.js | 57 ++++++++
lib/less-browser/error-reporting.js | 168 ++++++++++++++++++++++
lib/less-browser/index.js | 276 ++++--------------------------------
lib/less-browser/log-listener.js | 10 +-
lib/less-browser/utils.js | 9 ++
6 files changed, 273 insertions(+), 250 deletions(-)
diff --git a/Gruntfile.js b/Gruntfile.js
index 37275a7..b52fef8 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -103,6 +103,9 @@ module.exports = function (grunt) {
src: [
'Gruntfile.js',
'lib/less/**/*.js',
+ 'lib/less-node/**/*.js',
+ 'lib/less-browser/**/*.js',
+ 'lib/less-rhino/**/*.js',
'bin/lessc'
]
}
diff --git a/lib/less-browser/browser.js b/lib/less-browser/browser.js
new file mode 100644
index 0000000..09eb7b9
--- /dev/null
+++ b/lib/less-browser/browser.js
@@ -0,0 +1,57 @@
+var utils = require("./utils");
+module.exports = {
+ createCSS: function (document, styles, sheet, lastModified) {
+ // Strip the query-string
+ var href = sheet.href || '';
+
+ // If there is no title set, use the filename, minus the extension
+ var id = 'less:' + (sheet.title || utils.extractId(href));
+
+ // If this has already been inserted into the DOM, we may need to replace it
+ var oldCss = document.getElementById(id);
+ var keepOldCss = false;
+
+ // Create a new stylesheet node for insertion or (if necessary) replacement
+ var css = document.createElement('style');
+ css.setAttribute('type', 'text/css');
+ if (sheet.media) {
+ css.setAttribute('media', sheet.media);
+ }
+ css.id = id;
+
+ if (!css.styleSheet) {
+ css.appendChild(document.createTextNode(styles));
+
+ // If new contents match contents of oldCss, don't replace oldCss
+ keepOldCss = (oldCss !== null && oldCss.childNodes.length > 0 && css.childNodes.length > 0 &&
+ oldCss.firstChild.nodeValue === css.firstChild.nodeValue);
+ }
+
+ var head = document.getElementsByTagName('head')[0];
+
+ // If there is no oldCss, just append; otherwise, only append if we need
+ // to replace oldCss with an updated stylesheet
+ if (oldCss === null || keepOldCss === false) {
+ var nextEl = sheet && sheet.nextSibling || null;
+ if (nextEl) {
+ nextEl.parentNode.insertBefore(css, nextEl);
+ } else {
+ head.appendChild(css);
+ }
+ }
+ if (oldCss && keepOldCss === false) {
+ oldCss.parentNode.removeChild(oldCss);
+ }
+
+ // For IE.
+ // This needs to happen *after* the style element is added to the DOM, otherwise IE 7 and 8 may crash.
+ // See http://social.msdn.microsoft.com/Forums/en-US/7e081b65-878a-4c22-8e68-c10d39c2ed32/internet-explorer-crashes-appending-style-element-to-head
+ if (css.styleSheet) {
+ try {
+ css.styleSheet.cssText = styles;
+ } catch (e) {
+ throw new(Error)("Couldn't reassign styleSheet.cssText.");
+ }
+ }
+ }
+};
diff --git a/lib/less-browser/error-reporting.js b/lib/less-browser/error-reporting.js
new file mode 100644
index 0000000..54d23c2
--- /dev/null
+++ b/lib/less-browser/error-reporting.js
@@ -0,0 +1,168 @@
+var utils = require("./utils"),
+ browser = require("./browser");
+
+module.exports = function(window, less, options) {
+
+ function errorHTML(e, rootHref) {
+ var id = 'less-error-message:' + utils.extractId(rootHref || "");
+ var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
+ var elem = window.document.createElement('div'), timer, content, errors = [];
+ var filename = e.filename || rootHref;
+ var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1];
+
+ elem.id = id;
+ elem.className = "less-error-message";
+
+ content = '<h3>' + (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') +
+ '</h3>' + '<p>in <a href="' + filename + '">' + filenameNoPath + "</a> ";
+
+ var errorline = function (e, i, classname) {
+ if (e.extract[i] !== undefined) {
+ errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1))
+ .replace(/\{class\}/, classname)
+ .replace(/\{content\}/, e.extract[i]));
+ }
+ };
+
+ if (e.extract) {
+ errorline(e, 0, '');
+ errorline(e, 1, 'line');
+ errorline(e, 2, '');
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
+ '<ul>' + errors.join('') + '</ul>';
+ } else if (e.stack) {
+ content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
+ }
+ elem.innerHTML = content;
+
+ // CSS for error messages
+ browser.createCSS(window.document, [
+ '.less-error-message ul, .less-error-message li {',
+ 'list-style-type: none;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message label {',
+ 'font-size: 12px;',
+ 'margin-right: 15px;',
+ 'padding: 4px 0;',
+ 'color: #cc7777;',
+ '}',
+ '.less-error-message pre {',
+ 'color: #dd6666;',
+ 'padding: 4px 0;',
+ 'margin: 0;',
+ 'display: inline-block;',
+ '}',
+ '.less-error-message pre.line {',
+ 'color: #ff0000;',
+ '}',
+ '.less-error-message h3 {',
+ 'font-size: 20px;',
+ 'font-weight: bold;',
+ 'padding: 15px 0 5px 0;',
+ 'margin: 0;',
+ '}',
+ '.less-error-message a {',
+ 'color: #10a',
+ '}',
+ '.less-error-message .error {',
+ 'color: red;',
+ 'font-weight: bold;',
+ 'padding-bottom: 2px;',
+ 'border-bottom: 1px dashed red;',
+ '}'
+ ].join('\n'), { title: 'error-message' });
+
+ elem.style.cssText = [
+ "font-family: Arial, sans-serif",
+ "border: 1px solid #e00",
+ "background-color: #eee",
+ "border-radius: 5px",
+ "-webkit-border-radius: 5px",
+ "-moz-border-radius: 5px",
+ "color: #e00",
+ "padding: 15px",
+ "margin-bottom: 15px"
+ ].join(';');
+
+ if (options.env === 'development') {
+ timer = setInterval(function () {
+ var document = window.document,
+ body = document.body;
+ if (body) {
+ if (document.getElementById(id)) {
+ body.replaceChild(elem, document.getElementById(id));
+ } else {
+ body.insertBefore(elem, body.firstChild);
+ }
+ clearInterval(timer);
+ }
+ }, 10);
+ }
+ }
+
+ function error(e, rootHref) {
+ if (!options.errorReporting || options.errorReporting === "html") {
+ errorHTML(e, rootHref);
+ } else if (options.errorReporting === "console") {
+ errorConsole(e, rootHref);
+ } else if (typeof options.errorReporting === 'function') {
+ options.errorReporting("add", e, rootHref);
+ }
+ }
+
+ function removeErrorHTML(path) {
+ var node = window.document.getElementById('less-error-message:' + utils.extractId(path));
+ if (node) {
+ node.parentNode.removeChild(node);
+ }
+ }
+
+ function removeErrorConsole(path) {
+ //no action
+ }
+
+ function removeError(path) {
+ if (!options.errorReporting || options.errorReporting === "html") {
+ removeErrorHTML(path);
+ } else if (options.errorReporting === "console") {
+ removeErrorConsole(path);
+ } else if (typeof options.errorReporting === 'function') {
+ options.errorReporting("remove", path);
+ }
+ }
+
+ function errorConsole(e, rootHref) {
+ var template = '{line} {content}';
+ var filename = e.filename || rootHref;
+ var errors = [];
+ var content = (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') +
+ " in " + filename + " ";
+
+ var errorline = function (e, i, classname) {
+ if (e.extract[i] !== undefined) {
+ errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1))
+ .replace(/\{class\}/, classname)
+ .replace(/\{content\}/, e.extract[i]));
+ }
+ };
+
+ if (e.extract) {
+ errorline(e, 0, '');
+ errorline(e, 1, 'line');
+ errorline(e, 2, '');
+ content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\n' +
+ errors.join('\n');
+ } else if (e.stack) {
+ content += e.stack;
+ }
+ less.logger.error(content);
+ }
+
+ return {
+ add: error,
+ remove: removeError
+ };
+};
diff --git a/lib/less-browser/index.js b/lib/less-browser/index.js
index 4ddb66b..3494fb0 100644
--- a/lib/less-browser/index.js
+++ b/lib/less-browser/index.js
@@ -11,7 +11,7 @@ var less;
then access as less.environment.options.fileAsync ?
*/
-var isFileProtocol = /^(file|chrome(-extension)?|resource|qrc|app):/.test(location.protocol),
+var isFileProtocol = /^(file|chrome(-extension)?|resource|qrc|app):/.test(window.location.protocol),
options = window.less || {};
window.less = less = require('../less')(require("./environment"));
@@ -20,12 +20,15 @@ var environment = less.environment,
environment.addFileManager(browserImport);
require("./log-listener")(less, options);
-
-less.env = options.env || (location.hostname == '127.0.0.1' ||
- location.hostname == '0.0.0.0' ||
- location.hostname == 'localhost' ||
- (location.port &&
- location.port.length > 0) ||
+//var utils = require("./utils");
+var errors = require("./error-reporting")(window, less, options);
+var browser = require("./browser");
+
+options.env = options.env || (window.location.hostname == '127.0.0.1' ||
+ window.location.hostname == '0.0.0.0' ||
+ window.location.hostname == 'localhost' ||
+ (window.location.port &&
+ window.location.port.length > 0) ||
isFileProtocol ? 'development'
: 'production');
@@ -39,7 +42,7 @@ options.async = options.async || false;
options.fileAsync = options.fileAsync || false;
// Interval between watch polls
-less.poll = less.poll || (isFileProtocol ? 1000 : 1500);
+options.poll = options.poll || (isFileProtocol ? 1000 : 1500);
//Setup user functions
if (options.functions) {
@@ -48,114 +51,12 @@ if (options.functions) {
var dumpLineNumbers = /!dumpLineNumbers:(comments|mediaquery|all)/.exec(location.hash);
if (dumpLineNumbers) {
- less.dumpLineNumbers = dumpLineNumbers[1];
+ options.dumpLineNumbers = dumpLineNumbers[1];
}
var typePattern = /^text\/(x-)?less$/;
var cache = null;
-function extractId(href) {
- return href.replace(/^[a-z-]+:\/+?[^\/]+/, '' ) // Remove protocol & domain
- .replace(/^\//, '' ) // Remove root /
- .replace(/\.[a-zA-Z]+$/, '' ) // Remove simple extension
- .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
- .replace(/\./g, ':'); // Replace dots with colons(for valid id)
-}
-
-function errorConsole(e, rootHref) {
- var template = '{line} {content}';
- var filename = e.filename || rootHref;
- var errors = [];
- var content = (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') +
- " in " + filename + " ";
-
- var errorline = function (e, i, classname) {
- if (e.extract[i] !== undefined) {
- errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1))
- .replace(/\{class\}/, classname)
- .replace(/\{content\}/, e.extract[i]));
- }
- };
-
- if (e.extract) {
- errorline(e, 0, '');
- errorline(e, 1, 'line');
- errorline(e, 2, '');
- content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':\n' +
- errors.join('\n');
- } else if (e.stack) {
- content += e.stack;
- }
- less.logger.error(content);
-}
-
-function createCSS(styles, sheet, lastModified) {
- // Strip the query-string
- var href = sheet.href || '';
-
- // If there is no title set, use the filename, minus the extension
- var id = 'less:' + (sheet.title || extractId(href));
-
- // If this has already been inserted into the DOM, we may need to replace it
- var oldCss = document.getElementById(id);
- var keepOldCss = false;
-
- // Create a new stylesheet node for insertion or (if necessary) replacement
- var css = document.createElement('style');
- css.setAttribute('type', 'text/css');
- if (sheet.media) {
- css.setAttribute('media', sheet.media);
- }
- css.id = id;
-
- if (!css.styleSheet) {
- css.appendChild(document.createTextNode(styles));
-
- // If new contents match contents of oldCss, don't replace oldCss
- keepOldCss = (oldCss !== null && oldCss.childNodes.length > 0 && css.childNodes.length > 0 &&
- oldCss.firstChild.nodeValue === css.firstChild.nodeValue);
- }
-
- var head = document.getElementsByTagName('head')[0];
-
- // If there is no oldCss, just append; otherwise, only append if we need
- // to replace oldCss with an updated stylesheet
- if (oldCss === null || keepOldCss === false) {
- var nextEl = sheet && sheet.nextSibling || null;
- if (nextEl) {
- nextEl.parentNode.insertBefore(css, nextEl);
- } else {
- head.appendChild(css);
- }
- }
- if (oldCss && keepOldCss === false) {
- oldCss.parentNode.removeChild(oldCss);
- }
-
- // For IE.
- // This needs to happen *after* the style element is added to the DOM, otherwise IE 7 and 8 may crash.
- // See http://social.msdn.microsoft.com/Forums/en-US/7e081b65-878a-4c22-8e68-c10d39c2ed32/internet-explorer-crashes-appending-style-element-to-head
- if (css.styleSheet) {
- try {
- css.styleSheet.cssText = styles;
- } catch (e) {
- throw new(Error)("Couldn't reassign styleSheet.cssText.");
- }
- }
-
- // Don't update the local store if the file wasn't modified
- if (lastModified && cache) {
- less.logger.info('saving ' + href + ' to cache.');
- try {
- cache.setItem(href, styles);
- cache.setItem(href + ':timestamp', lastModified);
- } catch(e) {
- //TODO - could do with adding more robust error handling
- less.logger.error('failed to save');
- }
- }
-}
-
function postProcessCSS(styles) {
if (options.postProcessor && typeof options.postProcessor === 'function') {
styles = options.postProcessor.call(styles, styles) || styles;
@@ -163,134 +64,19 @@ function postProcessCSS(styles) {
return styles;
}
-function errorHTML(e, rootHref) {
- var id = 'less-error-message:' + extractId(rootHref || "");
- var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
- var elem = document.createElement('div'), timer, content, errors = [];
- var filename = e.filename || rootHref;
- var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1];
-
- elem.id = id;
- elem.className = "less-error-message";
-
- content = '<h3>' + (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') +
- '</h3>' + '<p>in <a href="' + filename + '">' + filenameNoPath + "</a> ";
+// Replace the cache system
+// Don't update the local store if the file wasn't modified
+//if (lastModified && cache) {
+// logger.info('saving ' + href + ' to cache.');
+// try {
+// cache.setItem(href, styles);
+// cache.setItem(href + ':timestamp', lastModified);
+// } catch(e) {
+// //TODO - could do with adding more robust error handling
+// logger.error('failed to save');
+// }//
+//}
- var errorline = function (e, i, classname) {
- if (e.extract[i] !== undefined) {
- errors.push(template.replace(/\{line\}/, (parseInt(e.line, 10) || 0) + (i - 1))
- .replace(/\{class\}/, classname)
- .replace(/\{content\}/, e.extract[i]));
- }
- };
-
- if (e.extract) {
- errorline(e, 0, '');
- errorline(e, 1, 'line');
- errorline(e, 2, '');
- content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
- '<ul>' + errors.join('') + '</ul>';
- } else if (e.stack) {
- content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
- }
- elem.innerHTML = content;
-
- // CSS for error messages
- createCSS([
- '.less-error-message ul, .less-error-message li {',
- 'list-style-type: none;',
- 'margin-right: 15px;',
- 'padding: 4px 0;',
- 'margin: 0;',
- '}',
- '.less-error-message label {',
- 'font-size: 12px;',
- 'margin-right: 15px;',
- 'padding: 4px 0;',
- 'color: #cc7777;',
- '}',
- '.less-error-message pre {',
- 'color: #dd6666;',
- 'padding: 4px 0;',
- 'margin: 0;',
- 'display: inline-block;',
- '}',
- '.less-error-message pre.line {',
- 'color: #ff0000;',
- '}',
- '.less-error-message h3 {',
- 'font-size: 20px;',
- 'font-weight: bold;',
- 'padding: 15px 0 5px 0;',
- 'margin: 0;',
- '}',
- '.less-error-message a {',
- 'color: #10a',
- '}',
- '.less-error-message .error {',
- 'color: red;',
- 'font-weight: bold;',
- 'padding-bottom: 2px;',
- 'border-bottom: 1px dashed red;',
- '}'
- ].join('\n'), { title: 'error-message' });
-
- elem.style.cssText = [
- "font-family: Arial, sans-serif",
- "border: 1px solid #e00",
- "background-color: #eee",
- "border-radius: 5px",
- "-webkit-border-radius: 5px",
- "-moz-border-radius: 5px",
- "color: #e00",
- "padding: 15px",
- "margin-bottom: 15px"
- ].join(';');
-
- if (less.env == 'development') {
- timer = setInterval(function () {
- if (document.body) {
- if (document.getElementById(id)) {
- document.body.replaceChild(elem, document.getElementById(id));
- } else {
- document.body.insertBefore(elem, document.body.firstChild);
- }
- clearInterval(timer);
- }
- }, 10);
- }
-}
-
-function error(e, rootHref) {
- if (!options.errorReporting || options.errorReporting === "html") {
- errorHTML(e, rootHref);
- } else if (options.errorReporting === "console") {
- errorConsole(e, rootHref);
- } else if (typeof options.errorReporting === 'function') {
- options.errorReporting("add", e, rootHref);
- }
-}
-
-function removeErrorHTML(path) {
- var node = document.getElementById('less-error-message:' + extractId(path));
- if (node) {
- node.parentNode.removeChild(node);
- }
-}
-
-function removeErrorConsole(path) {
- //no action
-}
-
-function removeError(path) {
- if (!options.errorReporting || options.errorReporting === "html") {
- removeErrorHTML(path);
- } else if (options.errorReporting === "console") {
- removeErrorConsole(path);
- } else if (typeof options.errorReporting === 'function') {
- options.errorReporting("remove", path);
- }
-}
function clone(obj) {
var cloned = {};
@@ -339,7 +125,7 @@ function loadStyles(modifyVars) {
}
}, null, style),
function(e) {
- error(e, "inline");
+ errors.add(e, "inline");
});
}
}
@@ -383,7 +169,7 @@ function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) {
(new(Date)(webInfo.lastModified).valueOf() ===
new(Date)(timestamp).valueOf())) {
// Use local copy
- createCSS(css, sheet);
+ browser.createCSS(window.document, css, sheet);
webInfo.local = true;
callback(null, null, data, sheet, webInfo, path);
return;
@@ -391,7 +177,7 @@ function loadStyleSheet(sheet, callback, reload, remaining, modifyVars) {
}
//TODO add tests around how this behaves when reloading
- removeError(path);
+ errors.remove(path);
instanceOptions.rootFileInfo = newFileInfo;
less.render(data, instanceOptions)
@@ -420,10 +206,10 @@ function initRunningMode(){
if (less.watchMode) {
loadStyleSheets(function (e, css, _, sheet, context) {
if (e) {
- error(e, e.href || sheet.href);
+ errors.add(e, e.href || sheet.href);
} else if (css) {
css = postProcessCSS(css);
- createCSS(css, sheet, context.lastModified);
+ browser.createCSS(window.document, css, sheet, context.lastModified);
}
});
}
@@ -483,14 +269,14 @@ less.refresh = function (reload, modifyVars) {
loadStyleSheets(function (e, css, _, sheet, webInfo) {
if (e) {
- return error(e, e.href || sheet.href);
+ return errors.add(e, e.href || sheet.href);
}
if (webInfo.local) {
less.logger.info("loading " + sheet.href + " from cache.");
} else {
less.logger.info("rendered " + sheet.href + " successfully.");
css = postProcessCSS(css);
- createCSS(css, sheet, webInfo.lastModified);
+ browser.createCSS(window.document, css, sheet, webInfo.lastModified);
}
less.logger.info("css for " + sheet.href + " generated in " + (new Date() - endTime) + 'ms');
if (webInfo.remaining === 0) {
diff --git a/lib/less-browser/log-listener.js b/lib/less-browser/log-listener.js
index 1b1ad59..9806c99 100644
--- a/lib/less-browser/log-listener.js
+++ b/lib/less-browser/log-listener.js
@@ -1,9 +1,9 @@
module.exports = function(less, options) {
- var logLevel_debug = 3,
- logLevel_info = 2,
- logLevel_errors = 1,
- logLevel_none = 0;
+ var logLevel_debug = 4,
+ logLevel_info = 3,
+ logLevel_warn = 2,
+ logLevel_error = 1;
// The amount of logging in the javascript console.
// 3 - Debug, information and errors
@@ -11,7 +11,7 @@ module.exports = function(less, options) {
// 1 - Errors
// 0 - None
// Defaults to 2
- options.logLevel = typeof(options.logLevel) !== 'undefined' ? options.logLevel : (options.env === 'development' ? logLevel_debug : logLevel_errors);
+ options.logLevel = typeof(options.logLevel) !== 'undefined' ? options.logLevel : (options.env === 'development' ? logLevel_debug : logLevel_error);
if (!options.loggers) {
options.loggers = [{
diff --git a/lib/less-browser/utils.js b/lib/less-browser/utils.js
new file mode 100644
index 0000000..8d6644f
--- /dev/null
+++ b/lib/less-browser/utils.js
@@ -0,0 +1,9 @@
+module.exports = {
+ extractId: function(href) {
+ return href.replace(/^[a-z-]+:\/+?[^\/]+/, '' ) // Remove protocol & domain
+ .replace(/^\//, '' ) // Remove root /
+ .replace(/\.[a-zA-Z]+$/, '' ) // Remove simple extension
+ .replace(/[^\.\w-]+/g, '-') // Replace illegal characters
+ .replace(/\./g, ':'); // Replace dots with colons(for valid id)
+ }
+};
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-javascript/less.js.git
More information about the Pkg-javascript-commits
mailing list