Merge branch 'master' into strict-math-division

# Conflicts:
#	lib/less/tree/declaration.js
#	test/index.js
This commit is contained in:
Matthew Dean
2018-07-06 18:35:19 -07:00
212 changed files with 4360 additions and 2200 deletions

13
.editorconfig Normal file
View File

@@ -0,0 +1,13 @@
# @see http://editorconfig.org/
# the buck stops here
root = true
# all files
[*]
end_of_line = LF
indent_style = space
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true

1
.eslintignore Normal file
View File

@@ -0,0 +1 @@
Gruntfile.js

View File

@@ -3,11 +3,8 @@
"node": true
},
"globals": {},
"rules": {
"quotes": [
1,
"single"
],
"no-eval": 2,
"no-use-before-define": [
2,

16
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,16 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Less test",
"program": "${workspaceFolder}/test/index.js",
"cwd": "${workspaceFolder}",
"console": "integratedTerminal"
}
]
}

View File

@@ -1,8 +1,50 @@
## 3.5.3
2018-07-06
- Reverts @media eval change
- Other bug fixes
## 3.5.0
2018-07-05
- Feature: Namespaced Values / Maps e.g. `color: @color[primary]`
- Fixes to calc()
- Permissive parsing of custom properties and variables
- Inline expressions now not evaluated in at-rules `@media (min-width: @var) {}` works, `@media (min-width: @var + 1) {}` will not
- Allows unnamed lookups i.e. "functions" e.g. `.mixin(@a, @b)[]`
- Lots of bug fixes
## 3.5.0-beta.4
2018-06-30
- Fixes #3235, #3187
- Feature: Namespaced Values e.g. `color: #color[primary]`
## 3.5.0-beta.3
2018-06-29
- Fix: browser cache is always considered stale if .modifyVars wasn't
## 3.5.0-beta.2
2018-06-27
- Re-parses selectors after variables in selectors are evaluated - Fixes #1421
- Fixes #3191
## 3.5.0-beta
2018-06-24
- Adds permissive parsing for at-rules and custom properties - fixes #3147 #2715
- Updates dependencies
- Fixes file caching issue (not reloading modified files in "watched" environments)
## 3.0.4
2018-05-06
- Update source-map to 0.6.x (#3180). Enforces node 6+ though.
# 3.0.0
## 3.0.0
2018-02-10
- Fix `calc()` function to not do math operations on compile
- Rename Directive -> AtRule & Rule -> Declaration
@@ -17,25 +59,27 @@
- Bug fixes
- Removal of unnecessary nodes from API (like IE's `alpha()`)
# 2.7.3
## 2.7.3
2017-10-23
- Bump `request` dependency
# 2.7.2
## 2.7.2
2017-01-04
- Revert breaking changes to contrast() function
- Fix error reporting of lessc executable
- Changed octals to hex for ES6 strict mode
# 2.7.1 HOTFIX
## 2.7.1 HOTFIX
2016-05-09
- Revert commit 470af20 (source map performance) which broke source maps
# 2.7.0
## 2.7.0
2016-05-07
@@ -48,7 +92,7 @@
- Fix AST to include single-line comments
- Fix reversion for "color-like" words (outputting color values)
# 2.6.1
## 2.6.1
2016-03-04
@@ -57,7 +101,7 @@
- use instanceof operator instead of class comparison optimization
- disallow whitespace in variable calls
# 2.6.0
## 2.6.0
2016-01-29
@@ -72,13 +116,13 @@
- Logical operator ```and``` now has higher precedence than logical operator ```or```.
- Allow unknown at-rules w/o {} block
# 2.5.3
## 2.5.3
2015-09-25
- Fix import inline a URL
# 2.5.2
## 2.5.2
2015-09-24
@@ -89,7 +133,7 @@
- Fixed mixin definition matching problem when mixin definition contains parameters with default values
- Observe reference for imported comments
# 2.5.1
## 2.5.1
2015-05-21
@@ -97,7 +141,7 @@
- Minor fix only likely to affect programmatic usage of ruleset find
- Fix error when a namespaced mixin is invoked in global scope
# 2.5.0
## 2.5.0
2015-04-03
@@ -118,7 +162,7 @@
- consistently keep units if strict units is off
- Better support for comments in function all arguments
# 2.4.0
## 2.4.0
2015-02-07
@@ -132,14 +176,14 @@
- Files with just `\r` newlines now process ok (regression in 2.0.0)
- When strict units is off and the unit is 1/x, (e.g. 1 / 12px) the unit output is x, previously nothing (regression in 2.0.0)
# 2.3.1
## 2.3.1
2015-01-28
- Fix depends option (regression in 2.3.0)
- Support parent selector (`&`) used in sub element expression (e.g. `:not(.c_&)`)
# 2.3.0
## 2.3.0
2015-01-27
@@ -157,7 +201,7 @@
- Unicode BOM removed again
- Misc. bug fixes
# 2.2.0
## 2.2.0
2015-01-04
@@ -177,14 +221,14 @@
- support safari extension
- less.parse now exposes a way to get the AST. We do not recommend you use this unless you need to.
# 2.1.2
## 2.1.2
2014-12-20
- Fix for use with requirejs
- Fixes for data-uri function
# 2.1.1
## 2.1.1
2014-11-27
@@ -193,7 +237,7 @@
- Fix problem with plugins when used with the promises version of render
- If the render callback throws an exception it now propagates instead of calling the callback again with an error
# 2.1.0
## 2.1.0
2014-11-23
@@ -208,7 +252,7 @@
- livereload cache buster is now treated specially
- upgrade dependencies
# 2.0.0
## 2.0.0
2014-11-09
@@ -219,7 +263,7 @@
- fixed some local variable spellings
- support for `@counter-style` directive
# 2.0.0-b3
## 2.0.0-b3
2014-11-01
@@ -228,7 +272,7 @@
- browser can now be scoped with just window
- browser `useFileCache` defaults to `true`, but file cache is now cleared when refreshing or in watch mode
# 2.0.0-b2
## 2.0.0-b2
2014-10-26
@@ -240,7 +284,7 @@
- Fixed a bug where unquoted urls beginning `//` e.g. `url(//file/file.less)` would be incorrectly interpreted (bug introduced in b-1)
- lessc plugins can be a function, used as a constructor as well as an object - this to allow the plugin more flexibility to be used programattically
# 2.0.0-b1
## 2.0.0-b1
2014-10-19
@@ -261,7 +305,7 @@
- default values for the sourcemap options have been re-done and improved to hopefully mean creating sourcemaps is easier
- Many smaller bugfixes and API changes. Please let us know if something you relied on has disappeared or an area should be better documented.
# 1.7.5
## 1.7.5
2014-09-03
@@ -274,7 +318,7 @@
- Fix interpolated import in media query
- A few other various small corrections
# 1.7.4
## 1.7.4
2014-07-27
@@ -286,7 +330,7 @@
- Better error message for imports missing semi-colons or malformed
- Do not use util.print to avoid deprecate warnings in node 0.11
# 1.7.3
## 1.7.3
2014-06-22
@@ -294,14 +338,14 @@
- Do not round the results of color functions, like lightness, hue, luma etc.
- Support cover and contain keywords in background definitions
# 1.7.2
## 1.7.2
2014-06-19
- Allow paths option to be a string (in 1.7.1 less started throwing an exception instead of incorrectly processing the string as an array of chars)
- Do not round numbers when used with javascript (introduced 1.7.0)
# 1.7.1
## 1.7.1
2014-06-08
@@ -319,7 +363,7 @@
- Fix the e() function when passed empty string
- Several minor bug fixes
# 1.7.0
## 1.7.0
2014-02-27
@@ -341,13 +385,13 @@
- Browser - added postProcessor option, a function called to post-process the css before adding to the page
- Browser - use the right request for file access in IE
# 1.6.3
## 1.6.3
2014-02-08
- Fix issue with calling toCSS twice not working in some situations (like with bootstrap 2)
# 1.6.2
## 1.6.2
2014-02-02
@@ -362,7 +406,7 @@
- some improvements to the default() function in more complex scenarios
- improved missing '{' and '(' detection
# 1.6.1
## 1.6.1
2014-01-12
@@ -375,7 +419,7 @@
- use innerHTML in tests, not innerText
- protect for-in in case Array and Object prototypes have custom fields
# 1.6.0
## 1.6.0
2014-01-01
@@ -394,7 +438,7 @@
- Fixed error messages for undefined variables in javascript evaluation
- Fixed line/column numbers from math errors
# 1.5.1
## 1.5.1
2013-11-17
@@ -406,7 +450,7 @@
- correct a bug meaning imports weren't synchronous (syncImport option available for full synchronous behaviour)
- better mixin matching behaviour with calling multiple classes e.g. .a.b.c;
# 1.5.0
## 1.5.0
2013-10-21
@@ -432,7 +476,7 @@
- Now uses grunt for building and testing
- A few bug fixes for media queries, extends, scoping, compression and import once.
# 1.4.2
## 1.4.2
2013-07-20
@@ -441,7 +485,7 @@
- property names may include capital letters
- various windows path fixes (capital letters, multiple // in a path)
# 1.4.1
## 1.4.1
2013-07-05
@@ -449,20 +493,20 @@
- fixed several global variable leaks
- handle getting null or undefined passed as the options object
# 1.4.0
## 1.4.0
2013-06-05
- fix passing of strict maths option
# 1.4.0 Beta 4
## 1.4.0 Beta 4
2013-05-04
- change strictMaths to strictMath. Enable this with --strict-math=on in lessc and strictMath:true in JavaScript.
- change lessc option for strict units to --strict-units=off
# 1.4.0 Beta 3
## 1.4.0 Beta 3
2013-04-30
@@ -474,7 +518,7 @@
- remove es-5-shim as standard from the browser
- Fix path issues with windows/linux local paths
# 1.4.0 Beta 1 & 2
## 1.4.0 Beta 1 & 2
2013-03-07
@@ -500,14 +544,14 @@
- support for namespaces in attributes and selector interpolation in attributes
- other bug fixes
# 1.3.3
## 1.3.3
2012-12-30
- Fix critical bug with mixin call if using multiple brackets
- when using the filter contrast function, the function is passed through if the first argument is not a color
# 1.3.2
## 1.3.2
2012-12-28
@@ -544,7 +588,7 @@
- sass debug statements are now chrome compatible
- modifyVars function added to re-render with different root variables
# 1.3.1
## 1.3.1
2012-10-18
@@ -569,7 +613,7 @@
- implement named parameters when calling mixins
- many numerous bug fixes
# 1.3.0
## 1.3.0
2012-03-10
@@ -587,7 +631,7 @@
- Fix a bug when using @media with mixins
# 1.2.1
## 1.2.1
2012-01-15
@@ -597,7 +641,7 @@
- Fix `File not found` import error reporting
# 1.2.0
## 1.2.0
2012-01-07

View File

@@ -15,12 +15,12 @@ module.exports = function (grunt) {
var browsers = [
// Desktop browsers
{
browserName: "chrome",
browserName: 'chrome',
version: 'latest',
platform: 'Windows 7'
},
{
browserName: "firefox",
browserName: 'firefox',
version: 'latest',
platform: 'Linux'
},
@@ -30,17 +30,17 @@ module.exports = function (grunt) {
platform: 'OS X 10.11'
},
{
browserName: "internet explorer",
browserName: 'internet explorer',
version: '8',
platform: 'Windows XP'
},
{
browserName: "internet explorer",
browserName: 'internet explorer',
version: '11',
platform: 'Windows 8.1'
},
{
browserName: "edge",
browserName: 'edge',
version: '13',
platform: 'Windows 10'
},
@@ -70,17 +70,17 @@ module.exports = function (grunt) {
var sauceJobs = {};
var browserTests = [ "filemanager-plugin",
"visitor-plugin",
"global-vars",
"modify-vars",
"production",
"rootpath-relative",
"rootpath",
"relative-urls",
"browser",
"no-js-errors",
"legacy"
var browserTests = [ 'filemanager-plugin',
'visitor-plugin',
'global-vars',
'modify-vars',
'production',
'rootpath-relative',
'rootpath',
'relative-urls',
'browser',
'no-js-errors',
'legacy'
];
function makeJob(testName) {
@@ -88,16 +88,16 @@ module.exports = function (grunt) {
options: {
urls: testName === 'all' ?
browserTests.map(function(name) {
return "http://localhost:8081/tmp/browser/test-runner-" + name + ".html";
return 'http://localhost:8081/tmp/browser/test-runner-' + name + '.html';
}) :
["http://localhost:8081/tmp/browser/test-runner-" + testName + ".html"],
['http://localhost:8081/tmp/browser/test-runner-' + testName + '.html'],
testname: testName === 'all' ? 'Unit Tests for Less.js' : testName,
browsers: browsers,
public: 'public',
recordVideo: false,
videoUploadOnPass: false,
recordScreenshots: process.env.TRAVIS_BRANCH !== "master",
build: process.env.TRAVIS_BRANCH === "master" ? process.env.TRAVIS_JOB_ID : undefined,
recordScreenshots: process.env.TRAVIS_BRANCH !== 'master',
build: process.env.TRAVIS_BRANCH === 'master' ? process.env.TRAVIS_JOB_ID : undefined,
tags: [process.env.TRAVIS_BUILD_NUMBER, process.env.TRAVIS_PULL_REQUEST, process.env.TRAVIS_BRANCH],
statusCheckAttempts: -1,
sauceConfig: {
@@ -190,10 +190,13 @@ module.exports = function (grunt) {
command: [
'node bin/lessc --clean-css="--s1 --advanced" test/less/lazy-eval.less tmp/lazy-eval.css',
'cd lib',
'node ../bin/lessc --clean-css="--s1 --advanced" ../test/less/lazy-eval.less ../tmp/lazy-eval.css'
'node ../bin/lessc --clean-css="--s1 --advanced" ../test/less/lazy-eval.less ../tmp/lazy-eval.css',
'cd ..',
// Test multiple plugins
'node bin/lessc --plugin=clean-css="--s1 --advanced" --plugin=autoprefix="ie 11,Edge >= 13,Chrome >= 47,Firefox >= 45,iOS >= 9.2,Safari >= 9" test/less/lazy-eval.less tmp/lazy-eval.css'
].join(' && ')
},
"sourcemap-test": {
'sourcemap-test': {
command: [
'node bin/lessc --source-map=test/sourcemaps/maps/import-map.map test/less/import.less test/sourcemaps/import.css',
'node bin/lessc --source-map test/less/sourcemaps/basic.less test/sourcemaps/basic.css'
@@ -205,7 +208,7 @@ module.exports = function (grunt) {
browser: {
src: ['./lib/less-browser/bootstrap.js'],
options: {
exclude: ["promise"],
exclude: ['promise'],
browserifyOptions: {
standalone: 'less'
}
@@ -265,15 +268,15 @@ module.exports = function (grunt) {
},
eslint: {
target: ["Gruntfile.js",
"test/**/*.js",
"lib/less*/**/*.js",
"bin/lessc",
"!test/browser/jasmine-jsreporter.js",
"!test/less/errors/plugin/plugin-error.js"
target: ['Gruntfile.js',
'test/**/*.js',
'lib/less*/**/*.js',
'bin/lessc',
'!test/browser/jasmine-jsreporter.js',
'!test/less/errors/plugin/plugin-error.js'
],
options: {
configFile: ".eslintrc.json"
configFile: '.eslintrc.json'
}
},
@@ -295,7 +298,7 @@ module.exports = function (grunt) {
main: {
// src is used to build list of less files to compile
src: [
'test/less/*.less',
'test/less/plugin.less',
// Don't test NPM import, obviously
'!test/less/plugin-module.less',
'!test/less/import-module.less',
@@ -438,8 +441,8 @@ module.exports = function (grunt) {
// Clean the version of less built for the tests
clean: {
test: ['test/browser/less.js', 'tmp', 'test/less-bom'],
"sourcemap-test": ['test/sourcemaps/*.css', 'test/sourcemaps/*.map'],
sauce_log: ["sc_*.log"]
'sourcemap-test': ['test/sourcemaps/*.css', 'test/sourcemaps/*.map'],
sauce_log: ['sc_*.log']
}
});
@@ -491,17 +494,17 @@ module.exports = function (grunt) {
'connect::keepalive'
]);
var previous_force_state = grunt.option("force");
var previous_force_state = grunt.option('force');
grunt.registerTask("force",function(set) {
if (set === "on") {
grunt.option("force",true);
grunt.registerTask('force',function(set) {
if (set === 'on') {
grunt.option('force',true);
}
else if (set === "off") {
grunt.option("force",false);
else if (set === 'off') {
grunt.option('force',false);
}
else if (set === "restore") {
grunt.option("force",previous_force_state);
else if (set === 'restore') {
grunt.option('force',previous_force_state);
}
});
@@ -527,10 +530,10 @@ module.exports = function (grunt) {
if (isNaN(Number(process.env.TRAVIS_PULL_REQUEST, 10)) &&
Number(process.env.TRAVIS_NODE_VERSION) === 4 &&
(process.env.TRAVIS_BRANCH === "master" || process.env.TRAVIS_BRANCH === "3.x")) {
testTasks.push("force:on");
testTasks.push("sauce-after-setup");
testTasks.push("force:off");
(process.env.TRAVIS_BRANCH === 'master' || process.env.TRAVIS_BRANCH === '3.x')) {
testTasks.push('force:on');
testTasks.push('sauce-after-setup');
testTasks.push('force:off');
}
// Run all tests

View File

@@ -1,6 +1,10 @@
[![npm version](https://badge.fury.io/js/less.svg)](http://badge.fury.io/js/less) [![Build Status](https://travis-ci.org/less/less.js.svg?branch=master)](https://travis-ci.org/less/less.js) [![Build status](https://ci.appveyor.com/api/projects/status/bx2qspy3qbuxpl9q/branch/master?svg=true)](https://ci.appveyor.com/project/lukeapage/less-js/branch/master) [![Dependencies](https://david-dm.org/less/less.js.svg)](https://david-dm.org/less/less.js) [![devDependency Status](https://david-dm.org/less/less.js/dev-status.svg)](https://david-dm.org/less/less.js#info=devDependencies) [![optionalDependency Status](https://david-dm.org/less/less.js/optional-status.svg)](https://david-dm.org/less/less.js#info=optionalDependencies) [![Twitter Follow](https://img.shields.io/twitter/follow/lesstocss.svg?style=flat-square)](https://twitter.com/lesstocss) [![Join the chat at https://gitter.im/less/less.js](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/less/less.js?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) <sup>Chat with Less.js users</sup>
<p align="center"><img src="http://lesscss.org/public/img/less_logo.png" width="264" height="117">
[![Sauce Test Status](https://saucelabs.com/browser-matrix/less.svg)](https://saucelabs.com/u/less)
<p align="center"><a href="http://badge.fury.io/js/less"><img src="https://badge.fury.io/js/less.svg"></a> <a href="https://travis-ci.org/less/less.js"><img src="https://travis-ci.org/less/less.js.svg?branch=master" style="max-width:100%;"></a> <a href="https://ci.appveyor.com/project/lukeapage/less-js/branch/master"><img src="https://ci.appveyor.com/api/projects/status/bx2qspy3qbuxpl9q/branch/master?svg=true" style="max-width:100%;"></a> <a href="https://david-dm.org/less/less.js"><img src="https://david-dm.org/less/less.js.svg" style="max-width:100%;"></a> <a href="https://david-dm.org/less/less.js#info=devDependencies"><img src="https://david-dm.org/less/less.js/dev-status.svg" style="max-width:100%;"></a> <a href="https://david-dm.org/less/less.js#info=optionalDependencies"><img alt="optionalDependency Status" src="https://david-dm.org/less/less.js/optional-status.svg" style="max-width:100%;"></a> <a href="https://twitter.com/lesstocss"><img alt="Twitter Follow" src="https://img.shields.io/twitter/follow/lesstocss.svg?style=flat-square" style="max-width:100%;"></a></p>
<p align="center"><a href="https://gitter.im/less/less.js?utm_source=badge&amp;utm_medium=badge&amp;utm_campaign=pr-badge&amp;utm_content=badge"><img src="https://badges.gitter.im/Join%20Chat.svg" style="max-width:100%;"></a> <br><sup class="rich-diff-level-one">Chat with Less.js users and contributors</sup></p>
<p align="center"><a href="https://saucelabs.com/u/less" rel="nofollow"><img src="https://saucelabs.com/browser-matrix/less.svg" alt="Sauce Test Status" style="max-width:100%;"></a></p>
# [Less.js](http://lesscss.org)

View File

@@ -2,7 +2,7 @@
var path = require('path'),
fs = require('../lib/less-node/fs'),
os = require("os"),
os = require('os'),
utils = require('../lib/less/utils'),
errno,
mkdirp;
@@ -37,20 +37,20 @@ var continueProcessing = true;
// Additionally we also need to make sure that uncaughtExceptions are never swallowed.
// @see https://github.com/less/less.js/issues/2881
// This code can safely be removed if node 0.10.x is not supported anymore.
process.on("exit", function() { process.reallyExit(process.exitCode); });
process.on("uncaughtException", function(err) {
process.on('exit', function() { process.reallyExit(process.exitCode); });
process.on('uncaughtException', function(err) {
console.error(err);
process.exitCode = 1;
});
// This code will still be required because otherwise rejected promises would not be reported to the user
process.on("unhandledRejection", function(err) {
process.on('unhandledRejection', function(err) {
console.error(err);
process.exitCode = 1;
});
var checkArgFunc = function(arg, option) {
if (!option) {
console.error(arg + " option requires a parameter");
console.error(arg + ' option requires a parameter');
continueProcessing = false;
process.exitCode = 1;
return false;
@@ -61,7 +61,7 @@ var checkArgFunc = function(arg, option) {
var checkBooleanArg = function(arg) {
var onOff = /^((on|t|true|y|yes)|(off|f|false|n|no))$/i.exec(arg);
if (!onOff) {
console.error(" unable to parse " + arg + " as a boolean. use one of on/t/true/y/yes/off/f/false/n/no");
console.error(' unable to parse ' + arg + ' as a boolean. use one of on/t/true/y/yes/off/f/false/n/no');
continueProcessing = false;
process.exitCode = 1;
return false;
@@ -102,15 +102,15 @@ function render() {
sourceMapOptions.sourceMapInputFilename = input;
if (!sourceMapOptions.sourceMapFullFilename) {
if (!output && !sourceMapFileInline) {
console.error("the sourcemap option only has an optional filename if the css filename is given");
console.error("consider adding --source-map-map-inline which embeds the sourcemap into the css");
console.error('the sourcemap option only has an optional filename if the css filename is given');
console.error('consider adding --source-map-map-inline which embeds the sourcemap into the css');
process.exitCode = 1;
return;
}
// its in the same directory, so always just the basename
if (output) {
sourceMapOptions.sourceMapOutputFilename = path.basename(output);
sourceMapOptions.sourceMapFullFilename = output + ".map";
sourceMapOptions.sourceMapFullFilename = output + '.map';
}
// its in the same directory, so always just the basename
if ('sourceMapFullFilename' in sourceMapOptions) {
@@ -142,8 +142,8 @@ function render() {
if (!input) {
console.error("lessc: no input files");
console.error("");
console.error('lessc: no input files');
console.error('');
printUsage();
process.exitCode = 1;
return;
@@ -165,25 +165,25 @@ function render() {
if (options.depends) {
if (!outputbase) {
console.error("option --depends requires an output path to be specified");
console.error('option --depends requires an output path to be specified');
process.exitCode = 1;
return;
}
process.stdout.write(outputbase + ": ");
process.stdout.write(outputbase + ': ');
}
if (!sourceMapFileInline) {
var writeSourceMap = function(output, onDone) {
output = output || "";
output = output || '';
var filename = sourceMapOptions.sourceMapFullFilename;
ensureDirectory(filename);
fs.writeFile(filename, output, 'utf8', function (err) {
if (err) {
var description = "Error: ";
var description = 'Error: ';
if (errno && errno.errno[err.errno]) {
description += errno.errno[err.errno].description;
} else {
description += err.code + " " + err.message;
description += err.code + ' ' + err.message;
}
console.error('lessc: failed to create file ' + filename);
console.error(description);
@@ -211,11 +211,11 @@ function render() {
ensureDirectory(output);
fs.writeFile(output, result.css, {encoding: 'utf8'}, function (err) {
if (err) {
var description = "Error: ";
var description = 'Error: ';
if (errno && errno.errno[err.errno]) {
description += errno.errno[err.errno].description;
} else {
description += err.code + " " + err.message;
description += err.code + ' ' + err.message;
}
console.error('lessc: failed to create file ' + output);
console.error(description);
@@ -233,9 +233,9 @@ function render() {
var logDependencies = function(options, result) {
if (options.depends) {
var depends = "";
var depends = '';
for (var i = 0; i < result.imports.length; i++) {
depends += result.imports[i] + " ";
depends += result.imports[i] + ' ';
}
console.log(depends);
}
@@ -243,7 +243,7 @@ function render() {
var parseLessFile = function (e, data) {
if (e) {
console.error("lessc: " + e.message);
console.error('lessc: ' + e.message);
process.exitCode = 1;
return;
}
@@ -320,8 +320,8 @@ function processPluginQueue() {
var x = 0;
function pluginError(name) {
console.error("Unable to load plugin " + name +
" please make sure that it is installed under or at the same level as less");
console.error('Unable to load plugin ' + name +
' please make sure that it is installed under or at the same level as less');
process.exitCode = 1;
}
function pluginFinished(plugin) {
@@ -368,7 +368,7 @@ function processPluginQueue() {
switch (arg) {
case 'v':
case 'version':
console.log("lessc " + less.version.join('.') + " (Less Compiler) [JavaScript]");
console.log('lessc ' + less.version.join('.') + ' (Less Compiler) [JavaScript]');
continueProcessing = false;
break;
case 'verbose':
@@ -475,23 +475,23 @@ function processPluginQueue() {
options.rootpath = match[2].replace(/\\/g, '/');
}
break;
case "ru":
case "relative-urls":
case 'ru':
case 'relative-urls':
options.relativeUrls = true;
break;
case "sm":
case "strict-math":
case 'sm':
case 'strict-math':
if (checkArgFunc(arg, match[2])) {
options.strictMath = checkBooleanArg(match[2]);
}
break;
case "su":
case "strict-units":
case 'su':
case 'strict-units':
if (checkArgFunc(arg, match[2])) {
options.strictUnits = checkBooleanArg(match[2]);
}
break;
case "global-var":
case 'global-var':
if (checkArgFunc(arg, match[2])) {
if (!options.globalVars) {
options.globalVars = {};
@@ -499,7 +499,7 @@ function processPluginQueue() {
parseVariableOption(match[2], options.globalVars);
}
break;
case "modify-var":
case 'modify-var':
if (checkArgFunc(arg, match[2])) {
if (!options.modifyVars) {
options.modifyVars = {};

2379
dist/less.js vendored

File diff suppressed because it is too large Load Diff

13
dist/less.min.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
var addDataAttr = require("./utils").addDataAttr,
browser = require("./browser");
var addDataAttr = require('./utils').addDataAttr,
browser = require('./browser');
module.exports = function(window, options) {

View File

@@ -8,7 +8,7 @@
// TODO - consider switching this out for a recommendation for this polyfill?
// <script src="https://cdn.polyfill.io/v2/polyfill.min.js"></script>
// Browsers have good Promise support
require("promise/polyfill");
require('promise/polyfill');
var options = require('../less/default-options')();
@@ -19,7 +19,7 @@ if (window.less) {
}
}
}
require("./add-default-options")(window, options);
require('./add-default-options')(window, options);
options.plugins = options.plugins || [];
@@ -27,7 +27,7 @@ if (window.LESS_PLUGINS) {
options.plugins = options.plugins.concat(window.LESS_PLUGINS);
}
var less = module.exports = require("./index")(window, options);
var less = module.exports = require('./index')(window, options);
window.less = less;

View File

@@ -1,4 +1,4 @@
var utils = require("./utils");
var utils = require('./utils');
module.exports = {
createCSS: function (document, styles, sheet) {
// Strip the query-string
@@ -50,14 +50,14 @@ module.exports = {
try {
styleNode.styleSheet.cssText = styles;
} catch (e) {
throw new Error("Couldn't reassign styleSheet.cssText.");
throw new Error('Couldn\'t reassign styleSheet.cssText.');
}
}
},
currentScript: function(window) {
var document = window.document;
return document.currentScript || (function() {
var scripts = document.getElementsByTagName("script");
var scripts = document.getElementsByTagName('script');
return scripts[scripts.length - 1];
})();
}

View File

@@ -29,11 +29,12 @@ module.exports = function(window, options, logger) {
vars = cache && cache.getItem(path + ':vars');
modifyVars = modifyVars || {};
vars = vars || "{}"; // if not set, treat as the JSON representation of an empty object
if (timestamp && webInfo.lastModified &&
(new Date(webInfo.lastModified).valueOf() ===
new Date(timestamp).valueOf()) &&
(!modifyVars && !vars || JSON.stringify(modifyVars) === vars)) {
JSON.stringify(modifyVars) === vars) {
// Use local copy
return css;
}

View File

@@ -1,20 +1,20 @@
var utils = require("./utils"),
browser = require("./browser");
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 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";
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> ";
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) {
@@ -77,15 +77,15 @@ module.exports = function(window, less, options) {
].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"
'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') {
@@ -116,12 +116,12 @@ module.exports = function(window, less, options) {
}
function removeError(path) {
if (!options.errorReporting || options.errorReporting === "html") {
if (!options.errorReporting || options.errorReporting === 'html') {
removeErrorHTML(path);
} else if (options.errorReporting === "console") {
} else if (options.errorReporting === 'console') {
removeErrorConsole(path);
} else if (typeof options.errorReporting === 'function') {
options.errorReporting("remove", path);
options.errorReporting('remove', path);
}
}
@@ -129,8 +129,8 @@ module.exports = function(window, less, options) {
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 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) {
@@ -154,12 +154,12 @@ module.exports = function(window, less, options) {
}
function error(e, rootHref) {
if (!options.errorReporting || options.errorReporting === "html") {
if (!options.errorReporting || options.errorReporting === 'html') {
errorHTML(e, rootHref);
} else if (options.errorReporting === "console") {
} else if (options.errorReporting === 'console') {
errorConsole(e, rootHref);
} else if (typeof options.errorReporting === 'function') {
options.errorReporting("add", e, rootHref);
options.errorReporting('add', e, rootHref);
}
}

View File

@@ -2,7 +2,7 @@
module.exports = function(options, logger) {
var AbstractFileManager = require("../less/environment/abstract-file-manager.js");
var AbstractFileManager = require('../less/environment/abstract-file-manager.js');
var fileCache = {};
@@ -29,7 +29,7 @@ module.exports = function(options, logger) {
if (typeof xhr.overrideMimeType === 'function') {
xhr.overrideMimeType('text/css');
}
logger.debug("XHR: Getting '" + url + "'");
logger.debug('XHR: Getting \'' + url + '\'');
xhr.open('GET', url, async);
xhr.setRequestHeader('Accept', type || 'text/x-less, text/css; q=0.9, */*; q=0.5');
xhr.send(null);
@@ -37,7 +37,7 @@ module.exports = function(options, logger) {
function handleResponse(xhr, callback, errback) {
if (xhr.status >= 200 && xhr.status < 300) {
callback(xhr.responseText,
xhr.getResponseHeader("Last-Modified"));
xhr.getResponseHeader('Last-Modified'));
} else if (typeof errback === 'function') {
errback(xhr.status, url);
}
@@ -91,7 +91,7 @@ module.exports = function(options, logger) {
var lessText = fileCache[href];
return resolve({ contents: lessText, filename: href, webInfo: { lastModified: new Date() }});
} catch (e) {
return reject({ filename: href, message: "Error loading file " + href + " error was " + e.message });
return reject({ filename: href, message: 'Error loading file ' + href + ' error was ' + e.message });
}
}
@@ -102,7 +102,7 @@ module.exports = function(options, logger) {
// Use remote copy (re-parse)
resolve({ contents: data, filename: href, webInfo: { lastModified: lastModified }});
}, function doXHRError(status, url) {
reject({ type: 'File', message: "'" + url + "' wasn't found (" + status + ")", href: href });
reject({ type: 'File', message: '\'' + url + '\' wasn\'t found (' + status + ')', href: href });
});
});
};

View File

@@ -1,24 +1,24 @@
module.exports = function() {
var functionRegistry = require("./../less/functions/function-registry");
var functionRegistry = require('./../less/functions/function-registry');
function imageSize() {
throw {
type: "Runtime",
message: "Image size functions are not supported in browser version of less"
type: 'Runtime',
message: 'Image size functions are not supported in browser version of less'
};
}
var imageFunctions = {
"image-size": function(filePathNode) {
'image-size': function(filePathNode) {
imageSize(this, filePathNode);
return -1;
},
"image-width": function(filePathNode) {
'image-width': function(filePathNode) {
imageSize(this, filePathNode);
return -1;
},
"image-height": function(filePathNode) {
'image-height': function(filePathNode) {
imageSize(this, filePathNode);
return -1;
}

View File

@@ -2,8 +2,8 @@
// index.js
// Should expose the additional browser functions on to the less object
//
var addDataAttr = require("./utils").addDataAttr,
browser = require("./browser");
var addDataAttr = require('./utils').addDataAttr,
browser = require('./browser');
module.exports = function(window, options) {
var document = window.document;
@@ -11,15 +11,15 @@ module.exports = function(window, options) {
less.options = options;
var environment = less.environment,
FileManager = require("./file-manager")(options, less.logger),
FileManager = require('./file-manager')(options, less.logger),
fileManager = new FileManager();
environment.addFileManager(fileManager);
less.FileManager = FileManager;
less.PluginLoader = require("./plugin-loader");
less.PluginLoader = require('./plugin-loader');
require("./log-listener")(less, options);
var errors = require("./error-reporting")(window, less, options);
var cache = less.cache = options.cache || require("./cache")(window, options, less.logger);
require('./log-listener')(less, options);
var errors = require('./error-reporting')(window, less, options);
var cache = less.cache = options.cache || require('./cache')(window, options, less.logger);
require('./image-size')(less.environment);
// Setup user functions - Deprecate?
@@ -59,7 +59,7 @@ module.exports = function(window, options) {
less.render(lessText, instanceOptions,
bind(function(style, e, result) {
if (e) {
errors.add(e, "inline");
errors.add(e, 'inline');
} else {
style.type = 'text/css';
if (style.styleSheet) {
@@ -222,7 +222,7 @@ module.exports = function(window, options) {
endTime = new Date();
totalMilliseconds = endTime - startTime;
less.logger.info("Less has finished and no sheets were loaded.");
less.logger.info('Less has finished and no sheets were loaded.');
resolve({
startTime: startTime,
endTime: endTime,
@@ -239,12 +239,12 @@ module.exports = function(window, options) {
return;
}
if (webInfo.local) {
less.logger.info("Loading " + sheet.href + " from cache.");
less.logger.info('Loading ' + sheet.href + ' from cache.');
} else {
less.logger.info("Rendered " + sheet.href + " successfully.");
less.logger.info('Rendered ' + sheet.href + ' successfully.');
}
browser.createCSS(window.document, css, sheet);
less.logger.info("CSS for " + sheet.href + " generated in " + (new Date() - endTime) + 'ms');
less.logger.info('CSS for ' + sheet.href + ' generated in ' + (new Date() - endTime) + 'ms');
// Count completed sheet
remainingSheets--;
@@ -252,7 +252,7 @@ module.exports = function(window, options) {
// Check if the last remaining sheet was processed and then call the promise
if (remainingSheets === 0) {
totalMilliseconds = new Date() - startTime;
less.logger.info("Less has finished. CSS generated in " + totalMilliseconds + 'ms');
less.logger.info('Less has finished. CSS generated in ' + totalMilliseconds + 'ms');
resolve({
startTime: startTime,
endTime: endTime,

View File

@@ -1,15 +1,14 @@
// TODO: Add tests for browser @plugin
/*global window */
/* global window */
var AbstractPluginLoader = require("../less/environment/abstract-plugin-loader.js");
var AbstractPluginLoader = require('../less/environment/abstract-plugin-loader.js');
/**
* Browser Plugin Loader
*/
var PluginLoader = function(less) {
this.less = less;
// shim for browser require?
this.require = require;
// Should we shim this.require for browser? Probably not?
};
PluginLoader.prototype = new AbstractPluginLoader();

View File

@@ -10,7 +10,7 @@ module.exports = {
addDataAttr: function(options, tag) {
for (var opt in tag.dataset) {
if (tag.dataset.hasOwnProperty(opt)) {
if (opt === "env" || opt === "dumpLineNumbers" || opt === "rootpath" || opt === "errorReporting") {
if (opt === 'env' || opt === 'dumpLineNumbers' || opt === 'rootpath' || opt === 'errorReporting') {
options[opt] = tag.dataset[opt];
} else {
try {

View File

@@ -9,6 +9,6 @@ module.exports = {
return require('mime').charsets.lookup(mime);
},
getSourceMapGenerator: function getSourceMapGenerator() {
return require("source-map").SourceMapGenerator;
return require('source-map').SourceMapGenerator;
}
};

View File

@@ -1,7 +1,7 @@
var path = require('path'),
fs = require('./fs'),
PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise,
AbstractFileManager = require("../less/environment/abstract-file-manager.js");
AbstractFileManager = require('../less/environment/abstract-file-manager.js');
var FileManager = function() {
this.contents = {};
@@ -23,7 +23,7 @@ FileManager.prototype.loadFile = function(filename, currentDirectory, options, e
filenamesTried = [],
self = this,
prefix = filename.slice(0, 1),
explicit = prefix === "." || prefix === "/",
explicit = prefix === '.' || prefix === '/',
result = null,
isNodeModule = false,
npmPrefix = 'npm://';
@@ -162,7 +162,7 @@ FileManager.prototype.loadFile = function(filename, currentDirectory, options, e
}
})(0);
} else {
reject({ type: 'File', message: "'" + filename + "' wasn't found. Tried - " + filenamesTried.join(",") });
reject({ type: 'File', message: '\'' + filename + '\' wasn\'t found. Tried - ' + filenamesTried.join(',') });
}
}(0));
}

View File

@@ -1,10 +1,10 @@
var fs;
try
{
fs = require("graceful-fs");
fs = require('graceful-fs');
}
catch (e)
{
fs = require("fs");
fs = require('fs');
}
module.exports = fs;

View File

@@ -1,7 +1,7 @@
module.exports = function(environment) {
var Dimension = require("../less/tree/dimension"),
Expression = require("../less/tree/expression"),
functionRegistry = require("./../less/functions/function-registry");
var Dimension = require('../less/tree/dimension'),
Expression = require('../less/tree/expression'),
functionRegistry = require('./../less/functions/function-registry');
function imageSize(functionContext, filePathNode) {
var filePath = filePathNode.value;
@@ -20,8 +20,8 @@ module.exports = function(environment) {
if (!fileManager) {
throw {
type: "File",
message: "Can not set up FileManager for " + filePathNode
type: 'File',
message: 'Can not set up FileManager for ' + filePathNode
};
}
@@ -36,20 +36,20 @@ module.exports = function(environment) {
}
var imageFunctions = {
"image-size": function(filePathNode) {
'image-size': function(filePathNode) {
var size = imageSize(this, filePathNode);
return new Expression([
new Dimension(size.width, "px"),
new Dimension(size.height, "px")
new Dimension(size.width, 'px'),
new Dimension(size.height, 'px')
]);
},
"image-width": function(filePathNode) {
'image-width': function(filePathNode) {
var size = imageSize(this, filePathNode);
return new Dimension(size.width, "px");
return new Dimension(size.width, 'px');
},
"image-height": function(filePathNode) {
'image-height': function(filePathNode) {
var size = imageSize(this, filePathNode);
return new Dimension(size.height, "px");
return new Dimension(size.height, 'px');
}
};

View File

@@ -1,7 +1,7 @@
var environment = require("./environment"),
FileManager = require("./file-manager"),
UrlFileManager = require("./url-file-manager"),
createFromEnvironment = require("../less"),
var environment = require('./environment'),
FileManager = require('./file-manager'),
UrlFileManager = require('./url-file-manager'),
createFromEnvironment = require('../less'),
less = createFromEnvironment(environment, [new FileManager(), new UrlFileManager()]),
lesscHelper = require('./lessc-helper'),
path = require('path');
@@ -9,8 +9,8 @@ var environment = require("./environment"),
// allow people to create less with their own environment
less.createFromEnvironment = createFromEnvironment;
less.lesscHelper = lesscHelper;
less.PluginLoader = require("./plugin-loader");
less.fs = require("./fs");
less.PluginLoader = require('./plugin-loader');
less.fs = require('./fs');
less.FileManager = FileManager;
less.UrlFileManager = UrlFileManager;

View File

@@ -21,60 +21,60 @@ var lessc_helper = {
// Print command line options
printUsage: function() {
console.log("usage: lessc [option option=parameter ...] <source> [destination]");
console.log("");
console.log("If source is set to `-' (dash or hyphen-minus), input is read from stdin.");
console.log("");
console.log("options:");
console.log(" -h, --help Prints help (this message) and exit.");
console.log(" --include-path=PATHS Sets include paths. Separated by `:'. `;' also supported on windows.");
console.log(" -M, --depends Outputs a makefile import dependency list to stdout.");
console.log(" --no-color Disables colorized output.");
console.log(" --ie-compat Enables IE8 compatibility checks.");
console.log(" --js Enables inline JavaScript in less files");
console.log(" -l, --lint Syntax check only (lint).");
console.log(" -s, --silent Suppresses output of error messages.");
console.log(" --strict-imports Forces evaluation of imports.");
console.log(" --insecure Allows imports from insecure https hosts.");
console.log(" -v, --version Prints version number and exit.");
console.log(" --verbose Be verbose.");
console.log(" --source-map[=FILENAME] Outputs a v3 sourcemap to the filename (or output filename.map).");
console.log(" --source-map-rootpath=X Adds this path onto the sourcemap filename and less file paths.");
console.log(" --source-map-basepath=X Sets sourcemap base path, defaults to current working directory.");
console.log(" --source-map-include-source Puts the less files into the map instead of referencing them.");
console.log(" --source-map-inline Puts the map (and any less files) as a base64 data uri into the output css file.");
console.log(" --source-map-url=URL Sets a custom URL to map file, for sourceMappingURL comment");
console.log(" in generated CSS file.");
console.log(" -rp, --rootpath=URL Sets rootpath for url rewriting in relative imports and urls");
console.log(" Works with or without the relative-urls option.");
console.log(" -ru, --relative-urls Re-writes relative urls to the base less file.");
console.log(" -sm=on|off Turns on or off strict math, where in strict mode, math.");
console.log(" --strict-math=on|off Requires brackets. This option may default to on and then");
console.log(" be removed in the future.");
console.log(" -su=on|off Allows mixed units, e.g. 1px+1em or 1px*1px which have units");
console.log(" --strict-units=on|off that cannot be represented.");
console.log(" --global-var='VAR=VALUE' Defines a variable that can be referenced by the file.");
console.log(" --modify-var='VAR=VALUE' Modifies a variable already declared in the file.");
console.log(" --url-args='QUERYSTRING' Adds params into url tokens (e.g. 42, cb=42 or 'a=1&b=2')");
console.log(" --plugin=PLUGIN=OPTIONS Loads a plugin. You can also omit the --plugin= if the plugin begins");
console.log(" less-plugin. E.g. the clean css plugin is called less-plugin-clean-css");
console.log(" once installed (npm install less-plugin-clean-css), use either with");
console.log(" --plugin=less-plugin-clean-css or just --clean-css");
console.log(" specify options afterwards e.g. --plugin=less-plugin-clean-css=\"advanced\"");
console.log(" or --clean-css=\"advanced\"");
console.log("");
console.log("-------------------------- Deprecated ----------------");
console.log(" --line-numbers=TYPE Outputs filename and line numbers.");
console.log(" TYPE can be either 'comments', which will output");
console.log(" the debug info within comments, 'mediaquery'");
console.log(" that will output the information within a fake");
console.log(" media query which is compatible with the SASS");
console.log(" format, and 'all' which will do both.");
console.log(" -x, --compress Compresses output by removing some whitespaces.");
console.log(" We recommend you use a dedicated minifer like less-plugin-clean-css");
console.log("");
console.log("Report bugs to: http://github.com/less/less.js/issues");
console.log("Home page: <http://lesscss.org/>");
console.log('usage: lessc [option option=parameter ...] <source> [destination]');
console.log('');
console.log('If source is set to `-\' (dash or hyphen-minus), input is read from stdin.');
console.log('');
console.log('options:');
console.log(' -h, --help Prints help (this message) and exit.');
console.log(' --include-path=PATHS Sets include paths. Separated by `:\'. `;\' also supported on windows.');
console.log(' -M, --depends Outputs a makefile import dependency list to stdout.');
console.log(' --no-color Disables colorized output.');
console.log(' --ie-compat Enables IE8 compatibility checks.');
console.log(' --js Enables inline JavaScript in less files');
console.log(' -l, --lint Syntax check only (lint).');
console.log(' -s, --silent Suppresses output of error messages.');
console.log(' --strict-imports Forces evaluation of imports.');
console.log(' --insecure Allows imports from insecure https hosts.');
console.log(' -v, --version Prints version number and exit.');
console.log(' --verbose Be verbose.');
console.log(' --source-map[=FILENAME] Outputs a v3 sourcemap to the filename (or output filename.map).');
console.log(' --source-map-rootpath=X Adds this path onto the sourcemap filename and less file paths.');
console.log(' --source-map-basepath=X Sets sourcemap base path, defaults to current working directory.');
console.log(' --source-map-include-source Puts the less files into the map instead of referencing them.');
console.log(' --source-map-inline Puts the map (and any less files) as a base64 data uri into the output css file.');
console.log(' --source-map-url=URL Sets a custom URL to map file, for sourceMappingURL comment');
console.log(' in generated CSS file.');
console.log(' -rp, --rootpath=URL Sets rootpath for url rewriting in relative imports and urls');
console.log(' Works with or without the relative-urls option.');
console.log(' -ru, --relative-urls Re-writes relative urls to the base less file.');
console.log(' -sm=on|off Turns on or off strict math, where in strict mode, math.');
console.log(' --strict-math=on|off Requires brackets. This option may default to on and then');
console.log(' be removed in the future.');
console.log(' -su=on|off Allows mixed units, e.g. 1px+1em or 1px*1px which have units');
console.log(' --strict-units=on|off that cannot be represented.');
console.log(' --global-var=\'VAR=VALUE\' Defines a variable that can be referenced by the file.');
console.log(' --modify-var=\'VAR=VALUE\' Modifies a variable already declared in the file.');
console.log(' --url-args=\'QUERYSTRING\' Adds params into url tokens (e.g. 42, cb=42 or \'a=1&b=2\')');
console.log(' --plugin=PLUGIN=OPTIONS Loads a plugin. You can also omit the --plugin= if the plugin begins');
console.log(' less-plugin. E.g. the clean css plugin is called less-plugin-clean-css');
console.log(' once installed (npm install less-plugin-clean-css), use either with');
console.log(' --plugin=less-plugin-clean-css or just --clean-css');
console.log(' specify options afterwards e.g. --plugin=less-plugin-clean-css="advanced"');
console.log(' or --clean-css="advanced"');
console.log('');
console.log('-------------------------- Deprecated ----------------');
console.log(' --line-numbers=TYPE Outputs filename and line numbers.');
console.log(' TYPE can be either \'comments\', which will output');
console.log(' the debug info within comments, \'mediaquery\'');
console.log(' that will output the information within a fake');
console.log(' media query which is compatible with the SASS');
console.log(' format, and \'all\' which will do both.');
console.log(' -x, --compress Compresses output by removing some whitespaces.');
console.log(' We recommend you use a dedicated minifer like less-plugin-clean-css');
console.log('');
console.log('Report bugs to: http://github.com/less/less.js/issues');
console.log('Home page: <http://lesscss.org/>');
}
};

View File

@@ -1,14 +1,13 @@
var path = require("path"),
var path = require('path'),
PromiseConstructor = typeof Promise === 'undefined' ? require('promise') : Promise,
AbstractPluginLoader = require("../less/environment/abstract-plugin-loader.js");
AbstractPluginLoader = require('../less/environment/abstract-plugin-loader.js');
/**
* Node Plugin Loader
*/
var PluginLoader = function(less) {
this.less = less;
this.require = require;
this.requireRelative = function(prefix) {
this.require = function(prefix) {
prefix = path.dirname(prefix);
return function(id) {
var str = id.substr(0, 2);
@@ -25,9 +24,8 @@ var PluginLoader = function(less) {
PluginLoader.prototype = new AbstractPluginLoader();
PluginLoader.prototype.loadPlugin = function(filename, basePath, context, environment, fileManager) {
var self = this;
var prefix = filename.slice(0, 1);
var explicit = prefix === "." || prefix === "/" || filename.slice(-3).toLowerCase() === ".js";
var explicit = prefix === '.' || prefix === '/' || filename.slice(-3).toLowerCase() === '.js';
if (!explicit) {
context.prefixes = ['less-plugin-', ''];
}
@@ -36,7 +34,6 @@ PluginLoader.prototype.loadPlugin = function(filename, basePath, context, enviro
fileManager.loadFile(filename, basePath, context, environment).then(
function(data) {
try {
self.require = self.requireRelative(data.filename);
fulfill(data);
}
catch (e) {

View File

@@ -2,8 +2,8 @@ var isUrlRe = /^(?:https?:)?\/\//i,
url = require('url'),
request,
PromiseConstructor,
AbstractFileManager = require("../less/environment/abstract-file-manager.js"),
logger = require("../less/logger");
AbstractFileManager = require('../less/environment/abstract-file-manager.js'),
logger = require('../less/logger');
var UrlFileManager = function() {
};
@@ -24,7 +24,7 @@ UrlFileManager.prototype.loadFile = function(filename, currentDirectory, options
catch (e) { request = null; }
}
if (!request) {
reject({ type: 'File', message: "optional dependency 'request' required to import over http(s)\n" });
reject({ type: 'File', message: 'optional dependency \'request\' required to import over http(s)\n' });
return;
}
@@ -32,17 +32,17 @@ UrlFileManager.prototype.loadFile = function(filename, currentDirectory, options
urlObj = url.parse(urlStr);
if (!urlObj.protocol) {
urlObj.protocol = "http";
urlObj.protocol = 'http';
urlStr = urlObj.format();
}
request.get({uri: urlStr, strictSSL: !options.insecure }, function (error, res, body) {
if (error) {
reject({ type: 'File', message: "resource '" + urlStr + "' gave this Error:\n " + error + "\n" });
reject({ type: 'File', message: 'resource \'' + urlStr + '\' gave this Error:\n ' + error + '\n' });
return;
}
if (res && res.statusCode === 404) {
reject({ type: 'File', message: "resource '" + urlStr + "' was not found\n" });
reject({ type: 'File', message: 'resource \'' + urlStr + '\' was not found\n' });
return;
}
if (!body) {

View File

@@ -4,7 +4,7 @@
function formatError(ctx, options) {
options = options || {};
var message = "";
var message = '';
var extract = ctx.extract;
var error = [];
@@ -124,7 +124,7 @@ less.Parser.fileLoader = function (file, currentFileInfo, callback, env) {
try {
data = readFile(href);
} catch (e) {
callback({ type: 'File', message: "'" + less.modules.path.basename(href) + "' wasn't found" });
callback({ type: 'File', message: '\'' + less.modules.path.basename(href) + '\' wasn\'t found' });
return;
}
@@ -152,7 +152,7 @@ function writeFile(filename, content) {
var checkArgFunc = function(arg, option) {
if (!option) {
print(arg + " option requires a parameter");
print(arg + ' option requires a parameter');
continueProcessing = false;
return false;
}
@@ -162,14 +162,14 @@ function writeFile(filename, content) {
var checkBooleanArg = function(arg) {
var onOff = /^((on|t|true|y|yes)|(off|f|false|n|no))$/i.exec(arg);
if (!onOff) {
print(" unable to parse " + arg + " as a boolean. use one of on/t/true/y/yes/off/f/false/n/no");
print(' unable to parse ' + arg + ' as a boolean. use one of on/t/true/y/yes/off/f/false/n/no');
continueProcessing = false;
return false;
}
return Boolean(onOff[2]);
};
var warningMessages = "";
var warningMessages = '';
var sourceMapFileInline = false;
args = args.filter(function (arg) {
@@ -191,7 +191,7 @@ function writeFile(filename, content) {
switch (arg) {
case 'v':
case 'version':
console.log("lessc " + less.version.join('.') + " (Less Compiler) [JavaScript]");
console.log('lessc ' + less.version.join('.') + ' (Less Compiler) [JavaScript]');
continueProcessing = false;
break;
case 'verbose':
@@ -223,7 +223,7 @@ function writeFile(filename, content) {
options.depends = true;
break;
case 'yui-compress':
warningMessages += "yui-compress option has been removed. assuming clean-css.";
warningMessages += 'yui-compress option has been removed. assuming clean-css.';
options.cleancss = true;
break;
case 'clean-css':
@@ -307,18 +307,18 @@ function writeFile(filename, content) {
options.rootpath = match[2].replace(/\\/g, '/');
}
break;
case "ru":
case "relative-urls":
case 'ru':
case 'relative-urls':
options.relativeUrls = true;
break;
case "sm":
case "strict-math":
case 'sm':
case 'strict-math':
if (checkArgFunc(arg, match[2])) {
options.strictMath = checkBooleanArg(match[2]);
}
break;
case "su":
case "strict-units":
case 'su':
case 'strict-units':
if (checkArgFunc(arg, match[2])) {
options.strictUnits = checkBooleanArg(match[2]);
}
@@ -351,20 +351,20 @@ function writeFile(filename, content) {
// options.sourceMapBasepath = '';
if (options.sourceMap === true) {
console.log("output: " + output);
console.log('output: ' + output);
if (!output && !sourceMapFileInline) {
console.log("the sourcemap option only has an optional filename if the css filename is given");
console.log('the sourcemap option only has an optional filename if the css filename is given');
return;
}
options.sourceMapFullFilename = options.sourceMapOutputFilename + ".map";
options.sourceMapFullFilename = options.sourceMapOutputFilename + '.map';
options.sourceMap = less.modules.path.basename(options.sourceMapFullFilename);
} else if (options.sourceMap) {
options.sourceMapOutputFilename = options.sourceMap;
}
if (!name) {
console.log("lessc: no inout files");
console.log("");
console.log('lessc: no inout files');
console.log('');
// TODO
// require('../lib/less/lessc_helper').printUsage();
currentErrorcode = 1;
@@ -388,10 +388,10 @@ function writeFile(filename, content) {
if (options.depends) {
if (!outputbase) {
console.log("option --depends requires an output path to be specified");
console.log('option --depends requires an output path to be specified');
return;
}
console.log(outputbase + ": ");
console.log(outputbase + ': ');
}
if (!name) {
@@ -420,7 +420,7 @@ function writeFile(filename, content) {
result = root.toCSS(options);
if (output) {
writeFile(output, result);
console.log("Written to " + output);
console.log('Written to ' + output);
} else {
print(result);
}

View File

@@ -36,7 +36,7 @@ var parseCopyProperties = [
contexts.Parse = function(options) {
copyFromOriginal(options, this, parseCopyProperties);
if (typeof this.paths === "string") { this.paths = [this.paths]; }
if (typeof this.paths === 'string') { this.paths = [this.paths]; }
};
var evalCopyProperties = [
@@ -56,12 +56,27 @@ var evalCopyProperties = [
contexts.Eval = function(options, frames) {
copyFromOriginal(options, this, evalCopyProperties);
if (typeof this.paths === "string") { this.paths = [this.paths]; }
if (typeof this.paths === 'string') { this.paths = [this.paths]; }
this.frames = frames || [];
this.importantScope = this.importantScope || [];
};
contexts.Eval.prototype.enterCalc = function () {
if (!this.calcStack) {
this.calcStack = [];
}
this.calcStack.push(true);
this.inCalc = true;
};
contexts.Eval.prototype.exitCalc = function () {
this.calcStack.pop();
if (!this.calcStack) {
this.inCalc = false;
}
};
contexts.Eval.prototype.inParenthesis = function () {
if (!this.parensStack) {
this.parensStack = [];
@@ -73,6 +88,7 @@ contexts.Eval.prototype.outOfParenthesis = function () {
this.parensStack.pop();
};
contexts.Eval.prototype.inCalc = false;
contexts.Eval.prototype.mathOn = true;
contexts.Eval.prototype.isMathOn = function (op) {
if (!this.mathOn) {
@@ -93,17 +109,17 @@ contexts.Eval.prototype.isPathRelative = function (path) {
contexts.Eval.prototype.normalizePath = function( path ) {
var
segments = path.split("/").reverse(),
segments = path.split('/').reverse(),
segment;
path = [];
while (segments.length !== 0 ) {
segment = segments.pop();
switch ( segment ) {
case ".":
case '.':
break;
case "..":
if ((path.length === 0) || (path[path.length - 1] === "..")) {
case '..':
if ((path.length === 0) || (path[path.length - 1] === '..')) {
path.push( segment );
} else {
path.pop();
@@ -115,7 +131,7 @@ contexts.Eval.prototype.normalizePath = function( path ) {
}
}
return path.join("/");
return path.join('/');
};
// todo - do the same for the toCSS ?

View File

@@ -1,4 +1,4 @@
module.exports = {
colors: require("./colors"),
unitConversions: require("./unit-conversions")
colors: require('./colors'),
unitConversions: require('./unit-conversions')
};

View File

@@ -11,7 +11,7 @@ abstractFileManager.prototype.getPath = function (filename) {
j = filename.lastIndexOf('\\');
}
if (j < 0) {
return "";
return '';
}
return filename.slice(0, j + 1);
};
@@ -48,9 +48,9 @@ abstractFileManager.prototype.pathDiff = function pathDiff(url, baseUrl) {
var urlParts = this.extractUrlParts(url),
baseUrlParts = this.extractUrlParts(baseUrl),
i, max, urlDirectories, baseUrlDirectories, diff = "";
i, max, urlDirectories, baseUrlDirectories, diff = '';
if (urlParts.hostPart !== baseUrlParts.hostPart) {
return "";
return '';
}
max = Math.max(baseUrlParts.directories.length, urlParts.directories.length);
for (i = 0; i < max; i++) {
@@ -59,10 +59,10 @@ abstractFileManager.prototype.pathDiff = function pathDiff(url, baseUrl) {
baseUrlDirectories = baseUrlParts.directories.slice(i);
urlDirectories = urlParts.directories.slice(i);
for (i = 0; i < baseUrlDirectories.length - 1; i++) {
diff += "../";
diff += '../';
}
for (i = 0; i < urlDirectories.length - 1; i++) {
diff += urlDirectories[i] + "/";
diff += urlDirectories[i] + '/';
}
return diff;
};
@@ -79,31 +79,31 @@ abstractFileManager.prototype.extractUrlParts = function extractUrlParts(url, ba
returner = {}, rawDirectories = [], directories = [], i, baseUrlParts;
if (!urlParts) {
throw new Error("Could not parse sheet href - '" + url + "'");
throw new Error('Could not parse sheet href - \'' + url + '\'');
}
// Stylesheets in IE don't always return the full path
if (baseUrl && (!urlParts[1] || urlParts[2])) {
baseUrlParts = baseUrl.match(urlPartsRegex);
if (!baseUrlParts) {
throw new Error("Could not parse page url - '" + baseUrl + "'");
throw new Error('Could not parse page url - \'' + baseUrl + '\'');
}
urlParts[1] = urlParts[1] || baseUrlParts[1] || "";
urlParts[1] = urlParts[1] || baseUrlParts[1] || '';
if (!urlParts[2]) {
urlParts[3] = baseUrlParts[3] + urlParts[3];
}
}
if (urlParts[3]) {
rawDirectories = urlParts[3].replace(/\\/g, "/").split("/");
rawDirectories = urlParts[3].replace(/\\/g, '/').split('/');
// collapse '..' and skip '.'
for (i = 0; i < rawDirectories.length; i++) {
if (rawDirectories[i] === "..") {
if (rawDirectories[i] === '..') {
directories.pop();
}
else if (rawDirectories[i] !== ".") {
else if (rawDirectories[i] !== '.') {
directories.push(rawDirectories[i]);
}
@@ -112,11 +112,11 @@ abstractFileManager.prototype.extractUrlParts = function extractUrlParts(url, ba
returner.hostPart = urlParts[1];
returner.directories = directories;
returner.rawPath = (urlParts[1] || "") + rawDirectories.join("/");
returner.path = (urlParts[1] || "") + directories.join("/");
returner.rawPath = (urlParts[1] || '') + rawDirectories.join('/');
returner.path = (urlParts[1] || '') + directories.join('/');
returner.filename = urlParts[4];
returner.fileUrl = returner.path + (urlParts[4] || "");
returner.url = returner.fileUrl + (urlParts[5] || "");
returner.fileUrl = returner.path + (urlParts[4] || '');
returner.url = returner.fileUrl + (urlParts[5] || '');
return returner;
};

View File

@@ -1,17 +1,13 @@
var functionRegistry = require("../functions/function-registry"),
var functionRegistry = require('../functions/function-registry'),
LessError = require('../less-error');
var AbstractPluginLoader = function() {
// Implemented by Node.js plugin loader
this.require = function() {
return null;
}
};
function error(msg, type) {
throw new LessError(
{
type: type || 'Syntax',
message: msg
}
);
}
AbstractPluginLoader.prototype.evalPlugin = function(contents, context, imports, pluginOptions, fileInfo) {
var loader,
@@ -19,12 +15,13 @@ AbstractPluginLoader.prototype.evalPlugin = function(contents, context, imports,
pluginObj,
localModule,
pluginManager,
filename;
filename,
result;
pluginManager = context.pluginManager;
if (fileInfo) {
if (typeof fileInfo === "string") {
if (typeof fileInfo === 'string') {
filename = fileInfo;
}
else {
@@ -37,15 +34,18 @@ AbstractPluginLoader.prototype.evalPlugin = function(contents, context, imports,
pluginObj = pluginManager.get(filename);
if (pluginObj) {
this.trySetOptions(pluginObj, filename, shortname, pluginOptions);
result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);
if (result) {
return result;
}
try {
if (pluginObj.use) {
pluginObj.use.call(this.context, pluginObj);
}
}
catch (e) {
e.message = 'Error during @plugin call';
return new this.less.LessError(e, imports, filename);
e.message = e.message || 'Error during @plugin call';
return new LessError(e, imports, filename);
}
return pluginObj;
}
@@ -62,10 +62,11 @@ AbstractPluginLoader.prototype.evalPlugin = function(contents, context, imports,
};
try {
loader = new Function("module", "require", "registerPlugin", "functions", "tree", "less", "fileInfo", contents);
loader(localModule, this.require, registerPlugin, registry, this.less.tree, this.less, fileInfo);
} catch (e) {
return new this.less.LessError(e, imports, filename);
loader = new Function('module', 'require', 'registerPlugin', 'functions', 'tree', 'less', 'fileInfo', contents);
loader(localModule, this.require(filename), registerPlugin, registry, this.less.tree, this.less, fileInfo);
}
catch (e) {
return new LessError(e, imports, filename);
}
if (!pluginObj) {
@@ -73,14 +74,32 @@ AbstractPluginLoader.prototype.evalPlugin = function(contents, context, imports,
}
pluginObj = this.validatePlugin(pluginObj, filename, shortname);
if (pluginObj instanceof LessError) {
return pluginObj;
}
if (pluginObj) {
// Run on first load
pluginManager.addPlugin(pluginObj, fileInfo.filename, registry);
pluginObj.functions = registry.getLocalFunctions();
pluginObj.imports = imports;
pluginObj.filename = filename;
this.trySetOptions(pluginObj, filename, shortname, pluginOptions);
// For < 3.x (or unspecified minVersion) - setOptions() before install()
if (!pluginObj.minVersion || this.compareVersion('3.0.0', pluginObj.minVersion) < 0) {
result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);
if (result) {
return result;
}
}
// Run on first load
pluginManager.addPlugin(pluginObj, fileInfo.filename, registry);
pluginObj.functions = registry.getLocalFunctions();
// Need to call setOptions again because the pluginObj might have functions
result = this.trySetOptions(pluginObj, filename, shortname, pluginOptions);
if (result) {
return result;
}
// Run every @plugin call
try {
@@ -89,13 +108,13 @@ AbstractPluginLoader.prototype.evalPlugin = function(contents, context, imports,
}
}
catch (e) {
e.message = 'Error during @plugin call';
return new this.less.LessError(e, imports, filename);
e.message = e.message || 'Error during @plugin call';
return new LessError(e, imports, filename);
}
}
else {
return new this.less.LessError({ message: "Not a valid plugin" });
return new LessError({ message: 'Not a valid plugin' }, imports, filename);
}
return pluginObj;
@@ -103,18 +122,17 @@ AbstractPluginLoader.prototype.evalPlugin = function(contents, context, imports,
};
AbstractPluginLoader.prototype.trySetOptions = function(plugin, filename, name, options) {
if (options) {
if (!plugin.setOptions) {
error("Options have been provided but the plugin " + name + " does not support any options.");
return null;
}
try {
plugin.setOptions(options);
}
catch (e) {
error("Error setting options on plugin " + name + '\n' + e.message);
return null;
}
if (options && !plugin.setOptions) {
return new LessError({
message: 'Options have been provided but the plugin ' +
name + ' does not support any options.'
});
}
try {
plugin.setOptions && plugin.setOptions(options);
}
catch (e) {
return new LessError(e);
}
};
@@ -122,14 +140,16 @@ AbstractPluginLoader.prototype.validatePlugin = function(plugin, filename, name)
if (plugin) {
// support plugins being a function
// so that the plugin can be more usable programmatically
if (typeof plugin === "function") {
if (typeof plugin === 'function') {
plugin = new plugin();
}
if (plugin.minVersion) {
if (this.compareVersion(plugin.minVersion, this.less.version) < 0) {
error("Plugin " + name + " requires version " + this.versionToString(plugin.minVersion));
return null;
return new LessError({
message: 'Plugin ' + name + ' requires version ' +
this.versionToString(plugin.minVersion)
});
}
}
return plugin;
@@ -138,7 +158,7 @@ AbstractPluginLoader.prototype.validatePlugin = function(plugin, filename, name)
};
AbstractPluginLoader.prototype.compareVersion = function(aVersion, bVersion) {
if (typeof aVersion === "string") {
if (typeof aVersion === 'string') {
aVersion = aVersion.match(/^(\d+)\.?(\d+)?\.?(\d+)?/);
aVersion.shift();
}
@@ -150,9 +170,9 @@ AbstractPluginLoader.prototype.compareVersion = function(aVersion, bVersion) {
return 0;
};
AbstractPluginLoader.prototype.versionToString = function(version) {
var versionString = "";
var versionString = '';
for (var i = 0; i < version.length; i++) {
versionString += (versionString ? "." : "") + version[i];
versionString += (versionString ? '.' : '') + version[i];
}
return versionString;
};

View File

@@ -3,12 +3,12 @@
* environment, file managers, and plugin manager
*/
var logger = require("../logger");
var logger = require('../logger');
var environment = function(externalEnvironment, fileManagers) {
this.fileManagers = fileManagers || [];
externalEnvironment = externalEnvironment || {};
var optionalFunctions = ["encodeBase64", "mimeLookup", "charsetLookup", "getSourceMapGenerator"],
var optionalFunctions = ['encodeBase64', 'mimeLookup', 'charsetLookup', 'getSourceMapGenerator'],
requiredFunctions = [],
functions = requiredFunctions.concat(optionalFunctions);
@@ -18,7 +18,7 @@ var environment = function(externalEnvironment, fileManagers) {
if (environmentFunc) {
this[propName] = environmentFunc.bind(externalEnvironment);
} else if (i < requiredFunctions.length) {
this.warn("missing required function in environment - " + propName);
this.warn('missing required function in environment - ' + propName);
}
}
};
@@ -26,10 +26,10 @@ var environment = function(externalEnvironment, fileManagers) {
environment.prototype.getFileManager = function (filename, currentDirectory, options, environment, isSync) {
if (!filename) {
logger.warn("getFileManager called with no filename.. Please report this issue. continuing.");
logger.warn('getFileManager called with no filename.. Please report this issue. continuing.');
}
if (currentDirectory == null) {
logger.warn("getFileManager called with null directory.. Please report this issue. continuing.");
logger.warn('getFileManager called with null directory.. Please report this issue. continuing.');
}
var fileManagers = this.fileManagers;
@@ -38,7 +38,7 @@ environment.prototype.getFileManager = function (filename, currentDirectory, opt
}
for (var i = fileManagers.length - 1; i >= 0 ; i--) {
var fileManager = fileManagers[i];
if (fileManager[isSync ? "supportsSync" : "supports"](filename, currentDirectory, options, environment)) {
if (fileManager[isSync ? 'supportsSync' : 'supports'](filename, currentDirectory, options, environment)) {
return fileManager;
}
}

View File

@@ -1,7 +1,7 @@
var functionRegistry = require("./function-registry"),
Anonymous = require("../tree/anonymous"),
Keyword = require("../tree/keyword");
var functionRegistry = require('./function-registry'),
Anonymous = require('../tree/anonymous'),
Keyword = require('../tree/keyword');
functionRegistry.addMultiple({
boolean: function(condition) {

View File

@@ -1,5 +1,5 @@
var Color = require("../tree/color"),
functionRegistry = require("./function-registry");
var Color = require('../tree/color'),
functionRegistry = require('./function-registry');
// Color Blending
// ref: http://www.w3.org/TR/compositing-1

View File

@@ -1,8 +1,8 @@
var Dimension = require("../tree/dimension"),
Color = require("../tree/color"),
Quoted = require("../tree/quoted"),
Anonymous = require("../tree/anonymous"),
functionRegistry = require("./function-registry"),
var Dimension = require('../tree/dimension'),
Color = require('../tree/color'),
Quoted = require('../tree/quoted'),
Anonymous = require('../tree/anonymous'),
functionRegistry = require('./function-registry'),
colorFunctions;
function clamp(val) {
@@ -18,8 +18,8 @@ function number(n) {
return n;
} else {
throw {
type: "Argument",
message: "color functions take numbers as parameters"
type: 'Argument',
message: 'color functions take numbers as parameters'
};
}
}
@@ -152,7 +152,7 @@ colorFunctions = {
}
var hsl = color.toHSL();
if (typeof method !== "undefined" && method.value === "relative") {
if (typeof method !== 'undefined' && method.value === 'relative') {
hsl.s += hsl.s * amount.value / 100;
}
else {
@@ -164,7 +164,7 @@ colorFunctions = {
desaturate: function (color, amount, method) {
var hsl = color.toHSL();
if (typeof method !== "undefined" && method.value === "relative") {
if (typeof method !== 'undefined' && method.value === 'relative') {
hsl.s -= hsl.s * amount.value / 100;
}
else {
@@ -176,7 +176,7 @@ colorFunctions = {
lighten: function (color, amount, method) {
var hsl = color.toHSL();
if (typeof method !== "undefined" && method.value === "relative") {
if (typeof method !== 'undefined' && method.value === 'relative') {
hsl.l += hsl.l * amount.value / 100;
}
else {
@@ -188,7 +188,7 @@ colorFunctions = {
darken: function (color, amount, method) {
var hsl = color.toHSL();
if (typeof method !== "undefined" && method.value === "relative") {
if (typeof method !== 'undefined' && method.value === 'relative') {
hsl.l -= hsl.l * amount.value / 100;
}
else {
@@ -200,7 +200,7 @@ colorFunctions = {
fadein: function (color, amount, method) {
var hsl = color.toHSL();
if (typeof method !== "undefined" && method.value === "relative") {
if (typeof method !== 'undefined' && method.value === 'relative') {
hsl.a += hsl.a * amount.value / 100;
}
else {
@@ -212,7 +212,7 @@ colorFunctions = {
fadeout: function (color, amount, method) {
var hsl = color.toHSL();
if (typeof method !== "undefined" && method.value === "relative") {
if (typeof method !== 'undefined' && method.value === 'relative') {
hsl.a -= hsl.a * amount.value / 100;
}
else {
@@ -346,8 +346,8 @@ colorFunctions = {
return c;
}
throw {
type: "Argument",
message: "argument must be a color keyword or 3/6 digit hex e.g. #FFF"
type: 'Argument',
message: 'argument must be a color keyword or 3/6 digit hex e.g. #FFF'
};
},
tint: function(color, amount) {

View File

@@ -1,14 +1,14 @@
module.exports = function(environment) {
var Quoted = require("../tree/quoted"),
URL = require("../tree/url"),
var Quoted = require('../tree/quoted'),
URL = require('../tree/url'),
utils = require('../utils'),
functionRegistry = require("./function-registry"),
functionRegistry = require('./function-registry'),
fallback = function(functionThis, node) {
return new URL(node, functionThis.index, functionThis.currentFileInfo).eval(functionThis.context);
},
logger = require('../logger');
functionRegistry.add("data-uri", function(mimetypeNode, filePathNode) {
functionRegistry.add('data-uri', function(mimetypeNode, filePathNode) {
if (!filePathNode) {
filePathNode = mimetypeNode;
@@ -43,7 +43,7 @@ module.exports = function(environment) {
mimetype = environment.mimeLookup(filePath);
if (mimetype === "image/svg+xml") {
if (mimetype === 'image/svg+xml') {
useBase64 = false;
} else {
// use base 64 unless it's an ASCII or UTF-8 format
@@ -58,7 +58,7 @@ module.exports = function(environment) {
var fileSync = fileManager.loadFileSync(filePath, currentDirectory, context, environment);
if (!fileSync.contents) {
logger.warn("Skipped data-uri embedding of " + filePath + " because file not found");
logger.warn('Skipped data-uri embedding of ' + filePath + ' because file not found');
return fallback(this, filePathNode || mimetypeNode);
}
var buf = fileSync.contents;
@@ -68,7 +68,7 @@ module.exports = function(environment) {
buf = useBase64 ? environment.encodeBase64(buf) : encodeURIComponent(buf);
var uri = "data:" + mimetype + ',' + buf + fragment;
var uri = 'data:' + mimetype + ',' + buf + fragment;
// IE8 cannot handle a data-uri larger than 32,768 characters. If this is exceeded
// and the --ieCompat flag is enabled, return a normal url() instead.
@@ -76,8 +76,8 @@ module.exports = function(environment) {
if (uri.length >= DATA_URI_MAX) {
if (this.context.ieCompat !== false) {
logger.warn("Skipped data-uri embedding of " + filePath + " because its size (" + uri.length +
" characters) exceeds IE8-safe " + DATA_URI_MAX + " characters!");
logger.warn('Skipped data-uri embedding of ' + filePath + ' because its size (' + uri.length +
' characters) exceeds IE8-safe ' + DATA_URI_MAX + ' characters!');
return fallback(this, filePathNode || mimetypeNode);
}

View File

@@ -1,5 +1,5 @@
var Keyword = require("../tree/keyword"),
functionRegistry = require("./function-registry");
var Keyword = require('../tree/keyword'),
functionRegistry = require('./function-registry');
var defaultFunc = {
eval: function () {
@@ -22,6 +22,6 @@ var defaultFunc = {
}
};
functionRegistry.add("default", defaultFunc.eval.bind(defaultFunc));
functionRegistry.add('default', defaultFunc.eval.bind(defaultFunc));
module.exports = defaultFunc;

View File

@@ -1,4 +1,4 @@
var Expression = require("../tree/expression");
var Expression = require('../tree/expression');
var functionCaller = function(name, context, index, currentFileInfo) {
this.name = name.toLowerCase();
@@ -17,15 +17,15 @@ functionCaller.prototype.call = function(args) {
// https://github.com/less/less.js/issues/2477
if (Array.isArray(args)) {
args = args.filter(function (item) {
if (item.type === "Comment") {
if (item.type === 'Comment') {
return false;
}
return true;
})
.map(function(item) {
if (item.type === "Expression") {
if (item.type === 'Expression') {
var subNodes = item.value.filter(function (item) {
if (item.type === "Comment") {
if (item.type === 'Comment') {
return false;
}
return true;

View File

@@ -1,20 +1,20 @@
module.exports = function(environment) {
var functions = {
functionRegistry: require("./function-registry"),
functionCaller: require("./function-caller")
functionRegistry: require('./function-registry'),
functionCaller: require('./function-caller')
};
// register functions
require("./boolean");
require("./default");
require("./color");
require("./color-blending");
require("./data-uri")(environment);
require("./math");
require("./number");
require("./string");
require("./svg")(environment);
require("./types");
require('./boolean');
require('./default');
require('./color');
require('./color-blending');
require('./data-uri')(environment);
require('./math');
require('./number');
require('./string');
require('./svg')(environment);
require('./types');
return functions;
};

View File

@@ -1,10 +1,10 @@
var Dimension = require("../tree/dimension");
var Dimension = require('../tree/dimension');
var MathHelper = function() {
};
MathHelper._math = function (fn, unit, n) {
if (!(n instanceof Dimension)) {
throw { type: "Argument", message: "argument must be a number" };
throw { type: 'Argument', message: 'argument must be a number' };
}
if (unit == null) {
unit = n.unit;

View File

@@ -1,5 +1,5 @@
var functionRegistry = require("./function-registry"),
mathHelper = require("./math-helper.js");
var functionRegistry = require('./function-registry'),
mathHelper = require('./math-helper.js');
var mathFunctions = {
// name, unit
@@ -7,12 +7,12 @@ var mathFunctions = {
floor: null,
sqrt: null,
abs: null,
tan: "",
sin: "",
cos: "",
atan: "rad",
asin: "rad",
acos: "rad"
tan: '',
sin: '',
cos: '',
atan: 'rad',
asin: 'rad',
acos: 'rad'
};
for (var f in mathFunctions) {
@@ -22,7 +22,7 @@ for (var f in mathFunctions) {
}
mathFunctions.round = function (n, f) {
var fraction = typeof f === "undefined" ? 0 : f.value;
var fraction = typeof f === 'undefined' ? 0 : f.value;
return mathHelper._math(function(num) { return num.toFixed(fraction); }, null, n);
};

View File

@@ -1,12 +1,12 @@
var Dimension = require("../tree/dimension"),
Anonymous = require("../tree/anonymous"),
functionRegistry = require("./function-registry"),
mathHelper = require("./math-helper.js");
var Dimension = require('../tree/dimension'),
Anonymous = require('../tree/anonymous'),
functionRegistry = require('./function-registry'),
mathHelper = require('./math-helper.js');
var minMax = function (isMin, args) {
args = Array.prototype.slice.call(args);
switch (args.length) {
case 0: throw { type: "Argument", message: "one or more arguments required" };
case 0: throw { type: 'Argument', message: 'one or more arguments required' };
}
var i, j, current, currentUnified, referenceUnified, unit, unitStatic, unitClone,
order = [], // elems only contains original argument values.
@@ -20,20 +20,20 @@ var minMax = function (isMin, args) {
}
continue;
}
currentUnified = current.unit.toString() === "" && unitClone !== undefined ? new Dimension(current.value, unitClone).unify() : current.unify();
unit = currentUnified.unit.toString() === "" && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString();
unitStatic = unit !== "" && unitStatic === undefined || unit !== "" && order[0].unify().unit.toString() === "" ? unit : unitStatic;
unitClone = unit !== "" && unitClone === undefined ? current.unit.toString() : unitClone;
j = values[""] !== undefined && unit !== "" && unit === unitStatic ? values[""] : values[unit];
currentUnified = current.unit.toString() === '' && unitClone !== undefined ? new Dimension(current.value, unitClone).unify() : current.unify();
unit = currentUnified.unit.toString() === '' && unitStatic !== undefined ? unitStatic : currentUnified.unit.toString();
unitStatic = unit !== '' && unitStatic === undefined || unit !== '' && order[0].unify().unit.toString() === '' ? unit : unitStatic;
unitClone = unit !== '' && unitClone === undefined ? current.unit.toString() : unitClone;
j = values[''] !== undefined && unit !== '' && unit === unitStatic ? values[''] : values[unit];
if (j === undefined) {
if (unitStatic !== undefined && unit !== unitStatic) {
throw { type: "Argument", message: "incompatible types" };
throw { type: 'Argument', message: 'incompatible types' };
}
values[unit] = order.length;
order.push(current);
continue;
}
referenceUnified = order[j].unit.toString() === "" && unitClone !== undefined ? new Dimension(order[j].value, unitClone).unify() : order[j].unify();
referenceUnified = order[j].unit.toString() === '' && unitClone !== undefined ? new Dimension(order[j].value, unitClone).unify() : order[j].unify();
if ( isMin && currentUnified.value < referenceUnified.value ||
!isMin && currentUnified.value > referenceUnified.value) {
order[j] = current;
@@ -42,8 +42,8 @@ var minMax = function (isMin, args) {
if (order.length == 1) {
return order[0];
}
args = order.map(function (a) { return a.toCSS(this.context); }).join(this.context.compress ? "," : ", ");
return new Anonymous((isMin ? "min" : "max") + "(" + args + ")");
args = order.map(function (a) { return a.toCSS(this.context); }).join(this.context.compress ? ',' : ', ');
return new Anonymous((isMin ? 'min' : 'max') + '(' + args + ')');
};
functionRegistry.addMultiple({
min: function () {
@@ -62,11 +62,11 @@ functionRegistry.addMultiple({
return new Dimension(a.value % b.value, a.unit);
},
pow: function(x, y) {
if (typeof x === "number" && typeof y === "number") {
if (typeof x === 'number' && typeof y === 'number') {
x = new Dimension(x);
y = new Dimension(y);
} else if (!(x instanceof Dimension) || !(y instanceof Dimension)) {
throw { type: "Argument", message: "arguments must be numbers" };
throw { type: 'Argument', message: 'arguments must be numbers' };
}
return new Dimension(Math.pow(x.value, y.value), x.unit);

View File

@@ -1,7 +1,7 @@
var Quoted = require("../tree/quoted"),
Anonymous = require("../tree/anonymous"),
JavaScript = require("../tree/javascript"),
functionRegistry = require("./function-registry");
var Quoted = require('../tree/quoted'),
Anonymous = require('../tree/anonymous'),
JavaScript = require('../tree/javascript'),
functionRegistry = require('./function-registry');
functionRegistry.addMultiple({
e: function (str) {
@@ -9,12 +9,12 @@ functionRegistry.addMultiple({
},
escape: function (str) {
return new Anonymous(
encodeURI(str.value).replace(/=/g, "%3D").replace(/:/g, "%3A").replace(/#/g, "%23").replace(/;/g, "%3B")
.replace(/\(/g, "%28").replace(/\)/g, "%29"));
encodeURI(str.value).replace(/=/g, '%3D').replace(/:/g, '%3A').replace(/#/g, '%23').replace(/;/g, '%3B')
.replace(/\(/g, '%28').replace(/\)/g, '%29'));
},
replace: function (string, pattern, replacement, flags) {
var result = string.value;
replacement = (replacement.type === "Quoted") ?
replacement = (replacement.type === 'Quoted') ?
replacement.value : replacement.toCSS();
result = result.replace(new RegExp(pattern.value, flags ? flags.value : ''), replacement);
return new Quoted(string.quote || '', result, string.escaped);
@@ -26,7 +26,7 @@ functionRegistry.addMultiple({
for (var i = 0; i < args.length; i++) {
/* jshint loopfunc:true */
result = result.replace(/%[sda]/i, function(token) {
var value = ((args[i].type === "Quoted") &&
var value = ((args[i].type === 'Quoted') &&
token.match(/s/i)) ? args[i].value : args[i].toCSS();
return token.match(/[A-Z]$/) ? encodeURIComponent(value) : value;
});

View File

@@ -1,16 +1,16 @@
module.exports = function(environment) {
var Dimension = require("../tree/dimension"),
Color = require("../tree/color"),
Expression = require("../tree/expression"),
Quoted = require("../tree/quoted"),
URL = require("../tree/url"),
functionRegistry = require("./function-registry");
var Dimension = require('../tree/dimension'),
Color = require('../tree/color'),
Expression = require('../tree/expression'),
Quoted = require('../tree/quoted'),
URL = require('../tree/url'),
functionRegistry = require('./function-registry');
functionRegistry.add("svg-gradient", function(direction) {
functionRegistry.add('svg-gradient', function(direction) {
var stops,
gradientDirectionSvg,
gradientType = "linear",
gradientType = 'linear',
rectangleDimension = 'x="0" y="0" width="1" height="1"',
renderEnv = {compress: false},
returner,
@@ -18,9 +18,9 @@ module.exports = function(environment) {
i, color, position, positionValue, alpha;
function throwArgumentDescriptor() {
throw { type: "Argument",
message: "svg-gradient expects direction, start_color [start_position], [color position,]...," +
" end_color [end_position] or direction, color list" };
throw { type: 'Argument',
message: 'svg-gradient expects direction, start_color [start_position], [color position,]...,' +
' end_color [end_position] or direction, color list' };
}
if (arguments.length == 2) {
@@ -35,27 +35,27 @@ module.exports = function(environment) {
}
switch (directionValue) {
case "to bottom":
case 'to bottom':
gradientDirectionSvg = 'x1="0%" y1="0%" x2="0%" y2="100%"';
break;
case "to right":
case 'to right':
gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="0%"';
break;
case "to bottom right":
case 'to bottom right':
gradientDirectionSvg = 'x1="0%" y1="0%" x2="100%" y2="100%"';
break;
case "to top right":
case 'to top right':
gradientDirectionSvg = 'x1="0%" y1="100%" x2="100%" y2="0%"';
break;
case "ellipse":
case "ellipse at center":
gradientType = "radial";
case 'ellipse':
case 'ellipse at center':
gradientType = 'radial';
gradientDirectionSvg = 'cx="50%" cy="50%" r="75%"';
rectangleDimension = 'x="-50" y="-50" width="101" height="101"';
break;
default:
throw { type: "Argument", message: "svg-gradient direction must be 'to bottom', 'to right'," +
" 'to bottom right', 'to top right' or 'ellipse at center'" };
throw { type: 'Argument', message: 'svg-gradient direction must be \'to bottom\', \'to right\',' +
' \'to bottom right\', \'to top right\' or \'ellipse at center\'' };
}
returner = '<?xml version="1.0" ?>' +
'<svg xmlns="http://www.w3.org/2000/svg" version="1.1" width="100%" height="100%" viewBox="0 0 1 1" preserveAspectRatio="none">' +
@@ -73,7 +73,7 @@ module.exports = function(environment) {
if (!(color instanceof Color) || (!((i === 0 || i + 1 === stops.length) && position === undefined) && !(position instanceof Dimension))) {
throwArgumentDescriptor();
}
positionValue = position ? position.toCSS(renderEnv) : i === 0 ? "0%" : "100%";
positionValue = position ? position.toCSS(renderEnv) : i === 0 ? '0%' : '100%';
alpha = color.alpha;
returner += '<stop offset="' + positionValue + '" stop-color="' + color.toRGB() + '"' + (alpha < 1 ? ' stop-opacity="' + alpha + '"' : '') + '/>';
}
@@ -82,7 +82,7 @@ module.exports = function(environment) {
returner = encodeURIComponent(returner);
returner = "data:image/svg+xml," + returner;
return new URL(new Quoted("'" + returner + "'", returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);
returner = 'data:image/svg+xml,' + returner;
return new URL(new Quoted('\'' + returner + '\'', returner, false, this.index, this.currentFileInfo), this.index, this.currentFileInfo);
});
};

View File

@@ -1,23 +1,23 @@
var Keyword = require("../tree/keyword"),
DetachedRuleset = require("../tree/detached-ruleset"),
Dimension = require("../tree/dimension"),
Color = require("../tree/color"),
Quoted = require("../tree/quoted"),
Anonymous = require("../tree/anonymous"),
URL = require("../tree/url"),
Operation = require("../tree/operation"),
functionRegistry = require("./function-registry");
var Keyword = require('../tree/keyword'),
DetachedRuleset = require('../tree/detached-ruleset'),
Dimension = require('../tree/dimension'),
Color = require('../tree/color'),
Quoted = require('../tree/quoted'),
Anonymous = require('../tree/anonymous'),
URL = require('../tree/url'),
Operation = require('../tree/operation'),
functionRegistry = require('./function-registry');
var isa = function (n, Type) {
return (n instanceof Type) ? Keyword.True : Keyword.False;
},
isunit = function (n, unit) {
if (unit === undefined) {
throw { type: "Argument", message: "missing the required second argument to isunit." };
throw { type: 'Argument', message: 'missing the required second argument to isunit.' };
}
unit = typeof unit.value === "string" ? unit.value : unit;
if (typeof unit !== "string") {
throw { type: "Argument", message: "Second argument to isunit should be a unit or a string." };
unit = typeof unit.value === 'string' ? unit.value : unit;
if (typeof unit !== 'string') {
throw { type: 'Argument', message: 'Second argument to isunit should be a unit or a string.' };
}
return (n instanceof Dimension) && n.unit.is(unit) ? Keyword.True : Keyword.False;
},
@@ -60,9 +60,9 @@ functionRegistry.addMultiple({
isunit: isunit,
unit: function (val, unit) {
if (!(val instanceof Dimension)) {
throw { type: "Argument",
message: "the first argument to unit must be a number" +
(val instanceof Operation ? ". Have you forgotten parenthesis?" : "") };
throw { type: 'Argument',
message: 'the first argument to unit must be a number' +
(val instanceof Operation ? '. Have you forgotten parenthesis?' : '') };
}
if (unit) {
if (unit instanceof Keyword) {
@@ -71,11 +71,11 @@ functionRegistry.addMultiple({
unit = unit.toCSS();
}
} else {
unit = "";
unit = '';
}
return new Dimension(val.value, unit);
},
"get-unit": function (n) {
'get-unit': function (n) {
return new Anonymous(n.unit);
},
extract: function(values, index) {
@@ -85,5 +85,8 @@ functionRegistry.addMultiple({
},
length: function(values) {
return new Dimension(getItemsFromNode(values).length);
},
_SELF: function(n) {
return n;
}
});

View File

@@ -1,4 +1,4 @@
var contexts = require("./contexts"),
var contexts = require('./contexts'),
Parser = require('./parser/parser'),
LessError = require('./less-error'),
utils = require('./utils'),
@@ -50,7 +50,7 @@ module.exports = function(environment) {
var importedEqualsRoot = fullPath === importManager.rootFilename;
if (importOptions.optional && e) {
callback(null, {rules:[]}, false, null);
logger.info("The file " + fullPath + " was skipped because it was not found and the import was marked optional.");
logger.info('The file ' + fullPath + ' was skipped because it was not found and the import was marked optional.');
}
else {
// Inline imports aren't cached here.
@@ -74,7 +74,7 @@ module.exports = function(environment) {
var fileManager = environment.getFileManager(path, currentFileInfo.currentDirectory, this.context, environment);
if (!fileManager) {
fileParsedFunc({ message: "Could not find a file-manager for " + path });
fileParsedFunc({ message: 'Could not find a file-manager for ' + path });
return;
}
@@ -94,7 +94,7 @@ module.exports = function(environment) {
newFileInfo.currentDirectory = fileManager.getPath(resolvedFilename);
if (newFileInfo.relativeUrls) {
newFileInfo.rootpath = fileManager.join(
(importManager.context.rootpath || ""),
(importManager.context.rootpath || ''),
fileManager.pathDiff(newFileInfo.currentDirectory, newFileInfo.entryPath));
if (!fileManager.isPathAbsolute(newFileInfo.rootpath) && fileManager.alwaysMakePathsAbsolute()) {
@@ -142,7 +142,7 @@ module.exports = function(environment) {
var promise, context = utils.clone(this.context);
if (tryAppendExtension) {
context.ext = importOptions.isPlugin ? ".js" : ".less";
context.ext = importOptions.isPlugin ? '.js' : '.less';
}
if (importOptions.isPlugin) {

View File

@@ -2,23 +2,23 @@ module.exports = function(environment, fileManagers) {
var SourceMapOutput, SourceMapBuilder, ParseTree, ImportManager, Environment;
var initial = {
version: [3, 0, 4],
version: [3, 5, 3],
data: require('./data'),
tree: require('./tree'),
Environment: (Environment = require("./environment/environment")),
AbstractFileManager: require("./environment/abstract-file-manager"),
AbstractPluginLoader: require("./environment/abstract-plugin-loader"),
Environment: (Environment = require('./environment/environment')),
AbstractFileManager: require('./environment/abstract-file-manager'),
AbstractPluginLoader: require('./environment/abstract-plugin-loader'),
environment: (environment = new Environment(environment, fileManagers)),
visitors: require('./visitors'),
Parser: require('./parser/parser'),
functions: require('./functions')(environment),
contexts: require("./contexts"),
contexts: require('./contexts'),
SourceMapOutput: (SourceMapOutput = require('./source-map-output')(environment)),
SourceMapBuilder: (SourceMapBuilder = require('./source-map-builder')(SourceMapOutput, environment)),
ParseTree: (ParseTree = require('./parse-tree')(SourceMapBuilder)),
ImportManager: (ImportManager = require('./import-manager')(environment)),
render: require("./render")(environment, ParseTree, ImportManager),
parse: require("./parse")(environment, ParseTree, ImportManager),
render: require('./render')(environment, ParseTree, ImportManager),
parse: require('./parse')(environment, ParseTree, ImportManager),
LessError: require('./less-error'),
transformTree: require('./transform-tree'),
utils: require('./utils'),
@@ -39,7 +39,7 @@ module.exports = function(environment, fileManagers) {
for (var n in initial.tree) {
/* eslint guard-for-in: 0 */
t = initial.tree[n];
if (typeof t === "function") {
if (typeof t === 'function') {
api[n.toLowerCase()] = ctor(t);
}
else {

View File

@@ -1,15 +1,15 @@
module.exports = {
error: function(msg) {
this._fireEvent("error", msg);
this._fireEvent('error', msg);
},
warn: function(msg) {
this._fireEvent("warn", msg);
this._fireEvent('warn', msg);
},
info: function(msg) {
this._fireEvent("info", msg);
this._fireEvent('info', msg);
},
debug: function(msg) {
this._fireEvent("debug", msg);
this._fireEvent('debug', msg);
},
addListener: function(listener) {
this._listeners.push(listener);

View File

@@ -1,6 +1,6 @@
var LessError = require('./less-error'),
transformTree = require("./transform-tree"),
logger = require("./logger");
transformTree = require('./transform-tree'),
logger = require('./logger');
module.exports = function(SourceMapBuilder) {
var ParseTree = function(root, imports) {
@@ -19,7 +19,7 @@ module.exports = function(SourceMapBuilder) {
try {
var compress = Boolean(options.compress);
if (compress) {
logger.warn("The compress option has been deprecated. We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.");
logger.warn('The compress option has been deprecated. We recommend you use a dedicated css minifier, for instance see less-plugin-clean-css.');
}
var toCSSOptions = {

View File

@@ -1,5 +1,5 @@
var PromiseConstructor,
contexts = require("./contexts"),
contexts = require('./contexts'),
Parser = require('./parser/parser'),
PluginManager = require('./plugin-manager'),
LessError = require('./less-error'),
@@ -42,19 +42,19 @@ module.exports = function(environment, ParseTree, ImportManager) {
if (options.rootFileInfo) {
rootFileInfo = options.rootFileInfo;
} else {
var filename = options.filename || "input";
var entryPath = filename.replace(/[^\/\\]*$/, "");
var filename = options.filename || 'input';
var entryPath = filename.replace(/[^\/\\]*$/, '');
rootFileInfo = {
filename: filename,
relativeUrls: context.relativeUrls,
rootpath: context.rootpath || "",
rootpath: context.rootpath || '',
currentDirectory: entryPath,
entryPath: entryPath,
rootFilename: filename
};
// add in a missing trailing slash
if (rootFileInfo.rootpath && rootFileInfo.rootpath.slice(-1) !== "/") {
rootFileInfo.rootpath += "/";
if (rootFileInfo.rootpath && rootFileInfo.rootpath.slice(-1) !== '/') {
rootFileInfo.rootpath += '/';
}
}

View File

@@ -28,7 +28,7 @@ module.exports = function (input, fail) {
continue;
case 41: // )
if (--parenLevel < 0) {
return fail("missing opening `(`", chunkerCurrentIndex);
return fail('missing opening `(`', chunkerCurrentIndex);
}
continue;
case 59: // ;
@@ -40,13 +40,13 @@ module.exports = function (input, fail) {
continue;
case 125: // }
if (--level < 0) {
return fail("missing opening `{`", chunkerCurrentIndex);
return fail('missing opening `{`', chunkerCurrentIndex);
}
if (!level && !parenLevel) { emitChunk(); }
continue;
case 92: // \
if (chunkerCurrentIndex < len - 1) { chunkerCurrentIndex++; continue; }
return fail("unescaped `\\`", chunkerCurrentIndex);
return fail('unescaped `\\`', chunkerCurrentIndex);
case 34:
case 39:
case 96: // ", ' and `
@@ -58,13 +58,13 @@ module.exports = function (input, fail) {
if (cc2 == cc) { matched = 1; break; }
if (cc2 == 92) { // \
if (chunkerCurrentIndex == len - 1) {
return fail("unescaped `\\`", chunkerCurrentIndex);
return fail('unescaped `\\`', chunkerCurrentIndex);
}
chunkerCurrentIndex++;
}
}
if (matched) { continue; }
return fail("unmatched `" + String.fromCharCode(cc) + "`", currentChunkStartIndex);
return fail('unmatched `' + String.fromCharCode(cc) + '`', currentChunkStartIndex);
case 47: // /, check for comment
if (parenLevel || (chunkerCurrentIndex == len - 1)) { continue; }
cc2 = input.charCodeAt(chunkerCurrentIndex + 1);
@@ -84,14 +84,14 @@ module.exports = function (input, fail) {
if (input.charCodeAt(chunkerCurrentIndex + 1) == 47) { break; }
}
if (chunkerCurrentIndex == len - 1) {
return fail("missing closing `*/`", currentChunkStartIndex);
return fail('missing closing `*/`', currentChunkStartIndex);
}
chunkerCurrentIndex++;
}
continue;
case 42: // *, check for unmatched */
if ((chunkerCurrentIndex < len - 1) && (input.charCodeAt(chunkerCurrentIndex + 1) == 47)) {
return fail("unmatched `/*`", chunkerCurrentIndex);
return fail('unmatched `/*`', chunkerCurrentIndex);
}
continue;
}
@@ -99,12 +99,12 @@ module.exports = function (input, fail) {
if (level !== 0) {
if ((lastMultiComment > lastOpening) && (lastMultiCommentEndBrace > lastMultiComment)) {
return fail("missing closing `}` or `*/`", lastOpening);
return fail('missing closing `}` or `*/`', lastOpening);
} else {
return fail("missing closing `}`", lastOpening);
return fail('missing closing `}`', lastOpening);
}
} else if (parenLevel !== 0) {
return fail("missing closing `)`", lastOpeningParen);
return fail('missing closing `)`', lastOpeningParen);
}
emitChunk(true);

View File

@@ -35,7 +35,7 @@ module.exports = function() {
nextChar = inp.charAt(parserInput.i + 1);
if (nextChar === '/') {
comment = {index: parserInput.i, isLineComment: true};
var nextNewLine = inp.indexOf("\n", parserInput.i + 2);
var nextNewLine = inp.indexOf('\n', parserInput.i + 2);
if (nextNewLine < 0) {
nextNewLine = endIndex;
}
@@ -44,7 +44,7 @@ module.exports = function() {
parserInput.commentStore.push(comment);
continue;
} else if (nextChar === '*') {
var nextStarSlash = inp.indexOf("*/", parserInput.i + 2);
var nextStarSlash = inp.indexOf('*/', parserInput.i + 2);
if (nextStarSlash >= 0) {
comment = {
index: parserInput.i,
@@ -116,7 +116,7 @@ module.exports = function() {
}
skipWhitespace(m[0].length);
if (typeof m === "string") {
if (typeof m === 'string') {
return m;
}
@@ -149,7 +149,7 @@ module.exports = function() {
var pos = loc || parserInput.i,
startChar = input.charAt(pos);
if (startChar !== "'" && startChar !== '"') {
if (startChar !== '\'' && startChar !== '"') {
return;
}
var length = input.length,
@@ -158,11 +158,11 @@ module.exports = function() {
for (var i = 1; i + currentPosition < length; i++) {
var nextChar = input.charAt(i + currentPosition);
switch (nextChar) {
case "\\":
case '\\':
i++;
continue;
case "\r":
case "\n":
case '\r':
case '\n':
break;
case startChar:
var str = input.substr(currentPosition, i + 1);
@@ -211,17 +211,17 @@ module.exports = function() {
returnVal = input.substr(lastPos, i - lastPos);
if (returnVal) {
parseGroups.push(returnVal);
returnVal = parseGroups;
}
else {
returnVal = [' '];
parseGroups.push(' ');
}
returnVal = parseGroups;
skipWhitespace(i - startPos);
loop = false
} else {
if (inComment) {
if (nextChar === "*" &&
input.charAt(i + 1) === "/") {
if (nextChar === '*' &&
input.charAt(i + 1) === '/') {
i++;
blockDepth--;
inComment = false;
@@ -236,15 +236,14 @@ module.exports = function() {
parseGroups.push(input.substr(lastPos, i - lastPos + 1));
lastPos = i + 1;
break;
case "/":
if (input.charAt(i + 1) === "*") {
case '/':
if (input.charAt(i + 1) === '*') {
i++;
console.log(input.substr(lastPos, i - lastPos));
inComment = true;
blockDepth++;
}
break;
case "'":
case '\'':
case '"':
quote = parserInput.$quoted(i);
if (quote) {
@@ -258,21 +257,21 @@ module.exports = function() {
loop = false;
}
break;
case "{":
blockStack.push("}");
case '{':
blockStack.push('}');
blockDepth++;
break;
case "(":
blockStack.push(")");
case '(':
blockStack.push(')');
blockDepth++;
break;
case "[":
blockStack.push("]");
case '[':
blockStack.push(']');
blockDepth++;
break;
case "}":
case ")":
case "]":
case '}':
case ')':
case ']':
var expected = blockStack.pop();
if (nextChar === expected) {
blockDepth--;
@@ -324,6 +323,10 @@ module.exports = function() {
return input.charAt(parserInput.i);
};
parserInput.prevChar = function() {
return input.charAt(parserInput.i - 1);
};
parserInput.getInput = function() {
return input;
};

File diff suppressed because it is too large Load Diff

View File

@@ -37,15 +37,15 @@ module.exports = function (SourceMapOutput, environment) {
var sourceMapURL = this.sourceMapURL;
if (this.options.sourceMapFileInline) {
if (this.sourceMap === undefined) {
return "";
return '';
}
sourceMapURL = "data:application/json;base64," + environment.encodeBase64(this.sourceMap);
sourceMapURL = 'data:application/json;base64,' + environment.encodeBase64(this.sourceMap);
}
if (sourceMapURL) {
return "/*# sourceMappingURL=" + sourceMapURL + " */";
return '/*# sourceMappingURL=' + sourceMapURL + ' */';
}
return "";
return '';
};
SourceMapBuilder.prototype.getExternalSourceMap = function() {

View File

@@ -19,7 +19,7 @@ module.exports = function (environment) {
this._sourceMapRootpath += '/';
}
} else {
this._sourceMapRootpath = "";
this._sourceMapRootpath = '';
}
this._outputSourceFiles = options.outputSourceFiles;
this._sourceMapGeneratorConstructor = environment.getSourceMapGenerator();
@@ -42,7 +42,7 @@ module.exports = function (environment) {
SourceMapOutput.prototype.normalizeFilename = function(filename) {
filename = filename.replace(/\\/g, '/');
filename = this.removeBasepath(filename);
return (this._sourceMapRootpath || "") + filename;
return (this._sourceMapRootpath || '') + filename;
};
SourceMapOutput.prototype.add = function(chunk, fileInfo, index, mapLines) {
@@ -70,11 +70,11 @@ module.exports = function (environment) {
inputSource = inputSource.slice(this._contentsIgnoredCharsMap[fileInfo.filename]);
}
inputSource = inputSource.substring(0, index);
sourceLines = inputSource.split("\n");
sourceLines = inputSource.split('\n');
sourceColumns = sourceLines[sourceLines.length - 1];
}
lines = chunk.split("\n");
lines = chunk.split('\n');
columns = lines[lines.length - 1];
if (fileInfo) {

View File

@@ -1,6 +1,6 @@
var contexts = require("./contexts"),
visitor = require("./visitors"),
tree = require("./tree");
var contexts = require('./contexts'),
visitor = require('./visitors'),
tree = require('./tree');
module.exports = function(root, options) {
options = options || {};
@@ -41,29 +41,49 @@ module.exports = function(root, options) {
new visitor.MarkVisibleSelectorsVisitor(true),
new visitor.ExtendVisitor(),
new visitor.ToCSSVisitor({compress: Boolean(options.compress)})
], v, visitorIterator;
], preEvalVisitors = [], v, visitorIterator;
// first() / get() allows visitors to be added while visiting
/**
* first() / get() allows visitors to be added while visiting
*
* @todo Add scoping for visitors just like functions for @plugin; right now they're global
*/
if (options.pluginManager) {
visitorIterator = options.pluginManager.visitor();
visitorIterator.first();
while ((v = visitorIterator.get())) {
if (v.isPreEvalVisitor) {
v.run(root);
for (var i = 0; i < 2; i++) {
visitorIterator.first();
while ((v = visitorIterator.get())) {
if (v.isPreEvalVisitor) {
if (i === 0 || preEvalVisitors.indexOf(v) === -1) {
preEvalVisitors.push(v);
v.run(root);
}
}
else {
if (i === 0 || visitors.indexOf(v) === -1) {
if (v.isPreVisitor) {
visitors.unshift(v);
}
else {
visitors.push(v);
}
}
}
}
}
}
evaldRoot = root.eval(evalEnv);
for (var i = 0; i < visitors.length; i++) {
visitors[i].run(evaldRoot);
}
// Run any remaining visitors added after eval pass
if (options.pluginManager) {
visitorIterator.first();
while ((v = visitorIterator.get())) {
if (!v.isPreEvalVisitor) {
if (visitors.indexOf(v) === -1 && preEvalVisitors.indexOf(v) === -1) {
v.run(evaldRoot);
}
}

View File

@@ -1,4 +1,4 @@
var Node = require("./node");
var Node = require('./node');
var Anonymous = function (value, index, currentFileInfo, mapLines, rulesetLike, visibilityInfo) {
this.value = value;
@@ -10,7 +10,7 @@ var Anonymous = function (value, index, currentFileInfo, mapLines, rulesetLike,
this.copyVisibilityInfo(visibilityInfo);
};
Anonymous.prototype = new Node();
Anonymous.prototype.type = "Anonymous";
Anonymous.prototype.type = 'Anonymous';
Anonymous.prototype.eval = function () {
return new Anonymous(this.value, this._index, this._fileInfo, this.mapLines, this.rulesetLike, this.visibilityInfo());
};

View File

@@ -1,4 +1,4 @@
var Node = require("./node");
var Node = require('./node');
var Assignment = function (key, val) {
this.key = key;
@@ -6,7 +6,7 @@ var Assignment = function (key, val) {
};
Assignment.prototype = new Node();
Assignment.prototype.type = "Assignment";
Assignment.prototype.type = 'Assignment';
Assignment.prototype.accept = function (visitor) {
this.value = visitor.visit(this.value);
};

View File

@@ -1,6 +1,6 @@
var Node = require("./node"),
Selector = require("./selector"),
Ruleset = require("./ruleset"),
var Node = require('./node'),
Selector = require('./selector'),
Ruleset = require('./ruleset'),
Anonymous = require('./anonymous');
var AtRule = function (name, value, rules, index, currentFileInfo, debugInfo, isRooted, visibilityInfo) {
@@ -29,7 +29,7 @@ var AtRule = function (name, value, rules, index, currentFileInfo, debugInfo, is
};
AtRule.prototype = new Node();
AtRule.prototype.type = "AtRule";
AtRule.prototype.type = 'AtRule';
AtRule.prototype.accept = function (visitor) {
var value = this.value, rules = this.rules;
if (rules) {
@@ -43,7 +43,7 @@ AtRule.prototype.isRulesetLike = function() {
return this.rules || !this.isCharset();
};
AtRule.prototype.isCharset = function() {
return "@charset" === this.name;
return '@charset' === this.name;
};
AtRule.prototype.genCSS = function (context, output) {
var value = this.value, rules = this.rules;
@@ -118,11 +118,11 @@ AtRule.prototype.outputRuleset = function (context, output, rules) {
}
// Non-compressed
var tabSetStr = '\n' + Array(context.tabLevel).join(" "), tabRuleStr = tabSetStr + " ";
var tabSetStr = '\n' + Array(context.tabLevel).join(' '), tabRuleStr = tabSetStr + ' ';
if (!ruleCnt) {
output.add(" {" + tabSetStr + '}');
output.add(' {' + tabSetStr + '}');
} else {
output.add(" {" + tabRuleStr);
output.add(' {' + tabRuleStr);
rules[0].genCSS(context, output);
for (i = 1; i < ruleCnt; i++) {
output.add(tabRuleStr);

View File

@@ -1,4 +1,4 @@
var Node = require("./node");
var Node = require('./node');
var Attribute = function (key, op, value) {
this.key = key;
@@ -6,7 +6,7 @@ var Attribute = function (key, op, value) {
this.value = value;
};
Attribute.prototype = new Node();
Attribute.prototype.type = "Attribute";
Attribute.prototype.type = 'Attribute';
Attribute.prototype.eval = function (context) {
return new Attribute(this.key.eval ? this.key.eval(context) : this.key,
this.op, (this.value && this.value.eval) ? this.value.eval(context) : this.value);

View File

@@ -1,18 +1,18 @@
var Node = require("./node"),
Anonymous = require("./anonymous"),
FunctionCaller = require("../functions/function-caller");
var Node = require('./node'),
Anonymous = require('./anonymous'),
FunctionCaller = require('../functions/function-caller');
//
// A function call node.
//
var Call = function (name, args, index, currentFileInfo) {
this.name = name;
this.args = args;
this.mathOn = name === 'calc' ? false : true;
this.calc = name === 'calc';
this._index = index;
this._fileInfo = currentFileInfo;
};
Call.prototype = new Node();
Call.prototype.type = "Call";
Call.prototype.type = 'Call';
Call.prototype.accept = function (visitor) {
if (this.args) {
this.args = visitor.visitArray(this.args);
@@ -30,13 +30,18 @@ Call.prototype.accept = function (visitor) {
// The function should receive the value, not the variable.
//
Call.prototype.eval = function (context) {
/**
* Turn off math for calc(), and switch back on for evaluating nested functions
*/
var currentMathContext = context.mathOn;
context.mathOn = this.mathOn;
context.mathOn = !this.calc;
if (this.calc || context.inCalc) {
context.enterCalc();
}
var args = this.args.map(function (a) { return a.eval(context); });
if (this.calc || context.inCalc) {
context.exitCalc();
}
context.mathOn = currentMathContext;
var result, funcCaller = new FunctionCaller(this.name, context, this.getIndex(), this.fileInfo());
@@ -46,8 +51,8 @@ Call.prototype.eval = function (context) {
result = funcCaller.call(args);
} catch (e) {
throw {
type: e.type || "Runtime",
message: "error evaluating function `" + this.name + "`" +
type: e.type || 'Runtime',
message: 'error evaluating function `' + this.name + '`' +
(e.message ? ': ' + e.message : ''),
index: this.getIndex(),
filename: this.fileInfo().filename,
@@ -78,15 +83,15 @@ Call.prototype.eval = function (context) {
return new Call(this.name, args, this.getIndex(), this.fileInfo());
};
Call.prototype.genCSS = function (context, output) {
output.add(this.name + "(", this.fileInfo(), this.getIndex());
output.add(this.name + '(', this.fileInfo(), this.getIndex());
for (var i = 0; i < this.args.length; i++) {
this.args[i].genCSS(context, output);
if (i + 1 < this.args.length) {
output.add(", ");
output.add(', ');
}
}
output.add(")");
output.add(')');
};
module.exports = Call;

View File

@@ -1,5 +1,5 @@
var Node = require("./node"),
colors = require("../data/colors");
var Node = require('./node'),
colors = require('../data/colors');
//
// RGB Colors - #ff0014, #eee
@@ -29,7 +29,7 @@ var Color = function (rgb, a, originalForm) {
};
Color.prototype = new Node();
Color.prototype.type = "Color";
Color.prototype.type = 'Color';
function clamp(v, max) {
return Math.min(Math.max(v, 0), max);
@@ -72,10 +72,10 @@ Color.prototype.toCSS = function (context, doNotCompress) {
// Values are capped between `0` and `255`, rounded and zero-padded.
alpha = this.fround(context, this.alpha);
if (alpha < 1) {
return "rgba(" + this.rgb.map(function (c) {
return 'rgba(' + this.rgb.map(function (c) {
return clamp(Math.round(c), 255);
}).concat(clamp(alpha, 1))
.join(',' + (compress ? '' : ' ')) + ")";
.join(',' + (compress ? '' : ' ')) + ')';
}
color = this.toRGB();
@@ -177,7 +177,7 @@ Color.fromKeyword = function(keyword) {
if (colors.hasOwnProperty(key)) {
c = new Color(colors[key].slice(1));
}
else if (key === "transparent") {
else if (key === 'transparent') {
c = new Color([0, 0, 0], 0);
}

View File

@@ -1,16 +1,16 @@
var Node = require("./node");
var Node = require('./node');
var Combinator = function (value) {
if (value === ' ') {
this.value = ' ';
this.emptyOrWhitespace = true;
} else {
this.value = value ? value.trim() : "";
this.emptyOrWhitespace = this.value === "";
this.value = value ? value.trim() : '';
this.emptyOrWhitespace = this.value === '';
}
};
Combinator.prototype = new Node();
Combinator.prototype.type = "Combinator";
Combinator.prototype.type = 'Combinator';
var _noSpaceCombinators = {
'': true,
' ': true,

View File

@@ -1,5 +1,5 @@
var Node = require("./node"),
getDebugInfo = require("./debug-info");
var Node = require('./node'),
getDebugInfo = require('./debug-info');
var Comment = function (value, isLineComment, index, currentFileInfo) {
this.value = value;
@@ -9,7 +9,7 @@ var Comment = function (value, isLineComment, index, currentFileInfo) {
this.allowRoot = true;
};
Comment.prototype = new Node();
Comment.prototype.type = "Comment";
Comment.prototype.type = 'Comment';
Comment.prototype.genCSS = function (context, output) {
if (this.debugInfo) {
output.add(getDebugInfo(context, this), this.fileInfo(), this.getIndex());
@@ -17,7 +17,7 @@ Comment.prototype.genCSS = function (context, output) {
output.add(this.value);
};
Comment.prototype.isSilent = function(context) {
var isCompressed = context.compress && this.value[2] !== "!";
var isCompressed = context.compress && this.value[2] !== '!';
return this.isLineComment || isCompressed;
};
module.exports = Comment;

View File

@@ -1,4 +1,4 @@
var Node = require("./node");
var Node = require('./node');
var Condition = function (op, l, r, i, negate) {
this.op = op.trim();
@@ -8,7 +8,7 @@ var Condition = function (op, l, r, i, negate) {
this.negate = negate;
};
Condition.prototype = new Node();
Condition.prototype.type = "Condition";
Condition.prototype.type = 'Condition';
Condition.prototype.accept = function (visitor) {
this.lvalue = visitor.visit(this.lvalue);
this.rvalue = visitor.visit(this.rvalue);

View File

@@ -1,5 +1,5 @@
var debugInfo = function(context, ctx, lineSeparator) {
var result = "";
var result = '';
if (context.dumpLineNumbers && !context.compress) {
switch (context.dumpLineNumbers) {
case 'comments':
@@ -9,7 +9,7 @@ var debugInfo = function(context, ctx, lineSeparator) {
result = debugInfo.asMediaQuery(ctx);
break;
case 'all':
result = debugInfo.asComment(ctx) + (lineSeparator || "") + debugInfo.asMediaQuery(ctx);
result = debugInfo.asComment(ctx) + (lineSeparator || '') + debugInfo.asMediaQuery(ctx);
break;
}
}

View File

@@ -1,7 +1,7 @@
var Node = require("./node"),
Value = require("./value"),
Keyword = require("./keyword"),
Anonymous = require("./anonymous");
var Node = require('./node'),
Value = require('./value'),
Keyword = require('./keyword'),
Anonymous = require('./anonymous');
var Declaration = function (name, value, important, merge, index, currentFileInfo, inline, variable) {
this.name = name;
@@ -18,7 +18,7 @@ var Declaration = function (name, value, important, merge, index, currentFileInf
};
function evalName(context, name) {
var value = "", i, n = name.length,
var value = '', i, n = name.length,
output = {add: function (s) {value += s;}};
for (i = 0; i < n; i++) {
name[i].eval(context).genCSS(context, output);
@@ -27,7 +27,7 @@ function evalName(context, name) {
}
Declaration.prototype = new Node();
Declaration.prototype.type = "Declaration";
Declaration.prototype.type = 'Declaration';
Declaration.prototype.genCSS = function (context, output) {
output.add(this.name + (context.compress ? ':' : ': '), this.fileInfo(), this.getIndex());
try {
@@ -38,18 +38,18 @@ Declaration.prototype.genCSS = function (context, output) {
e.filename = this._fileInfo.filename;
throw e;
}
output.add(this.important + ((this.inline || (context.lastRule && context.compress)) ? "" : ";"), this._fileInfo, this._index);
output.add(this.important + ((this.inline || (context.lastRule && context.compress)) ? '' : ';'), this._fileInfo, this._index);
};
Declaration.prototype.eval = function (context) {
var strictMathBypass = false, prevMath, name = this.name, evaldValue, variable = this.variable;
if (typeof name !== "string") {
if (typeof name !== 'string') {
// expand 'primitive' name directly to get
// things faster (~10% for benchmark.less):
name = (name.length === 1) && (name[0] instanceof Keyword) ?
name[0].value : evalName(context, name);
variable = false; // never treat expanded interpolation as new variable name
}
if (name === "font" && !context.strictMath) {
if (name === 'font' && !context.strictMath) {
strictMathBypass = true;
prevMath = context.strictMath;
context.strictMath = 'division';
@@ -58,8 +58,8 @@ Declaration.prototype.eval = function (context) {
context.importantScope.push({});
evaldValue = this.value.eval(context);
if (!this.variable && evaldValue.type === "DetachedRuleset") {
throw { message: "Rulesets cannot be evaluated on a property.",
if (!this.variable && evaldValue.type === 'DetachedRuleset') {
throw { message: 'Rulesets cannot be evaluated on a property.',
index: this.getIndex(), filename: this.fileInfo().filename };
}
var important = this.important,
@@ -91,7 +91,7 @@ Declaration.prototype.eval = function (context) {
Declaration.prototype.makeImportant = function () {
return new Declaration(this.name,
this.value,
"!important",
'!important',
this.merge,
this.getIndex(), this.fileInfo(), this.inline);
};

View File

@@ -1,6 +1,6 @@
var Node = require("./node"),
contexts = require("../contexts"),
utils = require("../utils");
var Node = require('./node'),
contexts = require('../contexts'),
utils = require('../utils');
var DetachedRuleset = function (ruleset, frames) {
this.ruleset = ruleset;
@@ -8,7 +8,7 @@ var DetachedRuleset = function (ruleset, frames) {
this.setParent(this.ruleset, this);
};
DetachedRuleset.prototype = new Node();
DetachedRuleset.prototype.type = "DetachedRuleset";
DetachedRuleset.prototype.type = 'DetachedRuleset';
DetachedRuleset.prototype.evalFirst = true;
DetachedRuleset.prototype.accept = function (visitor) {
this.ruleset = visitor.visit(this.ruleset);

View File

@@ -1,7 +1,7 @@
var Node = require("./node"),
unitConversions = require("../data/unit-conversions"),
Unit = require("./unit"),
Color = require("./color");
var Node = require('./node'),
unitConversions = require('../data/unit-conversions'),
Unit = require('./unit'),
Color = require('./color');
//
// A number with a unit
@@ -9,7 +9,7 @@ var Node = require("./node"),
var Dimension = function (value, unit) {
this.value = parseFloat(value);
if (isNaN(this.value)) {
throw new Error("Dimension is not a number.");
throw new Error('Dimension is not a number.');
}
this.unit = (unit && unit instanceof Unit) ? unit :
new Unit(unit ? [unit] : undefined);
@@ -17,7 +17,7 @@ var Dimension = function (value, unit) {
};
Dimension.prototype = new Node();
Dimension.prototype.type = "Dimension";
Dimension.prototype.type = 'Dimension';
Dimension.prototype.accept = function (visitor) {
this.unit = visitor.visit(this.unit);
};
@@ -29,7 +29,7 @@ Dimension.prototype.toColor = function () {
};
Dimension.prototype.genCSS = function (context, output) {
if ((context && context.strictUnits) && !this.unit.isSingular()) {
throw new Error("Multiple units in dimension. Correct the units or use the unit function. Bad unit: " + this.unit.toString());
throw new Error('Multiple units in dimension. Correct the units or use the unit function. Bad unit: ' + this.unit.toString());
}
var value = this.fround(context, this.value),
@@ -37,7 +37,7 @@ Dimension.prototype.genCSS = function (context, output) {
if (value !== 0 && value < 0.000001 && value > -0.000001) {
// would be output 1e-6 etc.
strValue = value.toFixed(20).replace(/0+$/, "");
strValue = value.toFixed(20).replace(/0+$/, '');
}
if (context && context.compress) {
@@ -77,8 +77,8 @@ Dimension.prototype.operate = function (context, op, other) {
other = other.convertTo(this.unit.usedUnits());
if (context.strictUnits && other.unit.toString() !== unit.toString()) {
throw new Error("Incompatible units. Change the units or use the unit function. Bad units: '" + unit.toString() +
"' and '" + other.unit.toString() + "'.");
throw new Error('Incompatible units. Change the units or use the unit function. Bad units: \'' + unit.toString() +
'\' and \'' + other.unit.toString() + '\'.');
}
value = this._operate(context, op, this.value, other.value);

View File

@@ -1,8 +1,8 @@
var Node = require("./node"),
Paren = require("./paren"),
Combinator = require("./combinator");
var Node = require('./node'),
Paren = require('./paren'),
Combinator = require('./combinator');
var Element = function (combinator, value, index, currentFileInfo, visibilityInfo) {
var Element = function (combinator, value, isVariable, index, currentFileInfo, visibilityInfo) {
this.combinator = combinator instanceof Combinator ?
combinator : new Combinator(combinator);
@@ -11,31 +11,34 @@ var Element = function (combinator, value, index, currentFileInfo, visibilityInf
} else if (value) {
this.value = value;
} else {
this.value = "";
this.value = '';
}
this.isVariable = isVariable;
this._index = index;
this._fileInfo = currentFileInfo;
this.copyVisibilityInfo(visibilityInfo);
this.setParent(this.combinator, this);
};
Element.prototype = new Node();
Element.prototype.type = "Element";
Element.prototype.type = 'Element';
Element.prototype.accept = function (visitor) {
var value = this.value;
this.combinator = visitor.visit(this.combinator);
if (typeof value === "object") {
if (typeof value === 'object') {
this.value = visitor.visit(value);
}
};
Element.prototype.eval = function (context) {
return new Element(this.combinator,
this.value.eval ? this.value.eval(context) : this.value,
this.isVariable,
this.getIndex(),
this.fileInfo(), this.visibilityInfo());
};
Element.prototype.clone = function () {
return new Element(this.combinator,
this.value,
this.isVariable,
this.getIndex(),
this.fileInfo(), this.visibilityInfo());
};

View File

@@ -1,21 +1,22 @@
var Node = require("./node"),
Paren = require("./paren"),
Comment = require("./comment");
var Node = require('./node'),
Paren = require('./paren'),
Comment = require('./comment');
var Expression = function (value, noSpacing) {
this.value = value;
this.noSpacing = noSpacing;
if (!value) {
throw new Error("Expression requires an array parameter");
throw new Error('Expression requires an array parameter');
}
};
Expression.prototype = new Node();
Expression.prototype.type = "Expression";
Expression.prototype.type = 'Expression';
Expression.prototype.accept = function (visitor) {
this.value = visitor.visitArray(this.value);
};
Expression.prototype.eval = function (context) {
var returnValue,
mathOn = context.isMathOn(),
inParenthesis = this.parens && !this.parensInOp,
doubleParen = false;
if (inParenthesis) {
@@ -23,10 +24,13 @@ Expression.prototype.eval = function (context) {
}
if (this.value.length > 1) {
returnValue = new Expression(this.value.map(function (e) {
if (!e.eval) {
return e;
}
return e.eval(context);
}), this.noSpacing);
} else if (this.value.length === 1) {
if (this.value[0].parens && !this.value[0].parensInOp) {
if (this.value[0].parens && !this.value[0].parensInOp && !context.inCalc) {
doubleParen = true;
}
returnValue = this.value[0].eval(context);
@@ -36,7 +40,7 @@ Expression.prototype.eval = function (context) {
if (inParenthesis) {
context.outOfParenthesis();
}
if (this.parens && this.parensInOp && !(context.isMathOn()) && !doubleParen) {
if (this.parens && this.parensInOp && !mathOn && !doubleParen) {
returnValue = new Paren(returnValue);
}
return returnValue;
@@ -45,7 +49,7 @@ Expression.prototype.genCSS = function (context, output) {
for (var i = 0; i < this.value.length; i++) {
this.value[i].genCSS(context, output);
if (!this.noSpacing && i + 1 < this.value.length) {
output.add(" ");
output.add(' ');
}
}
};

View File

@@ -1,5 +1,5 @@
var Node = require("./node"),
Selector = require("./selector");
var Node = require('./node'),
Selector = require('./selector');
var Extend = function Extend(selector, option, index, currentFileInfo, visibilityInfo) {
this.selector = selector;
@@ -12,7 +12,7 @@ var Extend = function Extend(selector, option, index, currentFileInfo, visibilit
this.allowRoot = true;
switch (option) {
case "all":
case 'all':
this.allowBefore = true;
this.allowAfter = true;
break;
@@ -26,7 +26,7 @@ var Extend = function Extend(selector, option, index, currentFileInfo, visibilit
Extend.next_id = 0;
Extend.prototype = new Node();
Extend.prototype.type = "Extend";
Extend.prototype.type = 'Extend';
Extend.prototype.accept = function (visitor) {
this.selector = visitor.visit(this.selector);
};
@@ -46,7 +46,7 @@ Extend.prototype.findSelfSelectors = function (selectors) {
selectorElements = selectors[i].elements;
// duplicate the logic in genCSS function inside the selector node.
// future TODO - move both logics into the selector joiner visitor
if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === "") {
if (i > 0 && selectorElements.length && selectorElements[0].combinator.value === '') {
selectorElements[0].combinator.value = ' ';
}
selfElements = selfElements.concat(selectors[i].elements);

View File

@@ -1,11 +1,11 @@
var Node = require("./node"),
Media = require("./media"),
URL = require("./url"),
Quoted = require("./quoted"),
Ruleset = require("./ruleset"),
Anonymous = require("./anonymous"),
utils = require("../utils"),
LessError = require("../less-error");
var Node = require('./node'),
Media = require('./media'),
URL = require('./url'),
Quoted = require('./quoted'),
Ruleset = require('./ruleset'),
Anonymous = require('./anonymous'),
utils = require('../utils'),
LessError = require('../less-error');
//
// CSS @import node
@@ -50,7 +50,7 @@ var Import = function (path, features, options, index, currentFileInfo, visibili
// ruleset.
//
Import.prototype = new Node();
Import.prototype.type = "Import";
Import.prototype.type = 'Import';
Import.prototype.accept = function (visitor) {
if (this.features) {
this.features = visitor.visit(this.features);
@@ -62,10 +62,10 @@ Import.prototype.accept = function (visitor) {
};
Import.prototype.genCSS = function (context, output) {
if (this.css && this.path._fileInfo.reference === undefined) {
output.add("@import ", this._fileInfo, this._index);
output.add('@import ', this._fileInfo, this._index);
this.path.genCSS(context, output);
if (this.features) {
output.add(" ");
output.add(' ');
this.features.genCSS(context, output);
}
output.add(';');
@@ -136,7 +136,7 @@ Import.prototype.doEval = function (context) {
this.root.eval(context);
}
catch (e) {
e.message = "Plugin error during evaluation";
e.message = 'Plugin error during evaluation';
throw new LessError(e, this.root.imports, this.root.filename);
}
}
@@ -149,7 +149,7 @@ Import.prototype.doEval = function (context) {
}
if (this.skip) {
if (typeof this.skip === "function") {
if (typeof this.skip === 'function') {
this.skip = this.skip();
}
if (this.skip) {

View File

@@ -37,5 +37,6 @@ tree.UnicodeDescriptor = require('./unicode-descriptor');
tree.Negative = require('./negative');
tree.Extend = require('./extend');
tree.VariableCall = require('./variable-call');
tree.NamespaceValue = require('./namespace-value');
module.exports = tree;

View File

@@ -1,7 +1,7 @@
var JsEvalNode = require("./js-eval-node"),
Dimension = require("./dimension"),
Quoted = require("./quoted"),
Anonymous = require("./anonymous");
var JsEvalNode = require('./js-eval-node'),
Dimension = require('./dimension'),
Quoted = require('./quoted'),
Anonymous = require('./anonymous');
var JavaScript = function (string, escaped, index, currentFileInfo) {
this.escaped = escaped;
@@ -10,13 +10,14 @@ var JavaScript = function (string, escaped, index, currentFileInfo) {
this._fileInfo = currentFileInfo;
};
JavaScript.prototype = new JsEvalNode();
JavaScript.prototype.type = "JavaScript";
JavaScript.prototype.type = 'JavaScript';
JavaScript.prototype.eval = function(context) {
var result = this.evaluateJavaScript(this.expression, context);
var type = typeof result;
if (typeof result === 'number') {
if (type === 'number' && !isNaN(result)) {
return new Dimension(result);
} else if (typeof result === 'string') {
} else if (type === 'string') {
return new Quoted('"' + result + '"', result, this.escaped, this._index);
} else if (Array.isArray(result)) {
return new Anonymous(result.join(', '));

View File

@@ -1,5 +1,5 @@
var Node = require("./node"),
Variable = require("./variable");
var Node = require('./node'),
Variable = require('./variable');
var JsEvalNode = function() {
};
@@ -11,7 +11,7 @@ JsEvalNode.prototype.evaluateJavaScript = function (expression, context) {
evalContext = {};
if (!context.javascriptEnabled) {
throw { message: "Inline JavaScript is not enabled. Is it set in your options?",
throw { message: 'Inline JavaScript is not enabled. Is it set in your options?',
filename: this.fileInfo().filename,
index: this.getIndex() };
}
@@ -23,7 +23,7 @@ JsEvalNode.prototype.evaluateJavaScript = function (expression, context) {
try {
expression = new Function('return (' + expression + ')');
} catch (e) {
throw { message: "JavaScript evaluation error: " + e.message + " from `" + expression + "`" ,
throw { message: 'JavaScript evaluation error: ' + e.message + ' from `' + expression + '`' ,
filename: this.fileInfo().filename,
index: this.getIndex() };
}
@@ -44,7 +44,7 @@ JsEvalNode.prototype.evaluateJavaScript = function (expression, context) {
try {
result = expression.call(evalContext);
} catch (e) {
throw { message: "JavaScript evaluation error: '" + e.name + ': ' + e.message.replace(/["]/g, "'") + "'" ,
throw { message: 'JavaScript evaluation error: \'' + e.name + ': ' + e.message.replace(/["]/g, '\'') + '\'' ,
filename: this.fileInfo().filename,
index: this.getIndex() };
}

View File

@@ -1,10 +1,10 @@
var Node = require("./node");
var Node = require('./node');
var Keyword = function (value) { this.value = value; };
Keyword.prototype = new Node();
Keyword.prototype.type = "Keyword";
Keyword.prototype.type = 'Keyword';
Keyword.prototype.genCSS = function (context, output) {
if (this.value === '%') { throw { type: "Syntax", message: "Invalid % without number" }; }
if (this.value === '%') { throw { type: 'Syntax', message: 'Invalid % without number' }; }
output.add(this.value);
};

View File

@@ -1,10 +1,10 @@
var Ruleset = require("./ruleset"),
Value = require("./value"),
Selector = require("./selector"),
Anonymous = require("./anonymous"),
Expression = require("./expression"),
AtRule = require("./atrule"),
utils = require("../utils");
var Ruleset = require('./ruleset'),
Value = require('./value'),
Selector = require('./selector'),
Anonymous = require('./anonymous'),
Expression = require('./expression'),
AtRule = require('./atrule'),
utils = require('../utils');
var Media = function (value, features, index, currentFileInfo, visibilityInfo) {
this._index = index;
@@ -22,7 +22,7 @@ var Media = function (value, features, index, currentFileInfo, visibilityInfo) {
this.setParent(this.rules, this);
};
Media.prototype = new AtRule();
Media.prototype.type = "Media";
Media.prototype.type = 'Media';
Media.prototype.isRulesetLike = function() { return true; };
Media.prototype.accept = function (visitor) {
if (this.features) {
@@ -105,7 +105,7 @@ Media.prototype.evalNested = function (context) {
});
for (i = path.length - 1; i > 0; i--) {
path.splice(i, 0, new Anonymous("and"));
path.splice(i, 0, new Anonymous('and'));
}
return new Expression(path);

View File

@@ -1,7 +1,7 @@
var Node = require("./node"),
Selector = require("./selector"),
MixinDefinition = require("./mixin-definition"),
defaultFunc = require("../functions/default");
var Node = require('./node'),
Selector = require('./selector'),
MixinDefinition = require('./mixin-definition'),
defaultFunc = require('../functions/default');
var MixinCall = function (elements, args, index, currentFileInfo, important) {
this.selector = new Selector(elements);
@@ -13,7 +13,7 @@ var MixinCall = function (elements, args, index, currentFileInfo, important) {
this.setParent(this.selector, this);
};
MixinCall.prototype = new Node();
MixinCall.prototype.type = "MixinCall";
MixinCall.prototype.type = 'MixinCall';
MixinCall.prototype.accept = function (visitor) {
if (this.selector) {
this.selector = visitor.visit(this.selector);
@@ -28,6 +28,8 @@ MixinCall.prototype.eval = function (context) {
candidates = [], candidate, conditionResult = [], defaultResult, defFalseEitherCase = -1,
defNone = 0, defTrue = 1, defFalse = 2, count, originalRuleset, noArgumentsFilter;
this.selector = this.selector.eval(context);
function calcDefGroup(mixin, mixinPath) {
var f, p, namespace;
@@ -129,7 +131,7 @@ MixinCall.prototype.eval = function (context) {
mixin = candidates[m].mixin;
if (!(mixin instanceof MixinDefinition)) {
originalRuleset = mixin.originalRuleset || mixin;
mixin = new MixinDefinition("", [], mixin.rules, null, false, null, originalRuleset.visibilityInfo());
mixin = new MixinDefinition('', [], mixin.rules, null, false, null, originalRuleset.visibilityInfo());
mixin.originalRuleset = originalRuleset;
}
var newRules = mixin.evalCall(context, args, this.important).rules;
@@ -152,7 +154,7 @@ MixinCall.prototype.eval = function (context) {
index: this.getIndex(), filename: this.fileInfo().filename };
} else {
throw { type: 'Name',
message: this.selector.toCSS().trim() + " is undefined",
message: this.selector.toCSS().trim() + ' is undefined',
index: this.getIndex(), filename: this.fileInfo().filename };
}
};
@@ -169,16 +171,16 @@ MixinCall.prototype._setVisibilityToReplacement = function (replacement) {
MixinCall.prototype.format = function (args) {
return this.selector.toCSS().trim() + '(' +
(args ? args.map(function (a) {
var argValue = "";
var argValue = '';
if (a.name) {
argValue += a.name + ":";
argValue += a.name + ':';
}
if (a.value.toCSS) {
argValue += a.value.toCSS();
} else {
argValue += "???";
argValue += '???';
}
return argValue;
}).join(', ') : "") + ")";
}).join(', ') : '') + ')';
};
module.exports = MixinCall;

View File

@@ -1,14 +1,15 @@
var Selector = require("./selector"),
Element = require("./element"),
Ruleset = require("./ruleset"),
Declaration = require("./declaration"),
Expression = require("./expression"),
contexts = require("../contexts"),
utils = require("../utils");
var Selector = require('./selector'),
Element = require('./element'),
Ruleset = require('./ruleset'),
Declaration = require('./declaration'),
DetachedRuleset = require('./detached-ruleset'),
Expression = require('./expression'),
contexts = require('../contexts'),
utils = require('../utils');
var Definition = function (name, params, rules, condition, variadic, frames, visibilityInfo) {
this.name = name;
this.selectors = [new Selector([new Element(null, name, this._index, this._fileInfo)])];
this.selectors = [new Selector([new Element(null, name, false, this._index, this._fileInfo)])];
this.params = params;
this.condition = condition;
this.variadic = variadic;
@@ -31,7 +32,7 @@ var Definition = function (name, params, rules, condition, variadic, frames, vis
this.allowRoot = true;
};
Definition.prototype = new Ruleset();
Definition.prototype.type = "MixinDefinition";
Definition.prototype.type = 'MixinDefinition';
Definition.prototype.evalFirst = true;
Definition.prototype.accept = function (visitor) {
if (this.params && this.params.length) {
@@ -75,7 +76,7 @@ Definition.prototype.evalParams = function (context, mixinEnv, args, evaldArgume
i--;
continue;
} else {
throw { type: 'Runtime', message: "Named argument for " + this.name +
throw { type: 'Runtime', message: 'Named argument for ' + this.name +
' ' + args[i].name + ' not found' };
}
}
@@ -97,12 +98,18 @@ Definition.prototype.evalParams = function (context, mixinEnv, args, evaldArgume
} else {
val = arg && arg.value;
if (val) {
val = val.eval(context);
// This was a mixin call, pass in a detached ruleset of it's eval'd rules
if (Array.isArray(val)) {
val = new DetachedRuleset(new Ruleset('', val));
}
else {
val = val.eval(context);
}
} else if (params[i].value) {
val = params[i].value.eval(mixinEnv);
frame.resetCache();
} else {
throw { type: 'Runtime', message: "wrong number of arguments for " + this.name +
throw { type: 'Runtime', message: 'wrong number of arguments for ' + this.name +
' (' + argsLength + ' for ' + this.arity + ')' };
}

View File

@@ -0,0 +1,79 @@
var Node = require('./node'),
Variable = require('./variable'),
Ruleset = require('./ruleset'),
Selector = require('./selector');
var NamespaceValue = function (ruleCall, lookups, important, index, fileInfo) {
this.value = ruleCall;
this.lookups = lookups;
this.important = important;
this._index = index;
this._fileInfo = fileInfo;
};
NamespaceValue.prototype = new Node();
NamespaceValue.prototype.type = 'NamespaceValue';
NamespaceValue.prototype.eval = function (context) {
var i, j, name, rules = this.value.eval(context);
for (i = 0; i < this.lookups.length; i++) {
name = this.lookups[i];
/**
* Eval'd DRs return rulesets.
* Eval'd mixins return rules, so let's make a ruleset if we need it.
* We need to do this because of late parsing of values
*/
if (Array.isArray(rules)) {
rules = new Ruleset([new Selector()], rules);
}
if (name === '') {
rules = rules.lastDeclaration();
}
else if (name.charAt(0) === '@') {
if (name.charAt(1) === '@') {
name = '@' + new Variable(name.substr(1)).eval(context).value;
}
if (rules.variables) {
rules = rules.variable(name);
}
if (!rules) {
throw { type: 'Name',
message: 'variable ' + name + ' not found',
filename: this.fileInfo().filename,
index: this.getIndex() };
}
}
else {
if (name.substring(0, 2) === '$@') {
name = '$' + new Variable(name.substr(1)).eval(context).value;
}
else {
name = name.charAt(0) === '$' ? name : '$' + name;
}
if (rules.properties) {
rules = rules.property(name);
}
if (!rules) {
throw { type: 'Name',
message: 'property "' + name.substr(1) + '" not found',
filename: this.fileInfo().filename,
index: this.getIndex() };
}
// Properties are an array of values, since a ruleset can have multiple props.
// We pick the last one (the "cascaded" value)
rules = rules[rules.length - 1];
}
if (rules.value) {
rules = rules.eval(context).value;
}
if (rules.ruleset) {
rules = rules.ruleset.eval(context);
}
}
return rules;
};
module.exports = NamespaceValue;

View File

@@ -1,12 +1,12 @@
var Node = require("./node"),
Operation = require("./operation"),
Dimension = require("./dimension");
var Node = require('./node'),
Operation = require('./operation'),
Dimension = require('./dimension');
var Negative = function (node) {
this.value = node;
};
Negative.prototype = new Node();
Negative.prototype.type = "Negative";
Negative.prototype.type = 'Negative';
Negative.prototype.genCSS = function (context, output) {
output.add('-');
this.value.genCSS(context, output);

View File

@@ -6,10 +6,10 @@ var Node = function() {
this.parsed = null;
var self = this;
Object.defineProperty(this, "currentFileInfo", {
Object.defineProperty(this, 'currentFileInfo', {
get: function() { return self.fileInfo(); }
});
Object.defineProperty(this, "index", {
Object.defineProperty(this, 'index', {
get: function() { return self.getIndex(); }
});
@@ -76,7 +76,7 @@ Node.compare = function (a, b) {
if ((a.compare) &&
// for "symmetric results" force toCSS-based comparison
// of Quoted or Anonymous if either value is one of those
!(b.type === "Quoted" || b.type === "Anonymous")) {
!(b.type === 'Quoted' || b.type === 'Anonymous')) {
return a.compare(b);
} else if (b.compare) {
return -b.compare(a);

View File

@@ -1,6 +1,6 @@
var Node = require("./node"),
Color = require("./color"),
Dimension = require("./dimension");
var Node = require('./node'),
Color = require('./color'),
Dimension = require('./dimension');
var Operation = function (op, operands, isSpaced) {
this.op = op.trim();
@@ -8,7 +8,7 @@ var Operation = function (op, operands, isSpaced) {
this.isSpaced = isSpaced;
};
Operation.prototype = new Node();
Operation.prototype.type = "Operation";
Operation.prototype.type = 'Operation';
Operation.prototype.accept = function (visitor) {
this.operands = visitor.visit(this.operands);
};
@@ -26,8 +26,8 @@ Operation.prototype.eval = function (context) {
b = b.toColor();
}
if (!a.operate) {
throw { type: "Operation",
message: "Operation on an invalid type" };
throw { type: 'Operation',
message: 'Operation on an invalid type' };
}
return a.operate(context, op, b);
@@ -38,11 +38,11 @@ Operation.prototype.eval = function (context) {
Operation.prototype.genCSS = function (context, output) {
this.operands[0].genCSS(context, output);
if (this.isSpaced) {
output.add(" ");
output.add(' ');
}
output.add(this.op);
if (this.isSpaced) {
output.add(" ");
output.add(' ');
}
this.operands[1].genCSS(context, output);
};

View File

@@ -1,10 +1,10 @@
var Node = require("./node");
var Node = require('./node');
var Paren = function (node) {
this.value = node;
};
Paren.prototype = new Node();
Paren.prototype.type = "Paren";
Paren.prototype.type = 'Paren';
Paren.prototype.genCSS = function (context, output) {
output.add('(');
this.value.genCSS(context, output);

View File

@@ -1,5 +1,5 @@
var Node = require("./node"),
Declaration = require("./declaration");
var Node = require('./node'),
Declaration = require('./declaration');
var Property = function (name, index, currentFileInfo) {
this.name = name;
@@ -7,7 +7,7 @@ var Property = function (name, index, currentFileInfo) {
this._fileInfo = currentFileInfo;
};
Property.prototype = new Node();
Property.prototype.type = "Property";
Property.prototype.type = 'Property';
Property.prototype.eval = function (context) {
var property, name = this.name;
// TODO: shorten this reference
@@ -15,7 +15,7 @@ Property.prototype.eval = function (context) {
if (this.evaluating) {
throw { type: 'Name',
message: "Recursive property reference for " + name,
message: 'Recursive property reference for ' + name,
filename: this.fileInfo().filename,
index: this.getIndex() };
}
@@ -55,7 +55,7 @@ Property.prototype.eval = function (context) {
return property;
} else {
throw { type: 'Name',
message: "Property '" + name + "' is undefined",
message: 'Property \'' + name + '\' is undefined',
filename: this.currentFileInfo.filename,
index: this.index };
}

View File

@@ -1,6 +1,6 @@
var Node = require("./node"),
Variable = require("./variable"),
Property = require("./property");
var Node = require('./node'),
Variable = require('./variable'),
Property = require('./property');
var Quoted = function (str, content, escaped, index, currentFileInfo) {
this.escaped = (escaped == null) ? true : escaped;
@@ -12,7 +12,7 @@ var Quoted = function (str, content, escaped, index, currentFileInfo) {
this.propRegex = /\$\{([\w-]+)\}/g;
};
Quoted.prototype = new Node();
Quoted.prototype.type = "Quoted";
Quoted.prototype.type = 'Quoted';
Quoted.prototype.genCSS = function (context, output) {
if (!this.escaped) {
output.add(this.quote, this.fileInfo(), this.getIndex());
@@ -49,7 +49,7 @@ Quoted.prototype.eval = function (context) {
};
Quoted.prototype.compare = function (other) {
// when comparing quoted strings allow the quote to differ
if (other.type === "Quoted" && !this.escaped && !other.escaped) {
if (other.type === 'Quoted' && !this.escaped && !other.escaped) {
return Node.numericCompare(this.value, other.value);
} else {
return other.toCSS && this.toCSS() === other.toCSS() ? 0 : undefined;

View File

@@ -1,16 +1,16 @@
var Node = require("./node"),
Declaration = require("./declaration"),
Keyword = require("./keyword"),
Comment = require("./comment"),
Paren = require("./paren"),
Selector = require("./selector"),
Element = require("./element"),
Anonymous = require("./anonymous"),
contexts = require("../contexts"),
globalFunctionRegistry = require("../functions/function-registry"),
defaultFunc = require("../functions/default"),
getDebugInfo = require("./debug-info"),
utils = require("../utils");
var Node = require('./node'),
Declaration = require('./declaration'),
Keyword = require('./keyword'),
Comment = require('./comment'),
Paren = require('./paren'),
Selector = require('./selector'),
Element = require('./element'),
Anonymous = require('./anonymous'),
contexts = require('../contexts'),
globalFunctionRegistry = require('../functions/function-registry'),
defaultFunc = require('../functions/default'),
getDebugInfo = require('./debug-info'),
utils = require('../utils');
var Ruleset = function (selectors, rules, strictImports, visibilityInfo) {
this.selectors = selectors;
@@ -27,7 +27,7 @@ var Ruleset = function (selectors, rules, strictImports, visibilityInfo) {
};
Ruleset.prototype = new Node();
Ruleset.prototype.type = "Ruleset";
Ruleset.prototype.type = 'Ruleset';
Ruleset.prototype.isRuleset = true;
Ruleset.prototype.isRulesetLike = function() { return true; };
Ruleset.prototype.accept = function (visitor) {
@@ -41,22 +41,47 @@ Ruleset.prototype.accept = function (visitor) {
}
};
Ruleset.prototype.eval = function (context) {
var thisSelectors = this.selectors, selectors,
selCnt, selector, i, hasOnePassingSelector = false;
var that = this, selectors, selCnt, selector, i, hasVariable, hasOnePassingSelector = false;
if (thisSelectors && (selCnt = thisSelectors.length)) {
if (this.selectors && (selCnt = this.selectors.length)) {
selectors = new Array(selCnt);
defaultFunc.error({
type: "Syntax",
message: "it is currently only allowed in parametric mixin guards,"
type: 'Syntax',
message: 'it is currently only allowed in parametric mixin guards,'
});
for (i = 0; i < selCnt; i++) {
selector = thisSelectors[i].eval(context);
selector = this.selectors[i].eval(context);
for (var j = 0; j < selector.elements.length; j++) {
if (selector.elements[j].isVariable) {
hasVariable = true;
break;
}
}
selectors[i] = selector;
if (selector.evaldCondition) {
hasOnePassingSelector = true;
}
}
if (hasVariable) {
var toParseSelectors = new Array(selCnt);
for (i = 0; i < selCnt; i++) {
selector = selectors[i];
toParseSelectors[i] = selector.toCSS(context);
}
this.parse.parseNode(
toParseSelectors.join(','),
["selectors"],
selectors[0].getIndex(),
selectors[0].fileInfo(),
function(err, result) {
if (result) {
selectors = utils.flattenArray(result);
}
});
}
defaultFunc.reset();
} else {
hasOnePassingSelector = true;
@@ -121,7 +146,7 @@ Ruleset.prototype.eval = function (context) {
// Evaluate mixin calls.
for (i = 0; (rule = rsRules[i]); i++) {
if (rule.type === "MixinCall") {
if (rule.type === 'MixinCall') {
/* jshint loopfunc:true */
rules = rule.eval(context).filter(function(r) {
if ((r instanceof Declaration) && r.variable) {
@@ -135,7 +160,7 @@ Ruleset.prototype.eval = function (context) {
rsRules.splice.apply(rsRules, [i, 1].concat(rules));
i += rules.length - 1;
ruleset.resetCache();
} else if (rule.type === "VariableCall") {
} else if (rule.type === 'VariableCall') {
/* jshint loopfunc:true */
rules = rule.eval(context).rules.filter(function(r) {
if ((r instanceof Declaration) && r.variable) {
@@ -162,7 +187,7 @@ Ruleset.prototype.eval = function (context) {
// for rulesets, check if it is a css guard and can be removed
if (rule instanceof Ruleset && rule.selectors && rule.selectors.length === 1) {
// check if it can be folded in (e.g. & where)
if (rule.selectors[0].isJustParentSelector()) {
if (rule.selectors[0] && rule.selectors[0].isJustParentSelector()) {
rsRules.splice(i--, 1);
for (var j = 0; (subRule = rule.rules[j]); j++) {
@@ -194,7 +219,7 @@ Ruleset.prototype.evalImports = function(context) {
if (!rules) { return; }
for (i = 0; i < rules.length; i++) {
if (rules[i].type === "Import") {
if (rules[i].type === 'Import') {
importRules = rules[i].eval(context);
if (importRules && (importRules.length || importRules.length === 0)) {
rules.splice.apply(rules, [i, 1].concat(importRules));
@@ -249,11 +274,11 @@ Ruleset.prototype.variables = function () {
// when evaluating variables in an import statement, imports have not been eval'd
// so we need to go inside import statements.
// guard against root being a string (in the case of inlined less)
if (r.type === "Import" && r.root && r.root.variables) {
if (r.type === 'Import' && r.root && r.root.variables) {
var vars = r.root.variables();
for (var name in vars) {
if (vars.hasOwnProperty(name)) {
hash[name] = vars[name];
hash[name] = r.root.variable(name);
}
}
}
@@ -293,14 +318,22 @@ Ruleset.prototype.property = function (name) {
return this.parseValue(decl);
}
};
Ruleset.prototype.lastDeclaration = function () {
for (var i = this.rules.length; i > 0; i--) {
var decl = this.rules[i - 1];
if (decl instanceof Declaration) {
return this.parseValue(decl);
}
}
};
Ruleset.prototype.parseValue = function(toParse) {
var self = this;
function transformDeclaration(decl) {
if (decl.value instanceof Anonymous && !decl.parsed) {
if (typeof decl.value.value === "string") {
if (typeof decl.value.value === 'string') {
this.parse.parseNode(
decl.value.value,
["value", "important"],
['value', 'important'],
decl.value.getIndex(),
decl.fileInfo(),
function(err, result) {
@@ -402,8 +435,8 @@ Ruleset.prototype.genCSS = function (context, output) {
context.tabLevel++;
}
var tabRuleStr = context.compress ? '' : Array(context.tabLevel + 1).join(" "),
tabSetStr = context.compress ? '' : Array(context.tabLevel).join(" "),
var tabRuleStr = context.compress ? '' : Array(context.tabLevel + 1).join(' '),
tabSetStr = context.compress ? '' : Array(context.tabLevel).join(' '),
sep;
var charsetNodeIndex = 0;
@@ -418,7 +451,7 @@ Ruleset.prototype.genCSS = function (context, output) {
ruleNodes.splice(charsetNodeIndex, 0, rule);
charsetNodeIndex++;
importNodeIndex++;
} else if (rule.type === "Import") {
} else if (rule.type === 'Import') {
ruleNodes.splice(importNodeIndex, 0, rule);
importNodeIndex++;
} else {
@@ -511,7 +544,13 @@ Ruleset.prototype.joinSelector = function (paths, context, selector) {
} else {
var insideParent = new Array(elementsToPak.length);
for (j = 0; j < elementsToPak.length; j++) {
insideParent[j] = new Element(null, elementsToPak[j], originalElement._index, originalElement._fileInfo);
insideParent[j] = new Element(
null,
elementsToPak[j],
originalElement.isVariable,
originalElement._index,
originalElement._fileInfo
);
}
replacementParen = new Paren(new Selector(insideParent));
}
@@ -520,7 +559,7 @@ Ruleset.prototype.joinSelector = function (paths, context, selector) {
function createSelector(containedElement, originalElement) {
var element, selector;
element = new Element(null, containedElement, originalElement._index, originalElement._fileInfo);
element = new Element(null, containedElement, originalElement.isVariable, originalElement._index, originalElement._fileInfo);
selector = new Selector([element]);
return selector;
}
@@ -545,7 +584,8 @@ Ruleset.prototype.joinSelector = function (paths, context, selector) {
}
if (addPath.length > 0) {
// /deep/ is a combinator that is valid without anything in front of it
// /deep/ is a CSS4 selector - (removed, so should deprecate)
// that is valid without anything in front of it
// so if the & does not have a combinator that is "" or " " then
// and there is a combinator on the parent, then grab that.
// this also allows + a { & .b { .a & { ... though not sure why you would want to do that
@@ -554,7 +594,13 @@ Ruleset.prototype.joinSelector = function (paths, context, selector) {
combinator = parentEl.combinator;
}
// join the elements so far with the first part of the parent
newJoinedSelector.elements.push(new Element(combinator, parentEl.value, replacedElement._index, replacedElement._fileInfo));
newJoinedSelector.elements.push(new Element(
combinator,
parentEl.value,
replacedElement.isVariable,
replacedElement._index,
replacedElement._fileInfo
));
newJoinedSelector.elements = newJoinedSelector.elements.concat(addPath[0].elements.slice(1));
}
@@ -648,7 +694,7 @@ Ruleset.prototype.joinSelector = function (paths, context, selector) {
for (i = 0; (el = inSelector.elements[i]); i++) {
// non parent reference elements just get added
if (el.value !== "&") {
if (el.value !== '&') {
var nestedSelector = findNestedSelector(el);
if (nestedSelector != null) {
// merge the current list of non parent selector elements
@@ -688,7 +734,7 @@ Ruleset.prototype.joinSelector = function (paths, context, selector) {
// the combinator used on el should now be applied to the next element instead so that
// it is not lost
if (sel.length > 0) {
sel[0].elements.push(new Element(el.combinator, '', el._index, el._fileInfo));
sel[0].elements.push(new Element(el.combinator, '', el.isVariable, el._index, el._fileInfo));
}
selectorsMultiplied.push(sel);
}

View File

@@ -1,6 +1,6 @@
var Node = require("./node"),
Element = require("./element"),
LessError = require("../less-error");
var Node = require('./node'),
Element = require('./element'),
LessError = require('../less-error');
var Selector = function (elements, extendList, condition, index, currentFileInfo, visibilityInfo) {
this.extendList = extendList;
@@ -14,7 +14,7 @@ var Selector = function (elements, extendList, condition, index, currentFileInfo
this.setParent(this.elements, this);
};
Selector.prototype = new Node();
Selector.prototype.type = "Selector";
Selector.prototype.type = 'Selector';
Selector.prototype.accept = function (visitor) {
if (this.elements) {
this.elements = visitor.visitArray(this.elements);
@@ -35,10 +35,13 @@ Selector.prototype.createDerived = function(elements, extendList, evaldCondition
return newSelector;
};
Selector.prototype.getElements = function(els) {
if (typeof els === "string") {
if (!els) {
return [new Element('', '&', false, this._index, this._fileInfo)];
}
if (typeof els === 'string') {
this.parse.parseNode(
els,
["selector"],
['selector'],
this._index,
this._fileInfo,
function(err, result) {
@@ -54,7 +57,7 @@ Selector.prototype.getElements = function(els) {
return els;
};
Selector.prototype.createEmptySelectors = function() {
var el = new Element('', '&', this._index, this._fileInfo),
var el = new Element('', '&', false, this._index, this._fileInfo),
sels = [new Selector([el], null, null, this._index, this._fileInfo)];
sels[0].mediaEmpty = true;
return sels;
@@ -85,10 +88,10 @@ Selector.prototype.mixinElements = function() {
var elements = this.elements.map( function(v) {
return v.combinator.value + (v.value.value || v.value);
}).join("").match(/[,&#\*\.\w-]([\w-]|(\\.))*/g);
}).join('').match(/[,&#\*\.\w-]([\w-]|(\\.))*/g);
if (elements) {
if (elements[0] === "&") {
if (elements[0] === '&') {
elements.shift();
}
} else {
@@ -114,7 +117,7 @@ Selector.prototype.eval = function (context) {
};
Selector.prototype.genCSS = function (context, output) {
var i, element;
if ((!context || !context.firstSelector) && this.elements[0].combinator.value === "") {
if ((!context || !context.firstSelector) && this.elements[0].combinator.value === '') {
output.add(' ', this.fileInfo(), this.getIndex());
}
for (i = 0; i < this.elements.length; i++) {

View File

@@ -1,9 +1,9 @@
var Node = require("./node");
var Node = require('./node');
var UnicodeDescriptor = function (value) {
this.value = value;
};
UnicodeDescriptor.prototype = new Node();
UnicodeDescriptor.prototype.type = "UnicodeDescriptor";
UnicodeDescriptor.prototype.type = 'UnicodeDescriptor';
module.exports = UnicodeDescriptor;

View File

@@ -1,6 +1,6 @@
var Node = require("./node"),
unitConversions = require("../data/unit-conversions"),
utils = require("../utils");
var Node = require('./node'),
unitConversions = require('../data/unit-conversions'),
utils = require('../utils');
var Unit = function (numerator, denominator, backupUnit) {
this.numerator = numerator ? utils.copyArray(numerator).sort() : [];
@@ -13,7 +13,7 @@ var Unit = function (numerator, denominator, backupUnit) {
};
Unit.prototype = new Node();
Unit.prototype.type = "Unit";
Unit.prototype.type = 'Unit';
Unit.prototype.clone = function () {
return new Unit(utils.copyArray(this.numerator), utils.copyArray(this.denominator), this.backupUnit);
};
@@ -29,9 +29,9 @@ Unit.prototype.genCSS = function (context, output) {
}
};
Unit.prototype.toString = function () {
var i, returnStr = this.numerator.join("*");
var i, returnStr = this.numerator.join('*');
for (i = 0; i < this.denominator.length; i++) {
returnStr += "/" + this.denominator[i];
returnStr += '/' + this.denominator[i];
}
return returnStr;
};

View File

@@ -1,4 +1,4 @@
var Node = require("./node");
var Node = require('./node');
var URL = function (val, index, currentFileInfo, isEvald) {
this.value = val;
@@ -7,14 +7,14 @@ var URL = function (val, index, currentFileInfo, isEvald) {
this.isEvald = isEvald;
};
URL.prototype = new Node();
URL.prototype.type = "Url";
URL.prototype.type = 'Url';
URL.prototype.accept = function (visitor) {
this.value = visitor.visit(this.value);
};
URL.prototype.genCSS = function (context, output) {
output.add("url(");
output.add('url(');
this.value.genCSS(context, output);
output.add(")");
output.add(')');
};
URL.prototype.eval = function (context) {
var val = this.value.eval(context),
@@ -24,11 +24,11 @@ URL.prototype.eval = function (context) {
// Add the base path if the URL is relative
rootpath = this.fileInfo() && this.fileInfo().rootpath;
if (rootpath &&
typeof val.value === "string" &&
typeof val.value === 'string' &&
context.isPathRelative(val.value)) {
if (!val.quote) {
rootpath = rootpath.replace(/[\(\)'"\s]/g, function(match) { return "\\" + match; });
rootpath = rootpath.replace(/[\(\)'"\s]/g, function(match) { return '\\' + match; });
}
val.value = rootpath + val.value;
}

View File

@@ -1,8 +1,8 @@
var Node = require("./node");
var Node = require('./node');
var Value = function (value) {
if (!value) {
throw new Error("Value requires an array argument");
throw new Error('Value requires an array argument');
}
if (!Array.isArray(value)) {
this.value = [ value ];
@@ -12,7 +12,7 @@ var Value = function (value) {
}
};
Value.prototype = new Node();
Value.prototype.type = "Value";
Value.prototype.type = 'Value';
Value.prototype.accept = function (visitor) {
if (this.value) {
this.value = visitor.visitArray(this.value);

View File

@@ -1,14 +1,36 @@
var Node = require("./node"),
Variable = require("./variable");
var Node = require('./node'),
Variable = require('./variable'),
Ruleset = require('./ruleset'),
DetachedRuleset = require('./detached-ruleset'),
LessError = require('../less-error');
var VariableCall = function (variable) {
var VariableCall = function (variable, index, currentFileInfo) {
this.variable = variable;
this._index = index;
this._fileInfo = currentFileInfo;
this.allowRoot = true;
};
VariableCall.prototype = new Node();
VariableCall.prototype.type = "VariableCall";
VariableCall.prototype.type = 'VariableCall';
VariableCall.prototype.eval = function (context) {
var detachedRuleset = new Variable(this.variable).eval(context);
return detachedRuleset.callEval(context);
var rules, detachedRuleset = new Variable(this.variable, this.getIndex(), this.fileInfo()).eval(context),
error = new LessError({message: 'Could not evaluate variable call ' + this.variable});
if (!detachedRuleset.ruleset) {
if (Array.isArray(detachedRuleset)) {
rules = detachedRuleset;
}
else if (Array.isArray(detachedRuleset.value)) {
rules = detachedRuleset.value;
}
else {
throw error;
}
detachedRuleset = new DetachedRuleset(new Ruleset('', rules));
}
if (detachedRuleset.ruleset) {
return detachedRuleset.callEval(context);
}
throw error;
};
module.exports = VariableCall;

View File

@@ -1,4 +1,5 @@
var Node = require("./node");
var Node = require('./node'),
Call = require('./call');
var Variable = function (name, index, currentFileInfo) {
this.name = name;
@@ -6,7 +7,7 @@ var Variable = function (name, index, currentFileInfo) {
this._fileInfo = currentFileInfo;
};
Variable.prototype = new Node();
Variable.prototype.type = "Variable";
Variable.prototype.type = 'Variable';
Variable.prototype.eval = function (context) {
var variable, name = this.name;
@@ -16,7 +17,7 @@ Variable.prototype.eval = function (context) {
if (this.evaluating) {
throw { type: 'Name',
message: "Recursive variable definition for " + name,
message: 'Recursive variable definition for ' + name,
filename: this.fileInfo().filename,
index: this.getIndex() };
}
@@ -30,7 +31,13 @@ Variable.prototype.eval = function (context) {
var importantScope = context.importantScope[context.importantScope.length - 1];
importantScope.important = v.important;
}
return v.value.eval(context);
// If in calc, wrap vars in a function call to cascade evaluate args first
if (context.inCalc) {
return (new Call('_SELF', [v.value])).eval(context);
}
else {
return v.value.eval(context);
}
}
});
if (variable) {
@@ -38,7 +45,7 @@ Variable.prototype.eval = function (context) {
return variable;
} else {
throw { type: 'Name',
message: "variable " + name + " is undefined",
message: 'variable ' + name + ' is undefined',
filename: this.fileInfo().filename,
index: this.getIndex() };
}

View File

@@ -1,5 +1,5 @@
/* jshint proto: true */
module.exports = {
var utils = {
getLocation: function(index, inputStream) {
var n = index + 1,
line = null,
@@ -10,7 +10,7 @@ module.exports = {
}
if (typeof index === 'number') {
line = (inputStream.slice(0, index).match(/\n/g) || "").length;
line = (inputStream.slice(0, index).match(/\n/g) || '').length;
}
return {
@@ -65,5 +65,21 @@ module.exports = {
}
}
return obj1;
},
flattenArray: function(arr, result) {
result = result || [];
for (var i = 0, length = arr.length; i < length; i++) {
var value = arr[i];
if (Array.isArray(value)) {
utils.flattenArray(value, result);
} else {
if (value !== undefined) {
result.push(value);
}
}
}
return result;
}
};
module.exports = utils;

View File

@@ -1,7 +1,7 @@
var tree = require("../tree"),
Visitor = require("./visitor"),
logger = require("../logger"),
utils = require("../utils");
var tree = require('../tree'),
Visitor = require('./visitor'),
logger = require('../logger'),
utils = require('../utils');
/* jshint loopfunc:true */
@@ -110,7 +110,7 @@ ProcessExtendsVisitor.prototype = {
extendList.filter(function(extend) {
return !extend.hasFoundMatches && extend.parent_ids.length == 1;
}).forEach(function(extend) {
var selector = "_unknown_";
var selector = '_unknown_';
try {
selector = extend.selector.toCSS({});
}
@@ -118,7 +118,7 @@ ProcessExtendsVisitor.prototype = {
if (!indices[extend.index + ' ' + selector]) {
indices[extend.index + ' ' + selector] = true;
logger.warn("extend '" + selector + "' has no matches");
logger.warn('extend \'' + selector + '\' has no matches');
}
});
},
@@ -177,7 +177,7 @@ ProcessExtendsVisitor.prototype = {
extendsToAdd.push(newExtend);
newExtend.ruleset = targetExtend.ruleset;
//remember its parents for circular references
// remember its parents for circular references
newExtend.parent_ids = newExtend.parent_ids.concat(targetExtend.parent_ids, extend.parent_ids);
// only process the selector once.. if we have :extend(.a,.b) then multiple
@@ -197,15 +197,15 @@ ProcessExtendsVisitor.prototype = {
// may no longer be needed.
this.extendChainCount++;
if (iterationCount > 100) {
var selectorOne = "{unable to calculate}";
var selectorTwo = "{unable to calculate}";
var selectorOne = '{unable to calculate}';
var selectorTwo = '{unable to calculate}';
try {
selectorOne = extendsToAdd[0].selfSelectors[0].toCSS();
selectorTwo = extendsToAdd[0].selector.toCSS();
}
catch (e) {}
throw { message: "extend circular reference detected. One of the circular extends is currently:" +
selectorOne + ":extend(" + selectorTwo + ")"};
throw { message: 'extend circular reference detected. One of the circular extends is currently:' +
selectorOne + ':extend(' + selectorTwo + ')'};
}
// now process the new extends on the existing rules so that we can handle a extending b extending c extending
@@ -329,7 +329,7 @@ ProcessExtendsVisitor.prototype = {
return matches;
},
isElementValuesEqual: function(elementValue1, elementValue2) {
if (typeof elementValue1 === "string" || typeof elementValue2 === "string") {
if (typeof elementValue1 === 'string' || typeof elementValue2 === 'string') {
return elementValue1 === elementValue2;
}
if (elementValue1 instanceof tree.Attribute) {
@@ -385,6 +385,7 @@ ProcessExtendsVisitor.prototype = {
firstElement = new tree.Element(
match.initialCombinator,
replacementSelector.elements[0].value,
replacementSelector.elements[0].isVariable,
replacementSelector.elements[0].getIndex(),
replacementSelector.elements[0].fileInfo()
);

View File

@@ -1,7 +1,7 @@
var contexts = require("../contexts"),
Visitor = require("./visitor"),
ImportSequencer = require("./import-sequencer"),
utils = require("../utils");
var contexts = require('../contexts'),
Visitor = require('./visitor'),
ImportSequencer = require('./import-sequencer'),
utils = require('../utils');
var ImportVisitor = function(importer, finish) {
@@ -151,14 +151,14 @@ ImportVisitor.prototype = {
}
},
visitDeclaration: function (declNode, visitArgs) {
if (declNode.value.type === "DetachedRuleset") {
if (declNode.value.type === 'DetachedRuleset') {
this.context.frames.unshift(declNode);
} else {
visitArgs.visitDeeper = false;
}
},
visitDeclarationOut: function(declNode) {
if (declNode.value.type === "DetachedRuleset") {
if (declNode.value.type === 'DetachedRuleset') {
this.context.frames.shift();
}
},

Some files were not shown because too many files have changed in this diff Show More