CSSLint: parse <declaration-value> for --custom-property
https://drafts.csswg.org/css-syntax-3/#typedef-declaration-value Example: :root { --fit: { position: absolute; top: 0; bottom: 0; left: 0; right: 0; } }
This commit is contained in:
parent
12fe1b619f
commit
1406cae6c5
|
@ -2546,9 +2546,14 @@ Parser.prototype = function() {
|
||||||
if (property !== null) {
|
if (property !== null) {
|
||||||
|
|
||||||
tokenStream.mustMatch(Tokens.COLON);
|
tokenStream.mustMatch(Tokens.COLON);
|
||||||
this._readWhitespace();
|
|
||||||
|
|
||||||
expr = this._expr();
|
// whitespace is a part of custom property value
|
||||||
|
if (property.text.startsWith("--")) {
|
||||||
|
expr = this._customProperty();
|
||||||
|
} else {
|
||||||
|
this._readWhitespace();
|
||||||
|
expr = this._expr();
|
||||||
|
}
|
||||||
|
|
||||||
//if there's no parts for the value, it's an error
|
//if there's no parts for the value, it's an error
|
||||||
if (!expr || expr.length === 0) {
|
if (!expr || expr.length === 0) {
|
||||||
|
@ -2655,6 +2660,73 @@ Parser.prototype = function() {
|
||||||
return values.length > 0 ? new PropertyValue(values, values[0].line, values[0].col) : null;
|
return values.length > 0 ? new PropertyValue(values, values[0].line, values[0].col) : null;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
_customProperty: function() {
|
||||||
|
const reader = this._tokenStream._reader;
|
||||||
|
const value = [];
|
||||||
|
|
||||||
|
const endings = [];
|
||||||
|
let end = /[;!}]/;
|
||||||
|
|
||||||
|
readValue:
|
||||||
|
while (!reader.eof()) {
|
||||||
|
const chunk = reader.readMatch(/([^;!'"{}()[\]/]|\/(?!\*))+/y);
|
||||||
|
if (chunk) value.push(chunk);
|
||||||
|
|
||||||
|
reader.mark();
|
||||||
|
let c = reader.read();
|
||||||
|
value.push(c);
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
case '/':
|
||||||
|
value.push(reader.readMatch(/([^*]|\*(?!\/))*(\*\/|$)/y));
|
||||||
|
continue;
|
||||||
|
case '"':
|
||||||
|
case "'":
|
||||||
|
reader.reset();
|
||||||
|
value.pop();
|
||||||
|
value.push(reader.readString());
|
||||||
|
continue;
|
||||||
|
case '{':
|
||||||
|
endings.push(end);
|
||||||
|
end = '}';
|
||||||
|
continue;
|
||||||
|
case '(':
|
||||||
|
endings.push(end);
|
||||||
|
end = ')';
|
||||||
|
continue;
|
||||||
|
case '[':
|
||||||
|
endings.push(end);
|
||||||
|
end = ']';
|
||||||
|
continue;
|
||||||
|
case ';':
|
||||||
|
case '!':
|
||||||
|
if (endings.length) continue;
|
||||||
|
reader.reset();
|
||||||
|
// fallthrough
|
||||||
|
case '}':
|
||||||
|
case ')':
|
||||||
|
case ']':
|
||||||
|
if (end instanceof RegExp ? !end.test(c) : c !== end) {
|
||||||
|
reader.reset();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
end = endings.pop();
|
||||||
|
if (end) continue;
|
||||||
|
if (c === '}') {
|
||||||
|
// unget parent }
|
||||||
|
reader.reset();
|
||||||
|
value.pop();
|
||||||
|
}
|
||||||
|
break readValue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!value[0]) return null;
|
||||||
|
const {startCol: col, startLine: line} = this._tokenStream._token;
|
||||||
|
return new PropertyValue([
|
||||||
|
new PropertyValuePart(value.join(''), line, col),
|
||||||
|
], line, col);
|
||||||
|
},
|
||||||
|
|
||||||
_term: function(inFunction) {
|
_term: function(inFunction) {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -6916,6 +6988,14 @@ StringReader.prototype = {
|
||||||
*/
|
*/
|
||||||
readMatch: function(matcher) {
|
readMatch: function(matcher) {
|
||||||
|
|
||||||
|
if (matcher.sticky) {
|
||||||
|
matcher.lastIndex = this._cursor;
|
||||||
|
if (matcher.test(this._input)) {
|
||||||
|
return this.readCount(RegExp.lastMatch.length);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
var source = this._input.substring(this._cursor),
|
var source = this._input.substring(this._cursor),
|
||||||
value = null;
|
value = null;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user