Comparing version 3.5.0-beta to 3.5.0-beta.2
@@ -6,7 +6,4 @@ { | ||
"globals": {}, | ||
"rules": { | ||
"quotes": [ | ||
1, | ||
"single" | ||
], | ||
"no-eval": 2, | ||
@@ -13,0 +10,0 @@ "no-use-before-define": [ |
@@ -1,2 +0,10 @@ | ||
## 3.0.4 | ||
# 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 | ||
@@ -6,2 +14,3 @@ - Update source-map to 0.6.x (#3180). Enforces node 6+ though. | ||
# 3.0.0 | ||
2018-02-10 | ||
@@ -22,2 +31,3 @@ - Fix `calc()` function to not do math operations on compile | ||
# 2.7.3 | ||
2017-10-23 | ||
@@ -28,2 +38,3 @@ | ||
# 2.7.2 | ||
2017-01-04 | ||
@@ -30,0 +41,0 @@ |
@@ -298,3 +298,3 @@ 'use strict'; | ||
src: [ | ||
'test/less/*.less', | ||
'test/less/plugin.less', | ||
// Don't test NPM import, obviously | ||
@@ -301,0 +301,0 @@ '!test/less/plugin-module.less', |
@@ -65,2 +65,17 @@ var contexts = {}; | ||
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 () { | ||
@@ -77,2 +92,3 @@ if (!this.parensStack) { | ||
contexts.Eval.prototype.inCalc = false; | ||
contexts.Eval.prototype.mathOn = true; | ||
@@ -79,0 +95,0 @@ contexts.Eval.prototype.isMathOn = function () { |
@@ -242,3 +242,2 @@ var chunker = require('./chunker'); | ||
i++; | ||
console.log(input.substr(lastPos, i - lastPos)); | ||
inComment = true; | ||
@@ -328,2 +327,6 @@ blockDepth++; | ||
parserInput.prevChar = function() { | ||
return input.charAt(parserInput.i - 1); | ||
}; | ||
parserInput.getInput = function() { | ||
@@ -330,0 +333,0 @@ return input; |
@@ -44,15 +44,34 @@ var contexts = require('./contexts'), | ||
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); | ||
@@ -64,6 +83,7 @@ | ||
// 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); | ||
@@ -70,0 +90,0 @@ } |
@@ -10,3 +10,3 @@ var Node = require('./node'), | ||
this.args = args; | ||
this.mathOn = name === 'calc' ? false : true; | ||
this.calc = name === 'calc'; | ||
this._index = index; | ||
@@ -34,3 +34,2 @@ this._fileInfo = currentFileInfo; | ||
Call.prototype.eval = function (context) { | ||
/** | ||
@@ -40,4 +39,10 @@ * 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; | ||
@@ -44,0 +49,0 @@ |
@@ -5,3 +5,3 @@ var Node = require('./node'), | ||
var Element = function (combinator, value, index, currentFileInfo, visibilityInfo) { | ||
var Element = function (combinator, value, isVariable, index, currentFileInfo, visibilityInfo) { | ||
this.combinator = combinator instanceof Combinator ? | ||
@@ -17,2 +17,3 @@ combinator : new Combinator(combinator); | ||
} | ||
this.isVariable = isVariable; | ||
this._index = index; | ||
@@ -35,2 +36,3 @@ this._fileInfo = currentFileInfo; | ||
this.value.eval ? this.value.eval(context) : this.value, | ||
this.isVariable, | ||
this.getIndex(), | ||
@@ -42,2 +44,3 @@ this.fileInfo(), this.visibilityInfo()); | ||
this.value, | ||
this.isVariable, | ||
this.getIndex(), | ||
@@ -44,0 +47,0 @@ this.fileInfo(), this.visibilityInfo()); |
@@ -19,2 +19,3 @@ var Node = require('./node'), | ||
var returnValue, | ||
mathOn = context.isMathOn(), | ||
inParenthesis = this.parens && !this.parensInOp, | ||
@@ -27,6 +28,9 @@ doubleParen = false; | ||
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; | ||
@@ -41,3 +45,3 @@ } | ||
} | ||
if (this.parens && this.parensInOp && !(context.isMathOn()) && !doubleParen) { | ||
if (this.parens && this.parensInOp && !mathOn && !doubleParen) { | ||
returnValue = new Paren(returnValue); | ||
@@ -44,0 +48,0 @@ } |
@@ -11,3 +11,3 @@ var Selector = require('./selector'), | ||
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; | ||
@@ -14,0 +14,0 @@ this.condition = condition; |
@@ -44,6 +44,5 @@ var Node = require('./node'), | ||
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); | ||
@@ -54,4 +53,11 @@ defaultFunc.error({ | ||
}); | ||
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; | ||
@@ -62,2 +68,21 @@ if (selector.evaldCondition) { | ||
} | ||
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(); | ||
@@ -168,3 +193,3 @@ } else { | ||
// 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); | ||
@@ -518,3 +543,9 @@ | ||
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 | ||
); | ||
} | ||
@@ -528,3 +559,3 @@ replacementParen = new Paren(new Selector(insideParent)); | ||
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]); | ||
@@ -554,3 +585,4 @@ return 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 | ||
@@ -564,3 +596,9 @@ // and there is a combinator on the parent, then grab that. | ||
// 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)); | ||
@@ -699,3 +737,3 @@ } | ||
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)); | ||
} | ||
@@ -702,0 +740,0 @@ selectorsMultiplied.push(sel); |
@@ -57,3 +57,3 @@ var Node = require('./node'), | ||
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)]; | ||
@@ -60,0 +60,0 @@ sels[0].mediaEmpty = true; |
/* jshint proto: true */ | ||
module.exports = { | ||
var utils = { | ||
getLocation: function(index, inputStream) { | ||
@@ -68,3 +68,19 @@ var n = index + 1, | ||
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; |
@@ -388,2 +388,3 @@ var tree = require('../tree'), | ||
replacementSelector.elements[0].value, | ||
replacementSelector.elements[0].isVariable, | ||
replacementSelector.elements[0].getIndex(), | ||
@@ -390,0 +391,0 @@ replacementSelector.elements[0].fileInfo() |
@@ -35,3 +35,4 @@ var tree = require('../tree'); | ||
this._implementation = implementation; | ||
this._visitFnCache = []; | ||
this._visitInCache = {}; | ||
this._visitOutCache = {}; | ||
@@ -52,11 +53,12 @@ if (!_hasIndexed) { | ||
if (!nodeTypeIndex) { | ||
// MixinCall args aren't a node type? | ||
if (node.value && node.value.typeIndex) { | ||
this.visit(node.value); | ||
} | ||
return node; | ||
} | ||
var visitFnCache = this._visitFnCache, | ||
impl = this._implementation, | ||
aryIndx = nodeTypeIndex << 1, | ||
outAryIndex = aryIndx | 1, | ||
func = visitFnCache[aryIndx], | ||
funcOut = visitFnCache[outAryIndex], | ||
var impl = this._implementation, | ||
func = this._visitInCache[nodeTypeIndex], | ||
funcOut = this._visitOutCache[nodeTypeIndex], | ||
visitArgs = _visitArgs, | ||
@@ -71,4 +73,4 @@ fnName; | ||
funcOut = impl[fnName + 'Out'] || _noop; | ||
visitFnCache[aryIndx] = func; | ||
visitFnCache[outAryIndex] = funcOut; | ||
this._visitInCache[nodeTypeIndex] = func; | ||
this._visitOutCache[nodeTypeIndex] = funcOut; | ||
} | ||
@@ -78,3 +80,3 @@ | ||
var newNode = func.call(impl, node, visitArgs); | ||
if (impl.isReplacing) { | ||
if (node && impl.isReplacing) { | ||
node = newNode; | ||
@@ -81,0 +83,0 @@ } |
{ | ||
"name": "less", | ||
"version": "3.5.0-beta", | ||
"version": "3.5.0-beta.2", | ||
"description": "Leaner CSS", | ||
@@ -5,0 +5,0 @@ "homepage": "http://lesscss.org", |
@@ -1,4 +0,3 @@ | ||
SyntaxError: @unknown rule is missing block or ending semi-colon in {path}at-rules-unmatching-block.less on line 2, column 10: | ||
1 | ||
2 @unknown url( { | ||
3 50% {width: 20px;} | ||
SyntaxError: expected ')' got '' in {path}at-rules-unmatching-block.less on line 5, column 1: | ||
4 } | ||
5 |
@@ -1,4 +0,3 @@ | ||
SyntaxError: @unknown rule is missing block or ending semi-colon in {path}at-rules-unmatching-block.less on line 2, column 10: | ||
1 | ||
2 @unknown url( { | ||
3 50% {width: 20px;} | ||
SyntaxError: expected ')' got '' in {path}at-rules-unmatching-block.less on line 5, column 1: | ||
4 } | ||
5 |
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is too big to display
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
2191131
928
41646