parserlib: simplified media query L4
This commit is contained in:
parent
95a4514f15
commit
91501cce19
|
@ -1398,6 +1398,12 @@ self.parserlib = (() => {
|
||||||
Tokens.RIGHTMIDDLE_SYM,
|
Tokens.RIGHTMIDDLE_SYM,
|
||||||
Tokens.RIGHTBOTTOM_SYM,
|
Tokens.RIGHTBOTTOM_SYM,
|
||||||
],
|
],
|
||||||
|
mediaValue: [
|
||||||
|
Tokens.IDENT,
|
||||||
|
Tokens.NUMBER,
|
||||||
|
Tokens.DIMENSION,
|
||||||
|
Tokens.LENGTH,
|
||||||
|
],
|
||||||
op: [
|
op: [
|
||||||
Tokens.SLASH,
|
Tokens.SLASH,
|
||||||
Tokens.COMMA,
|
Tokens.COMMA,
|
||||||
|
@ -3704,53 +3710,57 @@ self.parserlib = (() => {
|
||||||
_mediaQuery() {
|
_mediaQuery() {
|
||||||
const stream = this._tokenStream;
|
const stream = this._tokenStream;
|
||||||
const expressions = [];
|
const expressions = [];
|
||||||
|
const mod = stream.match(Tokens.IDENT, ['only', 'not']);
|
||||||
let type = null;
|
let type = null;
|
||||||
const token = stream.match(Tokens.IDENT, ['only', 'not']);
|
|
||||||
const ident = token.value || null;
|
|
||||||
this._ws();
|
this._ws();
|
||||||
const next = stream.LT(1);
|
const next = stream.LT(1);
|
||||||
switch (next.type) {
|
if (next.type === Tokens.IDENT) {
|
||||||
case Tokens.IDENT:
|
|
||||||
type = this._mediaFeature();
|
type = this._mediaFeature();
|
||||||
break;
|
} else if (next.value === '(') {
|
||||||
case Tokens.LPAREN:
|
expressions.push(this._mediaExpression({or: true}));
|
||||||
expressions.push(this._mediaExpression());
|
} else {
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._ws();
|
this._ws();
|
||||||
while (stream.match(Tokens.IDENT)) {
|
const c = stream.match(Tokens.IDENT).value;
|
||||||
if (lowerCmp(stream._token.value, 'and')) {
|
if (c) {
|
||||||
|
if (lowerCmp(c, 'and') || !type && lowerCmp(c, 'or')) {
|
||||||
this._ws();
|
this._ws();
|
||||||
expressions.push(this._mediaExpression());
|
expressions.push(this._mediaExpression());
|
||||||
} else {
|
} else {
|
||||||
stream.throwUnexpected(undefined, ["'and'"]);
|
stream.throwUnexpected(undefined, ["'and'", !type && "'or'"].filter(Boolean));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new MediaQuery(ident, type, expressions, token || next);
|
return new MediaQuery(mod.value || null, type, expressions, mod || next);
|
||||||
}
|
}
|
||||||
|
|
||||||
_mediaExpression() {
|
_mediaExpression() {
|
||||||
const stream = this._tokenStream;
|
const stream = this._tokenStream;
|
||||||
let token;
|
|
||||||
let expression = null;
|
|
||||||
stream.mustMatch(Tokens.LPAREN);
|
stream.mustMatch(Tokens.LPAREN);
|
||||||
const feature = this._mediaFeature();
|
const feature = this._mediaFeature(TT.mediaValue);
|
||||||
|
let b;
|
||||||
|
for (let pass = 0; ++pass <= 2;) {
|
||||||
this._ws();
|
this._ws();
|
||||||
if (stream.match(Tokens.COLON)) {
|
b = stream.get(true).value;
|
||||||
|
if (/^[:=<>]$/.test(b)) {
|
||||||
|
const isRange = /[<>]/.test(b);
|
||||||
|
if (isRange) stream.match(Tokens.EQUALS);
|
||||||
this._ws();
|
this._ws();
|
||||||
token = stream.LT(1);
|
b = this._expression({calc: true});
|
||||||
expression = this._expression({calc: true});
|
if (!isRange) break;
|
||||||
|
} else {
|
||||||
|
stream.unget();
|
||||||
|
b = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
stream.mustMatch(Tokens.RPAREN);
|
stream.mustMatch(Tokens.RPAREN);
|
||||||
this._ws();
|
this._ws();
|
||||||
return new MediaFeature(feature, expression ? new SyntaxUnit(expression, token) : null);
|
return new MediaFeature(feature); // TODO: construct the value properly
|
||||||
}
|
}
|
||||||
|
|
||||||
_mediaFeature() {
|
_mediaFeature(type = Tokens.IDENT) {
|
||||||
this._tokenStream.mustMatch(Tokens.IDENT);
|
return SyntaxUnit.fromToken(this._tokenStream.mustMatch(type));
|
||||||
return SyntaxUnit.fromToken(this._tokenStream._token);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_page(start) {
|
_page(start) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user