less 2.3.3 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Changelog.md +5 -0
- data/less.gemspec +1 -1
- data/lib/less/js/.gitattributes +9 -0
- data/lib/less/js/.gitignore +1 -0
- data/lib/less/js/.npmignore +1 -1
- data/lib/less/js/CHANGELOG.md +68 -0
- data/lib/less/js/CONTRIBUTING.md +33 -34
- data/lib/less/js/Makefile +24 -9
- data/lib/less/js/README.md +2 -2
- data/lib/less/js/bin/lessc +102 -25
- data/lib/less/js/build/amd.js +1 -1
- data/lib/less/js/build/header.js +9 -7
- data/lib/less/js/dist/less-1.3.3.js +2 -2
- data/lib/less/js/dist/less-1.3.3.min.js +2 -2
- data/lib/less/js/dist/less-1.4.0-beta.js +5830 -0
- data/lib/less/js/dist/less-1.4.0-beta.min.js +11 -0
- data/lib/less/js/dist/less-1.4.0.js +5830 -0
- data/lib/less/js/dist/less-1.4.0.min.js +11 -0
- data/lib/less/js/dist/less-1.4.1.js +5837 -0
- data/lib/less/js/dist/less-1.4.1.min.js +11 -0
- data/lib/less/js/dist/less-1.4.2.js +5837 -0
- data/lib/less/js/dist/less-1.4.2.min.js +11 -0
- data/lib/less/js/dist/less-rhino-1.4.0.js +4273 -0
- data/lib/less/js/lib/less/browser.js +131 -101
- data/lib/less/js/lib/less/env.js +105 -0
- data/lib/less/js/lib/less/extend-visitor.js +391 -0
- data/lib/less/js/lib/less/functions.js +174 -19
- data/lib/less/js/lib/less/import-visitor.js +107 -0
- data/lib/less/js/lib/less/index.js +70 -63
- data/lib/less/js/lib/less/join-selector-visitor.js +37 -0
- data/lib/less/js/lib/less/lessc_helper.js +13 -4
- data/lib/less/js/lib/less/parser.js +353 -264
- data/lib/less/js/lib/less/rhino.js +5 -2
- data/lib/less/js/lib/less/tree.js +1 -1
- data/lib/less/js/lib/less/tree/alpha.js +7 -3
- data/lib/less/js/lib/less/tree/anonymous.js +1 -0
- data/lib/less/js/lib/less/tree/assignment.js +4 -0
- data/lib/less/js/lib/less/tree/call.js +14 -8
- data/lib/less/js/lib/less/tree/color.js +50 -5
- data/lib/less/js/lib/less/tree/comment.js +1 -0
- data/lib/less/js/lib/less/tree/condition.js +35 -28
- data/lib/less/js/lib/less/tree/dimension.js +270 -16
- data/lib/less/js/lib/less/tree/directive.js +7 -2
- data/lib/less/js/lib/less/tree/element.js +57 -21
- data/lib/less/js/lib/less/tree/expression.js +29 -4
- data/lib/less/js/lib/less/tree/extend.js +43 -0
- data/lib/less/js/lib/less/tree/import.js +49 -28
- data/lib/less/js/lib/less/tree/javascript.js +1 -0
- data/lib/less/js/lib/less/tree/keyword.js +3 -2
- data/lib/less/js/lib/less/tree/media.js +20 -4
- data/lib/less/js/lib/less/tree/mixin.js +38 -18
- data/lib/less/js/lib/less/tree/negative.js +22 -0
- data/lib/less/js/lib/less/tree/operation.js +32 -17
- data/lib/less/js/lib/less/tree/paren.js +5 -1
- data/lib/less/js/lib/less/tree/quoted.js +5 -3
- data/lib/less/js/lib/less/tree/rule.js +44 -31
- data/lib/less/js/lib/less/tree/ruleset.js +50 -23
- data/lib/less/js/lib/less/tree/selector.js +49 -39
- data/lib/less/js/lib/less/tree/unicode-descriptor.js +1 -0
- data/lib/less/js/lib/less/tree/url.js +9 -5
- data/lib/less/js/lib/less/tree/value.js +4 -1
- data/lib/less/js/lib/less/tree/variable.js +4 -3
- data/lib/less/js/lib/less/visitor.js +54 -0
- data/lib/less/js/package.json +69 -19
- data/lib/less/js/test/browser-test-prepare.js +23 -6
- data/lib/less/js/test/browser/common.js +55 -3
- data/lib/less/js/test/browser/css/urls.css +13 -0
- data/lib/less/js/test/browser/less/relative-urls/urls.less +1 -1
- data/lib/less/js/test/browser/less/urls.less +16 -0
- data/lib/less/js/test/browser/phantom-runner.js +7 -5
- data/lib/less/js/test/browser/runner-browser.js +5 -1
- data/lib/less/js/test/browser/runner-errors.js +5 -0
- data/lib/less/js/test/browser/runner-legacy.js +6 -0
- data/lib/less/js/test/browser/runner-production.js +7 -0
- data/lib/less/js/test/browser/template.htm +6 -6
- data/lib/less/js/test/css/comments.css +1 -0
- data/lib/less/js/test/css/compression/compression.css +2 -0
- data/lib/less/js/test/css/css-3.css +4 -0
- data/lib/less/js/test/css/css.css +9 -3
- data/lib/less/js/test/css/extend-chaining.css +72 -0
- data/lib/less/js/test/css/extend-clearfix.css +19 -0
- data/lib/less/js/test/css/extend-exact.css +37 -0
- data/lib/less/js/test/css/extend-media.css +24 -0
- data/lib/less/js/test/css/extend-nest.css +57 -0
- data/lib/less/js/test/css/extend-selector.css +72 -0
- data/lib/less/js/test/css/extend.css +76 -0
- data/lib/less/js/test/css/functions.css +28 -0
- data/lib/less/js/test/css/import-interpolation.css +6 -0
- data/lib/less/js/test/css/import.css +18 -1
- data/lib/less/js/test/css/legacy/legacy.css +7 -0
- data/lib/less/js/test/css/media.css +9 -1
- data/lib/less/js/test/css/mixins-args.css +18 -0
- data/lib/less/js/test/css/mixins-guards.css +5 -0
- data/lib/less/js/test/css/parens.css +18 -5
- data/lib/less/js/test/css/selectors.css +14 -6
- data/lib/less/js/test/css/urls.css +17 -0
- data/lib/less/js/test/css/variables.css +22 -3
- data/lib/less/js/test/data/data-uri-fail.png +0 -0
- data/lib/less/js/test/data/image.jpg +0 -0
- data/lib/less/js/test/data/page.html +1 -0
- data/lib/less/js/test/less-test.js +41 -9
- data/lib/less/js/test/less/colors.less +4 -4
- data/lib/less/js/test/less/comments.less +2 -2
- data/lib/less/js/test/less/compression/compression.less +16 -0
- data/lib/less/js/test/less/css-3.less +5 -1
- data/lib/less/js/test/less/css.less +9 -3
- data/lib/less/js/test/less/errors/add-mixed-units.less +3 -0
- data/lib/less/js/test/less/errors/add-mixed-units.txt +2 -0
- data/lib/less/js/test/less/errors/add-mixed-units2.less +3 -0
- data/lib/less/js/test/less/errors/add-mixed-units2.txt +2 -0
- data/lib/less/js/test/less/errors/bad-variable-declaration1.txt +1 -1
- data/lib/less/js/test/less/errors/color-operation-error.less +3 -0
- data/lib/less/js/test/less/errors/color-operation-error.txt +2 -0
- data/lib/less/js/test/less/errors/comment-in-selector.txt +1 -1
- data/lib/less/js/test/less/errors/divide-mixed-units.less +3 -0
- data/lib/less/js/test/less/errors/divide-mixed-units.txt +4 -0
- data/lib/less/js/test/less/errors/extend-no-selector.less +3 -0
- data/lib/less/js/test/less/errors/extend-no-selector.txt +3 -0
- data/lib/less/js/test/less/errors/extend-not-at-end.less +3 -0
- data/lib/less/js/test/less/errors/extend-not-at-end.txt +3 -0
- data/lib/less/js/test/less/errors/import-missing.less +5 -0
- data/lib/less/js/test/less/errors/import-missing.txt +3 -3
- data/lib/less/js/test/less/errors/import-no-semi.txt +1 -1
- data/lib/less/js/test/less/errors/import-subfolder1.txt +1 -1
- data/lib/less/js/test/less/errors/import-subfolder2.txt +1 -1
- data/lib/less/js/test/less/errors/javascript-error.txt +1 -1
- data/lib/less/js/test/less/errors/mixed-mixin-definition-args-1.txt +1 -1
- data/lib/less/js/test/less/errors/mixed-mixin-definition-args-2.txt +1 -1
- data/lib/less/js/test/less/errors/mixin-not-defined.txt +1 -1
- data/lib/less/js/test/less/errors/mixin-not-matched.txt +1 -1
- data/lib/less/js/test/less/errors/mixin-not-matched2.txt +1 -1
- data/lib/less/js/test/less/errors/multiply-mixed-units.less +7 -0
- data/lib/less/js/test/less/errors/multiply-mixed-units.txt +4 -0
- data/lib/less/js/test/less/errors/parens-error-1.less +3 -0
- data/lib/less/js/test/less/errors/parens-error-1.txt +4 -0
- data/lib/less/js/test/less/errors/parens-error-2.less +3 -0
- data/lib/less/js/test/less/errors/parens-error-2.txt +4 -0
- data/lib/less/js/test/less/errors/parens-error-3.less +3 -0
- data/lib/less/js/test/less/errors/parens-error-3.txt +4 -0
- data/lib/less/js/test/less/errors/parse-error-curly-bracket.txt +1 -1
- data/lib/less/js/test/less/errors/parse-error-missing-bracket.txt +2 -1
- data/lib/less/js/test/less/errors/parse-error-with-import.txt +1 -1
- data/lib/less/js/test/less/errors/property-ie5-hack.txt +1 -1
- data/lib/less/js/test/less/errors/property-in-root.less +4 -0
- data/lib/less/js/test/less/errors/property-in-root.txt +4 -0
- data/lib/less/js/test/less/errors/property-in-root2.less +1 -0
- data/lib/less/js/test/less/errors/property-in-root2.txt +4 -0
- data/lib/less/js/test/less/errors/property-in-root3.less +4 -0
- data/lib/less/js/test/less/errors/property-in-root3.txt +3 -0
- data/lib/less/js/test/less/errors/recursive-variable.txt +1 -1
- data/lib/less/js/test/less/extend-chaining.less +79 -0
- data/lib/less/js/test/less/extend-clearfix.less +19 -0
- data/lib/less/js/test/less/extend-exact.less +46 -0
- data/lib/less/js/test/less/extend-media.less +24 -0
- data/lib/less/js/test/less/extend-nest.less +65 -0
- data/lib/less/js/test/less/extend-selector.less +84 -0
- data/lib/less/js/test/less/extend.less +81 -0
- data/lib/less/js/test/less/functions.less +37 -6
- data/lib/less/js/test/less/import-interpolation.less +8 -0
- data/lib/less/js/test/less/import-once.less +4 -4
- data/lib/less/js/test/less/import.less +11 -2
- data/lib/less/js/test/less/import/deeper/import-once-test-a.less +1 -1
- data/lib/less/js/test/less/import/import-interpolation.less +1 -0
- data/lib/less/js/test/less/import/import-interpolation2.less +5 -0
- data/lib/less/js/test/less/javascript.less +1 -1
- data/lib/less/js/test/less/legacy/legacy.less +7 -0
- data/lib/less/js/test/less/media.less +14 -3
- data/lib/less/js/test/less/mixins-args.less +43 -5
- data/lib/less/js/test/less/mixins-guards.less +13 -0
- data/lib/less/js/test/less/mixins-named-args.less +5 -5
- data/lib/less/js/test/less/mixins-nested.less +2 -2
- data/lib/less/js/test/less/mixins-pattern.less +1 -1
- data/lib/less/js/test/less/mixins.less +1 -1
- data/lib/less/js/test/less/operations.less +27 -27
- data/lib/less/js/test/less/parens.less +20 -5
- data/lib/less/js/test/less/selectors.less +14 -7
- data/lib/less/js/test/less/urls.less +24 -0
- data/lib/less/js/test/less/variables.less +42 -12
- data/lib/less/loader.rb +33 -0
- data/lib/less/version.rb +1 -1
- data/spec/less/parser_spec.rb +5 -5
- metadata +76 -6
- data/lib/less/js/build/ecma-5.js +0 -120
- data/lib/less/js/lib/less/tree/ratio.js +0 -13
@@ -38,35 +38,37 @@ if (dumpLineNumbers) {
|
|
38
38
|
//
|
39
39
|
// Watch mode
|
40
40
|
//
|
41
|
-
less.watch = function () {
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
41
|
+
less.watch = function () {
|
42
|
+
if (!less.watchMode ){
|
43
|
+
less.env = 'development';
|
44
|
+
initRunningMode();
|
45
|
+
}
|
46
|
+
return this.watchMode = true
|
47
47
|
};
|
48
48
|
|
49
49
|
less.unwatch = function () {clearInterval(less.watchTimer); return this.watchMode = false; };
|
50
50
|
|
51
51
|
function initRunningMode(){
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
52
|
+
if (less.env === 'development') {
|
53
|
+
less.optimization = 0;
|
54
|
+
less.watchTimer = setInterval(function () {
|
55
|
+
if (less.watchMode) {
|
56
|
+
loadStyleSheets(function (e, root, _, sheet, env) {
|
57
|
+
if (e) {
|
58
|
+
error(e, sheet.href);
|
59
|
+
} else if (root) {
|
60
|
+
createCSS(root.toCSS(less), sheet, env.lastModified);
|
61
|
+
}
|
62
|
+
});
|
63
|
+
}
|
64
|
+
}, less.poll);
|
65
|
+
} else {
|
66
|
+
less.optimization = 3;
|
67
|
+
}
|
66
68
|
}
|
67
69
|
|
68
70
|
if (/!watch/.test(location.hash)) {
|
69
|
-
|
71
|
+
less.watch();
|
70
72
|
}
|
71
73
|
|
72
74
|
var cache = null;
|
@@ -98,13 +100,17 @@ for (var i = 0; i < links.length; i++) {
|
|
98
100
|
//
|
99
101
|
var session_cache = '';
|
100
102
|
less.modifyVars = function(record) {
|
101
|
-
|
102
|
-
for (name in record) {
|
103
|
+
var str = session_cache;
|
104
|
+
for (var name in record) {
|
103
105
|
str += ((name.slice(0,1) === '@')? '' : '@') + name +': '+
|
104
106
|
((record[name].slice(-1) === ';')? record[name] : record[name] +';');
|
105
107
|
}
|
106
|
-
new(less.Parser)().parse(str, function (e, root) {
|
107
|
-
|
108
|
+
new(less.Parser)(new less.tree.parseEnv(less)).parse(str, function (e, root) {
|
109
|
+
if (e) {
|
110
|
+
error(e, "session_cache");
|
111
|
+
} else {
|
112
|
+
createCSS(root.toCSS(less), less.sheets[less.sheets.length - 1]);
|
113
|
+
}
|
108
114
|
});
|
109
115
|
};
|
110
116
|
|
@@ -113,11 +119,14 @@ less.refresh = function (reload) {
|
|
113
119
|
startTime = endTime = new(Date);
|
114
120
|
|
115
121
|
loadStyleSheets(function (e, root, _, sheet, env) {
|
122
|
+
if (e) {
|
123
|
+
return error(e, sheet.href);
|
124
|
+
}
|
116
125
|
if (env.local) {
|
117
126
|
log("loading " + sheet.href + " from cache.");
|
118
127
|
} else {
|
119
128
|
log("parsed " + sheet.href + " successfully.");
|
120
|
-
createCSS(root.toCSS(), sheet, env.lastModified);
|
129
|
+
createCSS(root.toCSS(less), sheet, env.lastModified);
|
121
130
|
}
|
122
131
|
log("css for " + sheet.href + " generated in " + (new(Date) - endTime) + 'ms');
|
123
132
|
(env.remaining === 0) && log("css generated in " + (new(Date) - startTime) + 'ms');
|
@@ -134,11 +143,14 @@ function loadStyles() {
|
|
134
143
|
var styles = document.getElementsByTagName('style');
|
135
144
|
for (var i = 0; i < styles.length; i++) {
|
136
145
|
if (styles[i].type.match(typePattern)) {
|
137
|
-
new(less
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
146
|
+
var env = new less.tree.parseEnv(less);
|
147
|
+
env.filename = document.location.href.replace(/#.*$/, '');
|
148
|
+
|
149
|
+
new(less.Parser)(env).parse(styles[i].innerHTML || '', function (e, cssAST) {
|
150
|
+
if (e) {
|
151
|
+
return error(e, "inline");
|
152
|
+
}
|
153
|
+
var css = cssAST.toCSS(less);
|
142
154
|
var style = styles[i];
|
143
155
|
style.type = 'text/css';
|
144
156
|
if (style.styleSheet) {
|
@@ -188,7 +200,7 @@ function extractUrlParts(url, baseUrl) {
|
|
188
200
|
// urlParts[4] = filename
|
189
201
|
// urlParts[5] = parameters
|
190
202
|
|
191
|
-
var urlPartsRegex = /^((?:[a-z-]+:)
|
203
|
+
var urlPartsRegex = /^((?:[a-z-]+:)?\/+?(?:[^\/\?#]*\/)|([\/\\]))?((?:[^\/\\\?#]*[\/\\])*)([^\/\\\?#]*)([#\?].*)?$/i,
|
192
204
|
urlParts = url.match(urlPartsRegex),
|
193
205
|
returner = {}, directories = [], i, baseUrlParts;
|
194
206
|
|
@@ -202,14 +214,22 @@ function extractUrlParts(url, baseUrl) {
|
|
202
214
|
if (!baseUrlParts) {
|
203
215
|
throw new Error("Could not parse page url - '"+baseUrl+"'");
|
204
216
|
}
|
205
|
-
urlParts[1] = baseUrlParts[1];
|
217
|
+
urlParts[1] = urlParts[1] || baseUrlParts[1] || "";
|
206
218
|
if (!urlParts[2]) {
|
207
219
|
urlParts[3] = baseUrlParts[3] + urlParts[3];
|
208
220
|
}
|
209
221
|
}
|
210
222
|
|
211
223
|
if (urlParts[3]) {
|
212
|
-
directories = urlParts[3].replace(
|
224
|
+
directories = urlParts[3].replace(/\\/g, "/").split("/");
|
225
|
+
|
226
|
+
// extract out . before .. so .. doesn't absorb a non-directory
|
227
|
+
for(i = 0; i < directories.length; i++) {
|
228
|
+
if (directories[i] === ".") {
|
229
|
+
directories.splice(i, 1);
|
230
|
+
i -= 1;
|
231
|
+
}
|
232
|
+
}
|
213
233
|
|
214
234
|
for(i = 0; i < directories.length; i++) {
|
215
235
|
if (directories[i] === ".." && i > 0) {
|
@@ -228,36 +248,41 @@ function extractUrlParts(url, baseUrl) {
|
|
228
248
|
}
|
229
249
|
|
230
250
|
function loadStyleSheet(sheet, callback, reload, remaining) {
|
251
|
+
|
231
252
|
// sheet may be set to the stylesheet for the initial load or a collection of properties including
|
232
253
|
// some env variables for imports
|
233
|
-
var contents = sheet.contents || {};
|
234
|
-
var files = sheet.files || {};
|
235
254
|
var hrefParts = extractUrlParts(sheet.href, window.location.href);
|
236
255
|
var href = hrefParts.url;
|
237
256
|
var css = cache && cache.getItem(href);
|
238
257
|
var timestamp = cache && cache.getItem(href + ':timestamp');
|
239
258
|
var styles = { css: css, timestamp: timestamp };
|
240
|
-
var
|
259
|
+
var env;
|
260
|
+
var newFileInfo = {
|
261
|
+
relativeUrls: less.relativeUrls,
|
262
|
+
currentDirectory: hrefParts.path,
|
263
|
+
filename: href
|
264
|
+
};
|
241
265
|
|
242
|
-
if (less.
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
266
|
+
if (sheet instanceof less.tree.parseEnv) {
|
267
|
+
env = new less.tree.parseEnv(sheet);
|
268
|
+
newFileInfo.entryPath = env.currentFileInfo.entryPath;
|
269
|
+
newFileInfo.rootpath = env.currentFileInfo.rootpath;
|
270
|
+
newFileInfo.rootFilename = env.currentFileInfo.rootFilename;
|
271
|
+
} else {
|
272
|
+
env = new less.tree.parseEnv(less);
|
273
|
+
env.mime = sheet.type;
|
274
|
+
newFileInfo.entryPath = hrefParts.path;
|
275
|
+
newFileInfo.rootpath = less.rootpath || hrefParts.path;
|
276
|
+
newFileInfo.rootFilename = href;
|
277
|
+
}
|
278
|
+
|
279
|
+
if (env.relativeUrls) {
|
280
|
+
//todo - this relies on option being set on less object rather than being passed in as an option
|
281
|
+
// - need an originalRootpath
|
253
282
|
if (less.rootpath) {
|
254
|
-
rootpath = less.rootpath;
|
283
|
+
newFileInfo.rootpath = extractUrlParts(less.rootpath + pathDiff(hrefParts.path, newFileInfo.entryPath)).path;
|
255
284
|
} else {
|
256
|
-
|
257
|
-
rootpath = sheet.entryPath;
|
258
|
-
} else {
|
259
|
-
rootpath = hrefParts.path;
|
260
|
-
}
|
285
|
+
newFileInfo.rootpath = hrefParts.path;
|
261
286
|
}
|
262
287
|
}
|
263
288
|
|
@@ -274,38 +299,35 @@ function loadStyleSheet(sheet, callback, reload, remaining) {
|
|
274
299
|
} else {
|
275
300
|
// Use remote copy (re-parse)
|
276
301
|
try {
|
277
|
-
contents[href] = data; // Updating
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
filename: href,
|
284
|
-
rootpath: rootpath,
|
285
|
-
relativeUrls: sheet.relativeUrls,
|
286
|
-
contents: contents, // Passing top importing parser content cache ref down.
|
287
|
-
files: files,
|
288
|
-
dumpLineNumbers: less.dumpLineNumbers
|
289
|
-
}).parse(data, function (e, root) {
|
290
|
-
if (e) { return error(e, href) }
|
302
|
+
env.contents[href] = data; // Updating content cache
|
303
|
+
env.paths = [hrefParts.path];
|
304
|
+
env.currentFileInfo = newFileInfo;
|
305
|
+
|
306
|
+
new(less.Parser)(env).parse(data, function (e, root) {
|
307
|
+
if (e) { return callback(e, null, null, sheet); }
|
291
308
|
try {
|
292
309
|
callback(e, root, data, sheet, { local: false, lastModified: lastModified, remaining: remaining }, href);
|
293
|
-
|
310
|
+
//TODO - there must be a better way? A generic less-to-css function that can both call error
|
311
|
+
//and removeNode where appropriate
|
312
|
+
//should also add tests
|
313
|
+
if (env.currentFileInfo.rootFilename === href) {
|
314
|
+
removeNode(document.getElementById('less-error-message:' + extractId(href)));
|
315
|
+
}
|
294
316
|
} catch (e) {
|
295
|
-
|
317
|
+
callback(e, null, null, sheet);
|
296
318
|
}
|
297
319
|
});
|
298
320
|
} catch (e) {
|
299
|
-
|
321
|
+
callback(e, null, null, sheet);
|
300
322
|
}
|
301
323
|
}
|
302
324
|
}, function (status, url) {
|
303
|
-
|
325
|
+
callback({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")" }, null, null, sheet);
|
304
326
|
});
|
305
327
|
}
|
306
328
|
|
307
329
|
function extractId(href) {
|
308
|
-
return href.replace(/^[a-z]
|
330
|
+
return href.replace(/^[a-z-]+:\/+?[^\/]+/, '' ) // Remove protocol & domain
|
309
331
|
.replace(/^\//, '' ) // Remove root /
|
310
332
|
.replace(/\.[a-zA-Z]+$/, '' ) // Remove simple extension
|
311
333
|
.replace(/[^\.\w-]+/g, '-') // Replace illegal characters
|
@@ -313,23 +335,23 @@ function extractId(href) {
|
|
313
335
|
}
|
314
336
|
|
315
337
|
function createCSS(styles, sheet, lastModified) {
|
316
|
-
var css;
|
317
|
-
|
318
338
|
// Strip the query-string
|
319
339
|
var href = sheet.href || '';
|
320
340
|
|
321
341
|
// If there is no title set, use the filename, minus the extension
|
322
342
|
var id = 'less:' + (sheet.title || extractId(href));
|
323
343
|
|
324
|
-
// If
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
344
|
+
// If this has already been inserted into the DOM, we may need to replace it
|
345
|
+
var oldCss = document.getElementById(id);
|
346
|
+
var keepOldCss = false;
|
347
|
+
|
348
|
+
// Create a new stylesheet node for insertion or (if necessary) replacement
|
349
|
+
var css = document.createElement('style');
|
350
|
+
css.setAttribute('type', 'text/css');
|
351
|
+
if (sheet.media) {
|
352
|
+
css.setAttribute('media', sheet.media);
|
332
353
|
}
|
354
|
+
css.id = id;
|
333
355
|
|
334
356
|
if (css.styleSheet) { // IE
|
335
357
|
try {
|
@@ -338,15 +360,23 @@ function createCSS(styles, sheet, lastModified) {
|
|
338
360
|
throw new(Error)("Couldn't reassign styleSheet.cssText.");
|
339
361
|
}
|
340
362
|
} else {
|
341
|
-
(
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
|
346
|
-
|
347
|
-
|
348
|
-
|
349
|
-
|
363
|
+
css.appendChild(document.createTextNode(styles));
|
364
|
+
|
365
|
+
// If new contents match contents of oldCss, don't replace oldCss
|
366
|
+
keepOldCss = (oldCss !== null && oldCss.childNodes.length > 0 && css.childNodes.length > 0 &&
|
367
|
+
oldCss.firstChild.nodeValue === css.firstChild.nodeValue);
|
368
|
+
}
|
369
|
+
|
370
|
+
var head = document.getElementsByTagName('head')[0];
|
371
|
+
|
372
|
+
// If there is no oldCss, just append; otherwise, only append if we need
|
373
|
+
// to replace oldCss with an updated stylesheet
|
374
|
+
if (oldCss == null || keepOldCss === false) {
|
375
|
+
var nextEl = sheet && sheet.nextSibling || null;
|
376
|
+
(nextEl || document.getElementsByTagName('head')[0]).parentNode.insertBefore(css, nextEl);
|
377
|
+
}
|
378
|
+
if (oldCss && keepOldCss === false) {
|
379
|
+
head.removeChild(oldCss);
|
350
380
|
}
|
351
381
|
|
352
382
|
// Don't update the local store if the file wasn't modified
|
@@ -420,35 +450,35 @@ function log(str) {
|
|
420
450
|
if (less.env == 'development' && typeof(console) !== "undefined") { console.log('less: ' + str) }
|
421
451
|
}
|
422
452
|
|
423
|
-
function error(e,
|
424
|
-
var id = 'less-error-message:' + extractId(
|
453
|
+
function error(e, rootHref) {
|
454
|
+
var id = 'less-error-message:' + extractId(rootHref || "");
|
425
455
|
var template = '<li><label>{line}</label><pre class="{class}">{content}</pre></li>';
|
426
456
|
var elem = document.createElement('div'), timer, content, error = [];
|
427
|
-
var filename = e.filename ||
|
457
|
+
var filename = e.filename || rootHref;
|
428
458
|
var filenameNoPath = filename.match(/([^\/]+(\?.*)?)$/)[1];
|
429
459
|
|
430
460
|
elem.id = id;
|
431
461
|
elem.className = "less-error-message";
|
432
462
|
|
433
|
-
content = '<h3>' + (e.message || 'There is an error in your .less file') +
|
463
|
+
content = '<h3>' + (e.type || "Syntax") + "Error: " + (e.message || 'There is an error in your .less file') +
|
434
464
|
'</h3>' + '<p>in <a href="' + filename + '">' + filenameNoPath + "</a> ";
|
435
465
|
|
436
466
|
var errorline = function (e, i, classname) {
|
437
|
-
if (e.extract[i]) {
|
438
|
-
error.push(template.replace(/\{line\}/, parseInt(e.line) + (i - 1))
|
467
|
+
if (e.extract[i] != undefined) {
|
468
|
+
error.push(template.replace(/\{line\}/, (parseInt(e.line) || 0) + (i - 1))
|
439
469
|
.replace(/\{class\}/, classname)
|
440
470
|
.replace(/\{content\}/, e.extract[i]));
|
441
471
|
}
|
442
472
|
};
|
443
473
|
|
444
|
-
if (e.
|
445
|
-
content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
|
446
|
-
} else if (e.extract) {
|
474
|
+
if (e.extract) {
|
447
475
|
errorline(e, 0, '');
|
448
476
|
errorline(e, 1, 'line');
|
449
477
|
errorline(e, 2, '');
|
450
478
|
content += 'on line ' + e.line + ', column ' + (e.column + 1) + ':</p>' +
|
451
479
|
'<ul>' + error.join('') + '</ul>';
|
480
|
+
} else if (e.stack) {
|
481
|
+
content += '<br/>' + e.stack.split('\n').slice(1).join('<br/>');
|
452
482
|
}
|
453
483
|
elem.innerHTML = content;
|
454
484
|
|
@@ -0,0 +1,105 @@
|
|
1
|
+
(function (tree) {
|
2
|
+
|
3
|
+
var parseCopyProperties = [
|
4
|
+
'paths', // option - unmodified - paths to search for imports on
|
5
|
+
'optimization', // option - optimization level (for the chunker)
|
6
|
+
'files', // list of files that have been imported, used for import-once
|
7
|
+
'contents', // browser-only, contents of all the files
|
8
|
+
'relativeUrls', // option - whether to adjust URL's to be relative
|
9
|
+
'strictImports', // option -
|
10
|
+
'dumpLineNumbers', // option - whether to dump line numbers
|
11
|
+
'compress', // option - whether to compress
|
12
|
+
'processImports', // option - whether to process imports. if false then imports will not be imported
|
13
|
+
'syncImport', // option - whether to import synchronously
|
14
|
+
'mime', // browser only - mime type for sheet import
|
15
|
+
'currentFileInfo' // information about the current file - for error reporting and importing and making urls relative etc.
|
16
|
+
];
|
17
|
+
|
18
|
+
//currentFileInfo = {
|
19
|
+
// 'relativeUrls' - option - whether to adjust URL's to be relative
|
20
|
+
// 'filename' - full resolved filename of current file
|
21
|
+
// 'rootpath' - path to append to normal URLs for this node
|
22
|
+
// 'currentDirectory' - path to the current file, absolute
|
23
|
+
// 'rootFilename' - filename of the base file
|
24
|
+
// 'entryPath' = absolute path to the entry file
|
25
|
+
|
26
|
+
tree.parseEnv = function(options) {
|
27
|
+
copyFromOriginal(options, this, parseCopyProperties);
|
28
|
+
|
29
|
+
if (!this.contents) { this.contents = {}; }
|
30
|
+
if (!this.files) { this.files = {}; }
|
31
|
+
|
32
|
+
if (!this.currentFileInfo) {
|
33
|
+
var filename = (options && options.filename) || "input";
|
34
|
+
var entryPath = filename.replace(/[^\/\\]*$/, "");
|
35
|
+
if (options) {
|
36
|
+
options.filename = null;
|
37
|
+
}
|
38
|
+
this.currentFileInfo = {
|
39
|
+
filename: filename,
|
40
|
+
relativeUrls: this.relativeUrls,
|
41
|
+
rootpath: (options && options.rootpath) || "",
|
42
|
+
currentDirectory: entryPath,
|
43
|
+
entryPath: entryPath,
|
44
|
+
rootFilename: filename
|
45
|
+
};
|
46
|
+
}
|
47
|
+
};
|
48
|
+
|
49
|
+
tree.parseEnv.prototype.toSheet = function (path) {
|
50
|
+
var env = new tree.parseEnv(this);
|
51
|
+
env.href = path;
|
52
|
+
//env.title = path;
|
53
|
+
env.type = this.mime;
|
54
|
+
return env;
|
55
|
+
};
|
56
|
+
|
57
|
+
var evalCopyProperties = [
|
58
|
+
'silent', // whether to swallow errors and warnings
|
59
|
+
'verbose', // whether to log more activity
|
60
|
+
'compress', // whether to compress
|
61
|
+
'yuicompress', // whether to compress with the outside tool yui compressor
|
62
|
+
'ieCompat', // whether to enforce IE compatibility (IE8 data-uri)
|
63
|
+
'strictMath', // whether math has to be within parenthesis
|
64
|
+
'strictUnits' // whether units need to evaluate correctly
|
65
|
+
];
|
66
|
+
|
67
|
+
tree.evalEnv = function(options, frames) {
|
68
|
+
copyFromOriginal(options, this, evalCopyProperties);
|
69
|
+
|
70
|
+
this.frames = frames || [];
|
71
|
+
};
|
72
|
+
|
73
|
+
tree.evalEnv.prototype.inParenthesis = function () {
|
74
|
+
if (!this.parensStack) {
|
75
|
+
this.parensStack = [];
|
76
|
+
}
|
77
|
+
this.parensStack.push(true);
|
78
|
+
};
|
79
|
+
|
80
|
+
tree.evalEnv.prototype.outOfParenthesis = function () {
|
81
|
+
this.parensStack.pop();
|
82
|
+
};
|
83
|
+
|
84
|
+
tree.evalEnv.prototype.isMathOn = function () {
|
85
|
+
return this.strictMath ? (this.parensStack && this.parensStack.length) : true;
|
86
|
+
};
|
87
|
+
|
88
|
+
tree.evalEnv.prototype.isPathRelative = function (path) {
|
89
|
+
return !/^(?:[a-z-]+:|\/)/.test(path);
|
90
|
+
};
|
91
|
+
|
92
|
+
//todo - do the same for the toCSS env
|
93
|
+
//tree.toCSSEnv = function (options) {
|
94
|
+
//};
|
95
|
+
|
96
|
+
var copyFromOriginal = function(original, destination, propertiesToCopy) {
|
97
|
+
if (!original) { return; }
|
98
|
+
|
99
|
+
for(var i = 0; i < propertiesToCopy.length; i++) {
|
100
|
+
if (original.hasOwnProperty(propertiesToCopy[i])) {
|
101
|
+
destination[propertiesToCopy[i]] = original[propertiesToCopy[i]];
|
102
|
+
}
|
103
|
+
}
|
104
|
+
}
|
105
|
+
})(require('./tree'));
|