CSSLint: fix '&&' in grammarParser

consequences:
* fixed text-shadow
* fixed <display-listitem>
* switched to a string in <shadow>
This commit is contained in:
tophf 2018-12-24 21:08:12 +03:00
parent 509f9fb18f
commit d3c73391f1

View File

@ -1050,13 +1050,7 @@ self.parserlib = (() => {
'<hsl-color>': '[ <number> | <angle> ] <percentage>{2} [ / <nonnegative-number-or-percentage> ]? | ' + '<hsl-color>': '[ <number> | <angle> ] <percentage>{2} [ / <nonnegative-number-or-percentage> ]? | ' +
'[ <number> | <angle> ] , <percentage>#{2} [ , <nonnegative-number-or-percentage> ]?', '[ <number> | <angle> ] , <percentage>#{2} [ , <nonnegative-number-or-percentage> ]?',
// inset? && [ <length>{2,4} && <color>? ] '<shadow>': 'inset? && [ <length>{2,4} && <color>? ]',
'<shadow>': Matcher =>
Matcher.many(
[true],
Matcher.cast('<length>').braces(2, 4),
'inset',
'<color>'),
'<single-timing-function>': 'linear | <cubic-bezier-timing-function> | <step-timing-function> | frames()', '<single-timing-function>': 'linear | <cubic-bezier-timing-function> | <step-timing-function> | frames()',
@ -1897,7 +1891,8 @@ self.parserlib = (() => {
const p = required === false ? Matcher.prec.OROR : Matcher.prec.ANDAND; const p = required === false ? Matcher.prec.OROR : Matcher.prec.ANDAND;
const s = ms.map((m, i) => { const s = ms.map((m, i) => {
if (required !== false && !required[i]) { if (required !== false && !required[i]) {
return m.toString(Matcher.prec.MOD) + '?'; const str = m.toString(Matcher.prec.MOD);
return str.endsWith('?') ? str : str + '?';
} }
return m.toString(p); return m.toString(p);
}).join(required === false ? ' || ' : ' && '); }).join(required === false ? ' || ' : ' && ');
@ -1935,10 +1930,22 @@ self.parserlib = (() => {
function andand() { function andand() {
// andand = seq ( " && " seq)* // andand = seq ( " && " seq)*
const m = [seq()]; const m = [seq()];
let reqPrev = !isOptional(m[0]);
const required = [reqPrev];
while (reader.readMatch(' && ')) { while (reader.readMatch(' && ')) {
m.push(seq()); const item = seq();
const req = !isOptional(item);
// Matcher.many apparently can't handle optional items first
if (req && !reqPrev) {
m.unshift(item);
required.unshift(req);
} else {
m.push(item);
required.push(req);
reqPrev = req;
} }
return m.length === 1 ? m[0] : Matcher.andand.apply(Matcher, m); }
return m.length === 1 ? m[0] : Matcher.many(required, ...m);
} }
function seq() { function seq() {
@ -1993,6 +2000,10 @@ self.parserlib = (() => {
} }
return result; return result;
} }
function isOptional(item) {
return !Array.isArray(item.options) && item.toString().endsWith('?');
}
})(); })();
//endregion //endregion