less 2.3.3 → 2.4.0
Sign up to get free protection for your applications and to get access to all the features.
- 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'));
|