media-query-parser
Advanced tools
Comparing version 3.0.0-beta.1 to 3.0.0-beta.2
@@ -1,23 +0,14 @@ | ||
import { MediaCondition, MediaFeature, MediaQuery, MediaQueryList, ParserError, ParserToken, RatioToken, ValidRange } from "../utils.js"; | ||
export type ConvenientToken = ParserToken | (RatioToken & { | ||
hasSpaceBefore: boolean; | ||
hasSpaceAfter: boolean; | ||
start: number; | ||
end: number; | ||
}); | ||
export type UncheckedRange = { | ||
leftToken?: ConvenientToken | undefined; | ||
leftOp?: ">=" | "<=" | ">" | "<" | "=" | undefined; | ||
feature: string; | ||
rightOp?: ">=" | "<=" | ">" | "<" | "=" | undefined; | ||
rightToken?: ConvenientToken | undefined; | ||
}; | ||
export declare const isParserError: (value: unknown) => value is ParserError; | ||
import { BooleanFeatureNode, ConditionNode, ConditionWithoutOrNode, FeatureNode, GeneralEnclosedNode, InParensNode, Match, ParserToken, PlainFeatureNode, QueryListNode, QueryNode } from "../utils.js"; | ||
export declare const matchPlain: (ts: ParserToken[], i?: number) => Match<PlainFeatureNode>; | ||
export declare const matchBoolean: (ts: ParserToken[], i?: number) => Match<BooleanFeatureNode>; | ||
export declare const matchFeature: (ts: ParserToken[], i?: number) => Match<FeatureNode>; | ||
export declare const matchGeneralEnclosed: (ts: ParserToken[], i?: number) => Match<GeneralEnclosedNode>; | ||
export declare const matchInParens: (ts: ParserToken[], i?: number) => Match<InParensNode>; | ||
export declare const matchOr: (ts: ParserToken[], i?: number) => Match<InParensNode>; | ||
export declare const matchAnd: (ts: ParserToken[], i?: number) => Match<InParensNode>; | ||
export declare const matchNot: (ts: ParserToken[], i?: number) => Match<InParensNode>; | ||
export declare const matchCondition: (ts: ParserToken[], i?: number) => Match<ConditionNode>; | ||
export declare const matchConditionWithoutOr: (ts: ParserToken[], i?: number) => Match<ConditionWithoutOrNode>; | ||
export declare const matchQuery: (ts: ParserToken[]) => Match<QueryNode>; | ||
export declare const matchQueryList: (parsingTokens: ParserToken[]) => QueryListNode; | ||
export declare const splitMediaQueryList: (tokens: ParserToken[]) => Array<ParserToken[]>; | ||
export declare const readMediaQueryList: (parsingTokens: ParserToken[]) => MediaQueryList; | ||
export declare const readMediaQuery: (parsingTokens: ParserToken[]) => MediaQuery | ParserError; | ||
export declare const readMediaCondition: (parsingTokens: ParserToken[], mayContainOr: boolean, previousOperator?: "and" | "or" | "not" | undefined) => MediaCondition | ParserError; | ||
export declare const readMediaFeature: (parsingTokens: ParserToken[]) => MediaFeature | ParserError; | ||
export declare const readRange: (convenientTokens: ConvenientToken[]) => (ValidRange & { | ||
feature: string; | ||
}) | ParserError; |
@@ -1,353 +0,334 @@ | ||
export const isParserError = e => 'object' == typeof e && null !== e && 'errid' in e | ||
export const splitMediaQueryList = e => { | ||
const t = [[]], | ||
r = [] | ||
for (const n of e) | ||
if ('comma' === n.type && 0 === r.length) t.push([]) | ||
else { | ||
switch (n.type) { | ||
const n = '<'.codePointAt(0), | ||
t = '>'.codePointAt(0), | ||
i = '='.codePointAt(0), | ||
e = '/'.codePointAt(0), | ||
o = (t, e = 0) => { | ||
const o = t.at(e) | ||
if ('delim' === (null == o ? void 0 : o.type) && o.value === n) { | ||
const n = t.at(e + 1), | ||
o = 'delim' === (null == n ? void 0 : n.type) && n.value === i && !n.isAfterSpace | ||
return {n: {t: 'lt', isIncl: o}, i: e + (o ? 2 : 1)} | ||
} | ||
}, | ||
a = (n, e = 0) => { | ||
const o = n.at(e) | ||
if ('delim' === (null == o ? void 0 : o.type) && o.value === t) { | ||
const t = n.at(e + 1), | ||
o = 'delim' === (null == t ? void 0 : t.type) && t.value === i && !t.isAfterSpace | ||
return {n: {t: 'gt', isIncl: o}, i: e + (o ? 2 : 1)} | ||
} | ||
}, | ||
r = (n, t = 0) => { | ||
var e, r | ||
return null !== (r = null !== (e = o(n, t)) && void 0 !== e ? e : a(n, t)) && void 0 !== r | ||
? r | ||
: ((n, t = 0) => { | ||
const e = n.at(t) | ||
if ('delim' === (null == e ? void 0 : e.type) && e.value === i) | ||
return {n: {t: 'eq'}, i: t + 1} | ||
})(n, t) | ||
}, | ||
c = (n, t = 0) => { | ||
const i = ((n, t = 0) => { | ||
const i = n.at(t) | ||
if ('number' === (null == i ? void 0 : i.type) && i.value >= 0) { | ||
const o = n.at(t + 1) | ||
if ('delim' === (null == o ? void 0 : o.type) && o.value === e) { | ||
const e = n.at(t + 2) | ||
if ('number' === (null == e ? void 0 : e.type) && e.value >= 0) | ||
return {n: {n: 'ratio', l: i.value, r: e.value}, i: t + 3} | ||
} | ||
} | ||
})(n, t) | ||
if (i) return i | ||
const o = n.at(t) | ||
if (o && ('number' === o.type || 'dimension' === o.type)) { | ||
return { | ||
n: | ||
'number' === o.type | ||
? {n: 'number', v: o.value, isInt: 'integer' === o.flag} | ||
: {n: 'dimension', v: o.value, u: o.unit}, | ||
i: t + 1 | ||
} | ||
} | ||
}, | ||
u = (n, t = 0) => { | ||
const i = c(n, t) | ||
if (i) return i | ||
const e = n.at(t) | ||
return 'ident' === (null == e ? void 0 : e.type) | ||
? {n: {n: 'ident', v: e.value}, i: t + 1} | ||
: void 0 | ||
} | ||
export const matchPlain = (n, t = 0) => { | ||
const i = n.at(t) | ||
if ('ident' === (null == i ? void 0 : i.type)) { | ||
const e = n.at(t + 1) | ||
if ('colon' === (null == e ? void 0 : e.type)) { | ||
const e = u(n, t + 2) | ||
if (e) return {n: {n: 'feature', t: 'value', f: i.value, v: e.n}, i: e.i} | ||
} | ||
} | ||
} | ||
export const matchBoolean = (n, t = 0) => { | ||
const i = n.at(t) | ||
if ('ident' === (null == i ? void 0 : i.type)) | ||
return {n: {n: 'feature', t: 'boolean', f: i.value}, i: t + 1} | ||
} | ||
export const matchFeature = (n, t = 0) => { | ||
var i, e | ||
const c = n.at(t) | ||
if ('(' === (null == c ? void 0 : c.type)) { | ||
const c = | ||
null !== | ||
(e = | ||
null !== (i = matchPlain(n, t + 1)) && void 0 !== i | ||
? i | ||
: ((n, t = 0) => { | ||
var i | ||
const e = u(n, t) | ||
if (e) { | ||
const t = r(n, e.i) | ||
if (t) { | ||
const r = u(n, t.i) | ||
if (r) { | ||
const c = null !== (i = o(n, r.i)) && void 0 !== i ? i : a(n, r.i) | ||
if (c) { | ||
const i = u(n, c.i) | ||
if (i && 'ident' === r.n.n && 'ident' !== e.n.n && 'ident' !== i.n.n) { | ||
if ('lt' === t.n.t && 'lt' === c.n.t) | ||
return { | ||
n: { | ||
n: 'feature', | ||
t: 'range', | ||
f: r.n.v, | ||
r: { | ||
a: e.n, | ||
op: t.n.isIncl ? '<=' : '<', | ||
b: r.n, | ||
op2: c.n.isIncl ? '<=' : '<', | ||
c: i.n | ||
} | ||
}, | ||
i: i.i | ||
} | ||
if ('gt' === t.n.t && 'gt' === c.n.t) | ||
return { | ||
n: { | ||
n: 'feature', | ||
t: 'range', | ||
f: r.n.v, | ||
r: { | ||
a: e.n, | ||
op: t.n.isIncl ? '>=' : '>', | ||
b: r.n, | ||
op2: c.n.isIncl ? '>=' : '>', | ||
c: i.n | ||
} | ||
}, | ||
i: i.i | ||
} | ||
} | ||
} | ||
let s = '=' | ||
if ( | ||
('lt' === t.n.t | ||
? (s = t.n.isIncl ? '<=' : '<') | ||
: 'gt' === t.n.t && (s = t.n.isIncl ? '>=' : '>'), | ||
'ident' === e.n.n && 'ident' !== r.n.n) | ||
) | ||
return { | ||
n: {n: 'feature', t: 'range', f: e.n.v, r: {a: e.n, op: s, b: r.n}}, | ||
i: r.i | ||
} | ||
if ('ident' === r.n.n && 'ident' !== e.n.n) | ||
return { | ||
n: {n: 'feature', t: 'range', f: r.n.v, r: {a: e.n, op: s, b: r.n}}, | ||
i: r.i | ||
} | ||
} | ||
} | ||
} | ||
})(n, t + 1)) && void 0 !== e | ||
? e | ||
: matchBoolean(n, t + 1) | ||
if (c) { | ||
const t = n.at(c.i) | ||
if (')' === (null == t ? void 0 : t.type)) return {n: c.n, i: c.i + 1} | ||
} | ||
} | ||
} | ||
export const matchGeneralEnclosed = (n, t = 0) => { | ||
const i = n.at(t) | ||
if (i && ('function' === i.type || '(' === i.type)) { | ||
const i = ['('] | ||
let e = t + 1, | ||
o = n.at(e) | ||
n: for (; o; ) { | ||
switch (o.type) { | ||
case 'function': | ||
case '(': | ||
r.push(')') | ||
i.push('(') | ||
break | ||
case '{': | ||
case '[': | ||
r.push(']') | ||
i.push(o.type) | ||
break | ||
case '{': | ||
r.push('}') | ||
case ')': | ||
if (('(' === i.at(-1) && i.pop(), 0 === i.length)) break n | ||
break | ||
case ')': | ||
case ']': | ||
'[' === i.at(-1) && i.pop() | ||
break | ||
case '}': | ||
r.at(-1) === n.type && r.pop() | ||
break | ||
'{' === i.at(-1) && i.pop() | ||
} | ||
t[t.length - 1].push(n) | ||
o = n.at(++e) | ||
} | ||
return t | ||
if (0 === i.length) return {n: {n: 'general-enclosed'}, i: e} | ||
} | ||
} | ||
export const readMediaQueryList = e => { | ||
const t = splitMediaQueryList(e) | ||
if (1 === t.length && 0 === t[0].length) | ||
return {type: 'query-list', mediaQueries: [{type: 'query'}]} | ||
{ | ||
const e = [] | ||
for (const r of t) { | ||
const t = readMediaQuery(r) | ||
isParserError(t) ? e.push({type: 'query', prefix: 'not'}) : e.push(t) | ||
export const matchInParens = (n, t = 0) => { | ||
const i = matchFeature(n, t) | ||
if (i) return {n: {n: 'in-parens', v: i.n}, i: i.i} | ||
const e = n.at(t) | ||
if ('(' === (null == e ? void 0 : e.type)) { | ||
const i = matchCondition(n, t + 1) | ||
if (i) { | ||
const t = n.at(i.i) | ||
if (')' === (null == t ? void 0 : t.type)) return {n: {n: 'in-parens', v: i.n}, i: i.i + 1} | ||
} | ||
return {type: 'query-list', mediaQueries: e} | ||
} | ||
const o = matchGeneralEnclosed(n, t) | ||
return o ? {n: {n: 'in-parens', v: o.n}, i: o.i} : void 0 | ||
} | ||
export const readMediaQuery = e => { | ||
var t, r, n | ||
const i = e.at(0) | ||
if (i) { | ||
if ('(' === i.type) { | ||
const r = readMediaCondition(e, !0) | ||
if (isParserError(r)) { | ||
const {start: n, end: a} = null !== (t = e.at(1)) && void 0 !== t ? t : i | ||
return {errid: 'EXPECT_FEATURE_OR_CONDITION', start: n, end: a, child: r} | ||
export const matchOr = (n, t = 0) => { | ||
const i = n.at(t) | ||
if ('ident' === (null == i ? void 0 : i.type) && 'or' === i.value) { | ||
const i = matchInParens(n, t + 1) | ||
if (i) return {n: i.n, i: i.i} | ||
} | ||
} | ||
export const matchAnd = (n, t = 0) => { | ||
const i = n.at(t) | ||
if ('ident' === (null == i ? void 0 : i.type) && 'and' === i.value) { | ||
const i = matchInParens(n, t + 1) | ||
if (i) return {n: i.n, i: i.i} | ||
} | ||
} | ||
export const matchNot = (n, t = 0) => { | ||
const i = n.at(t) | ||
if ('ident' === (null == i ? void 0 : i.type) && 'not' === i.value) { | ||
const i = matchInParens(n, t + 1) | ||
if (i) return {n: i.n, i: i.i} | ||
} | ||
} | ||
export const matchCondition = (n, t = 0) => { | ||
const i = matchNot(n, t) | ||
if (i) return {n: {n: 'condition', op: 'not', a: i.n}, i: i.i} | ||
{ | ||
const i = matchInParens(n, t) | ||
if (i) { | ||
const t = matchAnd(n, i.i) | ||
if (t) { | ||
const e = [t.n] | ||
let o = t.i, | ||
a = matchAnd(n, t.i) | ||
for (; a; ) e.push(a.n), (o = a.i), (a = matchAnd(n, a.i)) | ||
return {n: {n: 'condition', op: 'and', a: i.n, bs: e}, i: o} | ||
} | ||
return {type: 'query', mediaCondition: r} | ||
} | ||
if ('ident' === i.type) { | ||
let t, a | ||
const {value: d, end: s} = i | ||
;('only' !== d && 'not' !== d) || (t = d) | ||
const o = void 0 === t ? 0 : 1, | ||
l = e.at(o) | ||
if (!l) return {errid: 'EXPECT_LPAREN_OR_TYPE', start: s, end: s} | ||
if ('ident' !== l.type) { | ||
if ('not' === t && '(' === l.type) { | ||
const t = readMediaCondition(e.slice(o), !0) | ||
if (isParserError(t)) { | ||
const {start: n, end: i} = null !== (r = e.at(o + 1)) && void 0 !== r ? r : l | ||
return {errid: 'EXPECT_CONDITION', start: n, end: i, child: t} | ||
} | ||
return { | ||
type: 'query', | ||
mediaCondition: {type: 'condition', operator: 'not', children: [t]} | ||
} | ||
} | ||
{ | ||
const {start: e, end: t} = l | ||
return {errid: 'EXPECT_TYPE', start: e, end: t} | ||
} | ||
const e = matchOr(n, i.i) | ||
if (e) { | ||
const t = [e.n] | ||
let o = e.i, | ||
a = matchOr(n, e.i) | ||
for (; a; ) t.push(a.n), (o = a.i), (a = matchOr(n, a.i)) | ||
return {n: {n: 'condition', op: 'or', a: i.n, bs: t}, i: o} | ||
} | ||
{ | ||
const {value: e, start: r, end: n} = l | ||
if ('all' === e) a = void 0 | ||
else if ('print' === e || 'screen' === e) a = e | ||
else { | ||
if ( | ||
'tty' !== e && | ||
'tv' !== e && | ||
'projection' !== e && | ||
'handheld' !== e && | ||
'braille' !== e && | ||
'embossed' !== e && | ||
'aural' !== e && | ||
'speech' !== e | ||
) | ||
return {errid: 'EXPECT_TYPE', start: r, end: n} | ||
;(t = 'not' === t ? void 0 : 'not'), (a = void 0) | ||
} | ||
} | ||
if (o + 1 === e.length) return {type: 'query', prefix: t, mediaType: a} | ||
{ | ||
const r = e[o + 1] | ||
if ('ident' === r.type && 'and' === r.value) { | ||
const r = e.at(-1), | ||
i = e.at(o + 2) | ||
let d, | ||
s = r.end + 1 | ||
if ('ident' === (null == i ? void 0 : i.type) && 'not' === i.value) { | ||
s += 1 | ||
const t = readMediaCondition(e.slice(o + 3), !1) | ||
d = isParserError(t) ? t : {type: 'condition', operator: 'not', children: [t]} | ||
} else d = readMediaCondition(e.slice(o + 2), !1) | ||
const {start: l, end: u} = | ||
null !== (n = e.at(o + 2)) && void 0 !== n ? n : {start: s, end: s} | ||
return isParserError(d) | ||
? {errid: 'EXPECT_CONDITION', start: l, end: u, child: d} | ||
: {type: 'query', prefix: t, mediaType: a, mediaCondition: d} | ||
} | ||
return {errid: 'EXPECT_AND', start: r.start, end: r.end} | ||
} | ||
return {n: {n: 'condition', op: 'and', a: i.n}, i: i.i} | ||
} | ||
return {errid: 'EXPECT_LPAREN_OR_TYPE_OR_MODIFIER', start: i.start, end: i.end} | ||
} | ||
return {errid: 'EMPTY_QUERY', start: 0, end: 0} | ||
} | ||
export const readMediaCondition = (e, t, r) => { | ||
const n = e.at(0) | ||
if (n) { | ||
if ('(' !== n.type) return {errid: 'EXPECT_LPAREN', start: n.start, end: n.end} | ||
let i, | ||
a = e.length - 1, | ||
d = 0, | ||
s = 0 | ||
for (const [t, r] of e.entries()) | ||
if ( | ||
('(' === r.type ? ((s += 1), (d = Math.max(d, s))) : ')' === r.type && (s -= 1), 0 === s) | ||
) { | ||
a = t | ||
break | ||
export const matchConditionWithoutOr = (n, t = 0) => { | ||
const i = matchNot(n, t) | ||
if (i) return {n: {n: 'condition', op: 'not', a: i.n}, i: i.i} | ||
{ | ||
const i = matchInParens(n, t) | ||
if (i) { | ||
const t = matchAnd(n, i.i) | ||
if (t) { | ||
const e = [t.n] | ||
let o = t.i, | ||
a = matchAnd(n, t.i) | ||
for (; a; ) e.push(a.n), (o = a.i), (a = matchAnd(n, a.i)) | ||
return {n: {n: 'condition', op: 'and', a: i.n, bs: e}, i: o} | ||
} | ||
if (0 !== s) return {errid: 'MISMATCH_PARENS', start: n.start, end: e[e.length - 1].end} | ||
const o = e.slice(0, a + 1) | ||
if ( | ||
((i = | ||
1 === d | ||
? readMediaFeature(o) | ||
: 'ident' === o[1].type && 'not' === o[1].value | ||
? readMediaCondition(o.slice(2, -1), !0, 'not') | ||
: readMediaCondition(o.slice(1, -1), !0)), | ||
isParserError(i)) | ||
) | ||
return { | ||
errid: 'EXPECT_FEATURE_OR_CONDITION', | ||
start: n.start, | ||
end: o[o.length - 1].end, | ||
child: i | ||
} | ||
if (a === e.length - 1) return {type: 'condition', operator: r, children: [i]} | ||
{ | ||
const n = e[a + 1] | ||
if ('ident' !== n.type || ('and' !== n.value && 'or' !== n.value)) | ||
return {errid: 'EXPECT_AND_OR_OR', start: n.start, end: n.end} | ||
if (void 0 !== r && r !== n.value) | ||
return {errid: 'MIX_AND_WITH_OR', start: n.start, end: n.end} | ||
if ('or' === n.value && !t) return {errid: 'MIX_AND_WITH_OR', start: n.start, end: n.end} | ||
const d = readMediaCondition(e.slice(a + 2), t, n.value) | ||
return isParserError(d) | ||
? d | ||
: {type: 'condition', operator: n.value, children: [i, ...d.children]} | ||
return {n: {n: 'condition', op: 'and', a: i.n}, i: i.i} | ||
} | ||
} | ||
return {errid: 'EMPTY_CONDITION', start: 0, end: 0} | ||
} | ||
export const readMediaFeature = e => { | ||
const t = e.at(0) | ||
if (t) { | ||
if ('(' !== t.type) return {errid: 'EXPECT_LPAREN', start: t.start, end: t.end} | ||
const r = e[e.length - 1] | ||
if (')' !== r.type) return {errid: 'EXPECT_RPAREN', start: r.end + 1, end: r.end + 1} | ||
const n = [e[0]] | ||
for (let t = 1; t < e.length; t++) { | ||
if (t < e.length - 2) { | ||
const r = e[t], | ||
i = e[t + 1], | ||
a = e[t + 2] | ||
if ( | ||
'number' === r.type && | ||
r.value > 0 && | ||
'delim' === i.type && | ||
47 === i.value && | ||
'number' === a.type && | ||
a.value > 0 | ||
) { | ||
n.push({ | ||
type: 'ratio', | ||
numerator: r.value, | ||
denominator: a.value, | ||
hasSpaceBefore: r.hasSpaceBefore, | ||
hasSpaceAfter: a.hasSpaceAfter, | ||
start: r.start, | ||
end: a.end | ||
}), | ||
(t += 2) | ||
continue | ||
export const matchQuery = n => { | ||
const t = matchCondition(n, 0) | ||
if (t) return {n: {n: 'query', condition: t.n}, i: t.i} | ||
{ | ||
const t = n.at(0) | ||
if ('ident' === (null == t ? void 0 : t.type)) { | ||
if ('not' === t.value || 'only' === t.value) { | ||
const i = n.at(1) | ||
if ('ident' === (null == i ? void 0 : i.type)) { | ||
const e = n.at(2) | ||
if ('ident' === (null == e ? void 0 : e.type) && 'and' === e.value) { | ||
const e = matchConditionWithoutOr(n, 3) | ||
if (e) return {n: {n: 'query', condition: e.n, type: i.value, prefix: t.value}, i: e.i} | ||
} | ||
return {n: {n: 'query', type: i.value, prefix: t.value}, i: 2} | ||
} | ||
} | ||
n.push(e[t]) | ||
} | ||
const i = n[1] | ||
if ('ident' === i.type && 3 === n.length) | ||
return {type: 'feature', context: 'boolean', feature: i.value} | ||
if (5 === n.length && 'ident' === n[1].type && 'colon' === n[2].type) { | ||
const e = n[3] | ||
if ( | ||
'number' === e.type || | ||
'dimension' === e.type || | ||
'ratio' === e.type || | ||
'ident' === e.type | ||
) { | ||
let t, | ||
r = n[1].value | ||
const i = r.slice(0, 4) | ||
'min-' === i | ||
? ((t = 'min'), (r = r.slice(4))) | ||
: 'max-' === i && ((t = 'max'), (r = r.slice(4))) | ||
const {hasSpaceBefore: a, hasSpaceAfter: d, start: s, end: o, ...l} = e | ||
return {type: 'feature', context: 'value', prefix: t, feature: r, value: l} | ||
const i = n.at(1) | ||
if ('ident' === (null == i ? void 0 : i.type) && 'and' === i.value) { | ||
const i = matchConditionWithoutOr(n, 2) | ||
if (i) return {n: {n: 'query', condition: i.n, type: t.value}, i: i.i} | ||
} | ||
return {errid: 'EXPECT_VALUE', start: e.start, end: e.end} | ||
return {n: {n: 'query', type: t.value}, i: 1} | ||
} | ||
if (n.length >= 5) { | ||
const e = readRange(n) | ||
if (isParserError(e)) | ||
return {errid: 'EXPECT_RANGE', start: t.start, end: n[n.length - 1].end, child: e} | ||
{ | ||
const {feature: t, ...r} = e | ||
return {type: 'feature', context: 'range', feature: t, range: r} | ||
} | ||
} | ||
} | ||
export const matchQueryList = n => { | ||
const t = splitMediaQueryList(n) | ||
if (1 === t.length && 0 === t[0].length) return {n: 'query-list', qs: [{n: 'query', type: 'all'}]} | ||
{ | ||
const n = [] | ||
for (const i of t) { | ||
const t = matchQuery(i) | ||
t && t.i === i.length ? n.push(t.n) : n.push({n: 'query', prefix: 'not', type: 'all'}) | ||
} | ||
return {errid: 'INVALID_FEATURE', start: t.start, end: e[e.length - 1].end} | ||
return {n: 'query-list', qs: n} | ||
} | ||
return {errid: 'EMPTY_FEATURE', start: 0, end: 0} | ||
} | ||
export const readRange = e => { | ||
var t, r, n, i, a, d, s, o | ||
if (e.length < 5) | ||
return { | ||
errid: 'INVALID_RANGE', | ||
start: | ||
null !== (r = null === (t = e.at(0)) || void 0 === t ? void 0 : t.start) && void 0 !== r | ||
? r | ||
: 0, | ||
end: | ||
null !== (i = null === (n = e.at(-1)) || void 0 === n ? void 0 : n.end) && void 0 !== i | ||
? i | ||
: 0 | ||
} | ||
if ('(' !== e[0].type) return {errid: 'EXPECT_LPAREN', start: e[0].start, end: e[0].end} | ||
const l = e[e.length - 1] | ||
if (')' !== l.type) return {errid: 'EXPECT_RPAREN', start: l.start, end: l.end} | ||
const u = {feature: ''}, | ||
p = | ||
'number' === e[1].type || | ||
'dimension' === e[1].type || | ||
'ratio' === e[1].type || | ||
('ident' === e[1].type && 'infinite' === e[1].value) | ||
if ('delim' === e[2].type) { | ||
if (60 === e[2].value) | ||
'delim' !== e[3].type || 61 !== e[3].value || e[3].hasSpaceBefore | ||
? (u[p ? 'leftOp' : 'rightOp'] = '<') | ||
: (u[p ? 'leftOp' : 'rightOp'] = '<=') | ||
else if (62 === e[2].value) | ||
'delim' !== e[3].type || 61 !== e[3].value || e[3].hasSpaceBefore | ||
? (u[p ? 'leftOp' : 'rightOp'] = '>') | ||
: (u[p ? 'leftOp' : 'rightOp'] = '>=') | ||
export const splitMediaQueryList = n => { | ||
const t = [[]], | ||
i = [] | ||
for (const e of n) | ||
if ('comma' === e.type && 0 === i.length) t.push([]) | ||
else { | ||
if (61 !== e[2].value) return {errid: 'INVALID_RANGE', start: e[0].start, end: l.end} | ||
u[p ? 'leftOp' : 'rightOp'] = '=' | ||
switch (e.type) { | ||
case 'function': | ||
case '(': | ||
i.push(')') | ||
break | ||
case '[': | ||
i.push(']') | ||
break | ||
case '{': | ||
i.push('}') | ||
break | ||
case ')': | ||
case ']': | ||
case '}': | ||
i.at(-1) === e.type && i.pop() | ||
break | ||
} | ||
t[t.length - 1].push(e) | ||
} | ||
if (p) u.leftToken = e[1] | ||
else { | ||
if ('ident' !== e[1].type) return {errid: 'INVALID_RANGE', start: e[0].start, end: l.end} | ||
u.feature = e[1].value | ||
} | ||
const t = | ||
2 + | ||
(null !== | ||
(d = null === (a = u[p ? 'leftOp' : 'rightOp']) || void 0 === a ? void 0 : a.length) && | ||
void 0 !== d | ||
? d | ||
: 0), | ||
r = e[t] | ||
if (p) { | ||
if ('ident' !== r.type) return {errid: 'INVALID_RANGE', start: e[0].start, end: l.end} | ||
if (((u.feature = r.value), e.length >= 7)) { | ||
const r = e[t + 1], | ||
n = e[t + 2] | ||
if ('delim' !== r.type) return {errid: 'INVALID_RANGE', start: e[0].start, end: l.end} | ||
{ | ||
const i = r.value | ||
if (60 === i) | ||
'delim' !== n.type || 61 !== n.value || n.hasSpaceBefore | ||
? (u.rightOp = '<') | ||
: (u.rightOp = '<=') | ||
else { | ||
if (62 !== i) return {errid: 'INVALID_RANGE', start: e[0].start, end: l.end} | ||
'delim' !== n.type || 61 !== n.value || n.hasSpaceBefore | ||
? (u.rightOp = '>') | ||
: (u.rightOp = '>=') | ||
} | ||
const a = | ||
t + | ||
1 + | ||
(null !== (o = null === (s = u.rightOp) || void 0 === s ? void 0 : s.length) && | ||
void 0 !== o | ||
? o | ||
: 0), | ||
d = e.at(a) | ||
if (a + 2 !== e.length) return {errid: 'INVALID_RANGE', start: e[0].start, end: l.end} | ||
u.rightToken = d | ||
} | ||
} else if (t + 2 !== e.length) return {errid: 'INVALID_RANGE', start: e[0].start, end: l.end} | ||
} else u.rightToken = r | ||
let n | ||
const {leftToken: i, leftOp: f, feature: c, rightOp: y, rightToken: h} = u | ||
let E, v | ||
if (void 0 !== i) | ||
if ('ident' === i.type) { | ||
const {type: e, value: t} = i | ||
'infinite' === t && (E = {type: e, value: t}) | ||
} else if ('number' === i.type || 'dimension' === i.type || 'ratio' === i.type) { | ||
const {hasSpaceBefore: e, hasSpaceAfter: t, start: r, end: n, ...a} = i | ||
E = a | ||
} | ||
if (void 0 !== h) | ||
if ('ident' === h.type) { | ||
const {type: e, value: t} = h | ||
'infinite' === t && (v = {type: e, value: t}) | ||
} else if ('number' === h.type || 'dimension' === h.type || 'ratio' === h.type) { | ||
const {hasSpaceBefore: e, hasSpaceAfter: t, start: r, end: n, ...i} = h | ||
v = i | ||
} | ||
if (void 0 !== E && void 0 !== v) | ||
if (('<' !== f && '<=' !== f) || ('<' !== y && '<=' !== y)) { | ||
if (('>' !== f && '>=' !== f) || ('>' !== y && '>=' !== y)) | ||
return {errid: 'INVALID_RANGE', start: e[0].start, end: l.end} | ||
n = {leftToken: E, leftOp: f, feature: c, rightOp: y, rightToken: v} | ||
} else n = {leftToken: E, leftOp: f, feature: c, rightOp: y, rightToken: v} | ||
else | ||
((void 0 === E && void 0 === f && void 0 !== y && void 0 !== v) || | ||
(void 0 !== E && void 0 !== f && void 0 === y && void 0 === v)) && | ||
(n = {leftToken: E, leftOp: f, feature: c, rightOp: y, rightToken: v}) | ||
return null != n ? n : {errid: 'INVALID_RANGE', start: e[0].start, end: l.end} | ||
} | ||
return {errid: 'INVALID_RANGE', start: e[0].start, end: l.end} | ||
return t | ||
} |
@@ -1,14 +0,14 @@ | ||
import { MediaQueryList, MediaQuery, MediaCondition, MediaFeature, MediaFeatureBoolean, MediaFeatureValue, MediaFeatureRange, ValidValueToken, ValidRangeToken, RatioToken, NumberToken, DimensionToken, IdentToken } from "../utils.js"; | ||
export declare const generateMediaQueryList: (mediaQueryList: MediaQueryList) => string; | ||
export declare const generateMediaQuery: (mediaQuery: MediaQuery) => string; | ||
export declare const generateMediaCondition: (mediaCondition: MediaCondition) => string; | ||
export declare const generateMediaFeature: (mediaFeature: MediaFeature) => string; | ||
export declare const generateMediaFeatureBoolean: (mediaFeature: MediaFeatureBoolean) => string; | ||
export declare const generateMediaFeatureValue: (mediaFeature: MediaFeatureValue) => string; | ||
export declare const generateMediaFeatureRange: (mediaFeature: MediaFeatureRange) => string; | ||
export declare const generateValidValueToken: (validValueToken: ValidValueToken) => string; | ||
export declare const generateValidRangeToken: (validRangeToken: ValidRangeToken) => string; | ||
export declare const generateRatioToken: (ratioToken: RatioToken) => string; | ||
export declare const generateNumberToken: (numberToken: Omit<NumberToken, "start" | "end">) => string; | ||
export declare const generateDimensionToken: (dimensionToken: Omit<DimensionToken, "start" | "end">) => string; | ||
export declare const generateIdentToken: (identToken: Omit<IdentToken, "start" | "end">) => string; | ||
import { QueryListNode, QueryNode, ConditionNode, FeatureNode, BooleanFeatureNode, PlainFeatureNode, RangeFeatureNode, ValueNode, RatioNode, IdentNode, NumberNode, ConditionWithoutOrNode, InParensNode, DimensionNode } from "../utils.js"; | ||
export declare const generateQueryList: (queryList: QueryListNode) => string; | ||
export declare const generateQuery: (mediaQuery: QueryNode) => string; | ||
export declare const generateInParens: (inParens: InParensNode) => string; | ||
export declare const generateCondition: (condition: ConditionNode | ConditionWithoutOrNode) => string; | ||
export declare const generateFeature: (feature: FeatureNode) => string; | ||
export declare const generateFeatureBoolean: (feature: BooleanFeatureNode) => string; | ||
export declare const generateFeatureValue: (feature: PlainFeatureNode) => string; | ||
export declare const generateFeatureRange: (feature: RangeFeatureNode) => string; | ||
export declare const generateValue: (value: ValueNode) => string; | ||
export declare const generateRatio: (ratio: RatioNode) => string; | ||
export declare const generateNumber: (number: NumberNode) => string; | ||
export declare const generateDimension: (dimension: DimensionNode) => string; | ||
export declare const generateIdent: (ident: IdentNode) => string; |
@@ -1,39 +0,36 @@ | ||
export const generateMediaQueryList = e => e.mediaQueries.map(e => generateMediaQuery(e)).join(', ') | ||
export const generateMediaQuery = e => { | ||
export const generateQueryList = e => e.qs.map(e => generateQuery(e)).join(', ') | ||
export const generateQuery = e => { | ||
var n | ||
let t = '' | ||
e.prefix && (t += e.prefix + ' ') | ||
if ( | ||
((void 0 !== e.prefix || !e.mediaCondition || void 0 !== e.mediaType) && | ||
((t += null !== (n = e.mediaType) && void 0 !== n ? n : 'all'), | ||
e.mediaCondition && (t += ' and')), | ||
e.mediaCondition) | ||
) { | ||
'' !== t && (t += ' ') | ||
t += | ||
'or' !== e.mediaCondition.operator || !t | ||
? generateMediaCondition(e.mediaCondition).slice(1, -1) | ||
: generateMediaCondition(e.mediaCondition) | ||
} | ||
return t | ||
return ( | ||
(void 0 !== e.prefix || !e.condition || void 0 !== e.type) && | ||
((t += null !== (n = e.type) && void 0 !== n ? n : 'all'), e.condition && (t += ' and')), | ||
e.condition && ('' !== t && (t += ' '), (t += generateCondition(e.condition))), | ||
t | ||
) | ||
} | ||
export const generateMediaCondition = e => { | ||
let n = '(' | ||
if ('not' === e.operator) { | ||
const t = e.children[0] | ||
n += 'not ' + ('feature' === t.type ? generateMediaFeature(t) : generateMediaCondition(t)) | ||
} else | ||
for (const t of e.children) | ||
n.length > 1 && (n += ' ' + e.operator + ' '), | ||
(n += 'feature' === t.type ? generateMediaFeature(t) : generateMediaCondition(t)) | ||
return (n += ')'), n | ||
export const generateInParens = e => | ||
'condition' === e.v.n | ||
? '(' + generateCondition(e.v) + ')' | ||
: 'feature' === e.v.n | ||
? generateFeature(e.v) | ||
: '(general enclosed)' | ||
export const generateCondition = e => { | ||
var n | ||
return 'not' === e.op | ||
? 'not ' + generateInParens(e.a) | ||
: generateInParens(e.a) + | ||
(null !== (n = e.bs) && void 0 !== n ? n : []) | ||
.map(n => ` ${e.op} ${generateInParens(n)}`) | ||
.join('') | ||
} | ||
export const generateMediaFeature = e => { | ||
export const generateFeature = e => { | ||
let n = '(' | ||
return ( | ||
'boolean' === e.context | ||
? (n += generateMediaFeatureBoolean(e)) | ||
: 'value' === e.context | ||
? (n += generateMediaFeatureValue(e)) | ||
: (n += generateMediaFeatureRange(e)), | ||
'boolean' === e.t | ||
? (n += generateFeatureBoolean(e)) | ||
: 'value' === e.t | ||
? (n += generateFeatureValue(e)) | ||
: (n += generateFeatureRange(e)), | ||
(n += ')'), | ||
@@ -43,26 +40,19 @@ n | ||
} | ||
export const generateMediaFeatureBoolean = e => e.feature | ||
export const generateMediaFeatureValue = e => | ||
(e.prefix ? `${e.prefix}-` : '') + e.feature + ': ' + generateValidValueToken(e.value) | ||
export const generateMediaFeatureRange = e => { | ||
let n = '' | ||
return ( | ||
e.range.leftOp && (n += `${generateValidRangeToken(e.range.leftToken)} ${e.range.leftOp} `), | ||
(n += e.feature), | ||
e.range.rightOp && (n += ` ${e.range.rightOp} ${generateValidRangeToken(e.range.rightToken)}`), | ||
n | ||
) | ||
export const generateFeatureBoolean = e => e.f | ||
export const generateFeatureValue = e => e.f + ': ' + generateValue(e.v) | ||
export const generateFeatureRange = e => { | ||
let n = `${generateValue(e.r.a)} ${e.r.op} ${generateValue(e.r.b)}` | ||
return 'op2' in e.r && (n += ` ${e.r.op2} ${generateValue(e.r.c)}`), n | ||
} | ||
export const generateValidValueToken = e => | ||
'dimension' === e.type | ||
? generateDimensionToken(e) | ||
: 'ident' === e.type | ||
? generateIdentToken(e) | ||
: 'ratio' === e.type | ||
? generateRatioToken(e) | ||
: generateNumberToken(e) | ||
export const generateValidRangeToken = e => generateValidValueToken(e) | ||
export const generateRatioToken = e => `${e.numerator}/${e.denominator}` | ||
export const generateNumberToken = e => `${e.value}` | ||
export const generateDimensionToken = e => `${e.value}${e.unit}` | ||
export const generateIdentToken = e => e.value | ||
export const generateValue = e => | ||
'dimension' === e.n | ||
? generateDimension(e) | ||
: 'ident' === e.n | ||
? generateIdent(e) | ||
: 'ratio' === e.n | ||
? generateRatio(e) | ||
: generateNumber(e) | ||
export const generateRatio = e => `${e.l}/${e.r}` | ||
export const generateNumber = e => `${e.v}` | ||
export const generateDimension = e => `${e.v}${e.u}` | ||
export const generateIdent = e => e.v |
/**! media-query-parser | Tom Golden <oss@tom.bio> (https://tom.bio) | @license MIT */ | ||
import { MediaQueryList, ParserError, MediaQuery, MediaCondition, MediaFeature, ValidValueToken } from "./utils.js"; | ||
import { ConditionNode, FeatureNode, ParserError, QueryListNode, QueryNode, ValueNode } from "./utils.js"; | ||
/** | ||
@@ -24,3 +24,3 @@ * creates an AST from a **media-query-list** string; parses comma-separated media queries correctly | ||
*/ | ||
export declare const parseMediaQueryList: (str: string) => MediaQueryList | ParserError; | ||
export declare const parseMediaQueryList: (str: string) => QueryListNode | ParserError; | ||
/** | ||
@@ -40,3 +40,3 @@ * creates an AST from a **media-query** string | ||
*/ | ||
export declare const parseMediaQuery: (str: string) => MediaQuery | ParserError; | ||
export declare const parseMediaQuery: (str: string) => QueryNode | ParserError; | ||
/** | ||
@@ -71,3 +71,3 @@ * creates an AST from a **media-condition** string | ||
*/ | ||
export declare const parseMediaCondition: (str: string) => MediaCondition | ParserError; | ||
export declare const parseMediaCondition: (str: string) => ConditionNode | ParserError; | ||
/** | ||
@@ -89,3 +89,3 @@ * creates an AST from a **media-feature** string - including parentheses | ||
*/ | ||
export declare const parseMediaFeature: (str: string) => MediaFeature | ParserError; | ||
export declare const parseMediaFeature: (str: string) => FeatureNode | ParserError; | ||
/** | ||
@@ -116,3 +116,3 @@ * turns an AST into an equivalent string | ||
*/ | ||
export declare const stringify: (node: MediaQueryList | MediaQuery | MediaCondition | MediaFeature | ValidValueToken) => string; | ||
export declare const stringify: (node: QueryListNode | QueryNode | ConditionNode | FeatureNode | ValueNode) => string; | ||
export * from "./utils.js"; |
/**! media-query-parser | Tom Golden <oss@tom.bio> (https://tom.bio) | @license MIT */ | ||
import { | ||
readMediaQueryList as r, | ||
readMediaQuery as t, | ||
readMediaCondition as e, | ||
readMediaFeature as o | ||
matchCondition as r, | ||
matchFeature as t, | ||
matchQuery as e, | ||
matchQueryList as n | ||
} from './ast/ast.js' | ||
import { | ||
flattenMediaQueryList as s, | ||
flattenMediaQuery as n, | ||
flattenMediaCondition as i | ||
} from './flatten/flatten.js' | ||
import { | ||
generateMediaQueryList as a, | ||
generateMediaQuery as u, | ||
generateMediaCondition as c, | ||
generateMediaFeature as p, | ||
generateValidValueToken as f | ||
generateQueryList as o, | ||
generateQuery as i, | ||
generateCondition as s, | ||
generateFeature as a, | ||
generateValue as d | ||
} from './generator/generator.js' | ||
import {deleteUndefinedValues as m, invertParserError as l} from './internals.js' | ||
import {lexer as x} from './lexer/lexer.js' | ||
import {isParserError as d} from './utils.js' | ||
export const parseMediaQueryList = t => { | ||
const e = x(t) | ||
return d(e) ? l(e) : m(s(r(e))) | ||
import {lexer as l} from './lexer/lexer.js' | ||
import {isParserError as u} from './utils.js' | ||
export const parseMediaQueryList = r => { | ||
const t = l(r) | ||
return u(t) ? t : n(t) | ||
} | ||
export const parseMediaQuery = r => { | ||
const e = x(r) | ||
if (d(e)) return l(e) | ||
var t, n, o, i | ||
const s = l(r) | ||
if (u(s)) return s | ||
{ | ||
const r = t(e) | ||
return d(r) ? l(r) : m(n(r)) | ||
const r = e(s) | ||
return r && r.i === s.length | ||
? r.n | ||
: { | ||
errid: 'INVALID_QUERY', | ||
start: | ||
null !== (n = null === (t = s.at(0)) || void 0 === t ? void 0 : t.start) && void 0 !== n | ||
? n | ||
: 0, | ||
end: | ||
null !== (i = null === (o = s.at(-1)) || void 0 === o ? void 0 : o.end) && void 0 !== i | ||
? i | ||
: 0 | ||
} | ||
} | ||
} | ||
export const parseMediaCondition = r => { | ||
const t = x(r) | ||
if (d(t)) return l(t) | ||
export const parseMediaCondition = t => { | ||
var e, n, o, i | ||
const s = l(t) | ||
if (u(s)) return s | ||
{ | ||
const r = e(t, !0) | ||
return d(r) ? l(r) : m(i(r)) | ||
const t = r(s) | ||
return t && t.i === s.length | ||
? t.n | ||
: { | ||
errid: 'INVALID_CONDITION', | ||
start: | ||
null !== (n = null === (e = s.at(0)) || void 0 === e ? void 0 : e.start) && void 0 !== n | ||
? n | ||
: 0, | ||
end: | ||
null !== (i = null === (o = s.at(-1)) || void 0 === o ? void 0 : o.end) && void 0 !== i | ||
? i | ||
: 0 | ||
} | ||
} | ||
} | ||
export const parseMediaFeature = r => { | ||
const t = x(r) | ||
if (d(t)) return l(t) | ||
var e, n, o, i | ||
const s = l(r) | ||
if (u(s)) return s | ||
{ | ||
const r = o(t) | ||
return d(r) ? r : m(r) | ||
const r = t(s) | ||
return r && r.i === s.length | ||
? r.n | ||
: { | ||
errid: 'INVALID_FEATURE', | ||
start: | ||
null !== (n = null === (e = s.at(0)) || void 0 === e ? void 0 : e.start) && void 0 !== n | ||
? n | ||
: 0, | ||
end: | ||
null !== (i = null === (o = s.at(-1)) || void 0 === o ? void 0 : o.end) && void 0 !== i | ||
? i | ||
: 0 | ||
} | ||
} | ||
} | ||
export const stringify = r => { | ||
switch (r.type) { | ||
switch (r.n) { | ||
case 'query-list': | ||
return a(r) | ||
return o(r) | ||
case 'query': | ||
return u(r) | ||
return i(r) | ||
case 'condition': | ||
return c(r) | ||
return s(r) | ||
case 'feature': | ||
return p(r) | ||
return a(r) | ||
default: | ||
return f(r) | ||
return d(r) | ||
} | ||
} | ||
export * from './utils.js' |
@@ -1,3 +0,3 @@ | ||
import { MediaCondition, MediaFeature, MediaQuery, MediaQueryList, ParserError, ValidValueToken } from "./utils.js"; | ||
export declare const invertParserError: (parserError: ParserError) => ParserError; | ||
export declare const deleteUndefinedValues: <T extends MediaQuery | MediaQueryList | MediaCondition | MediaFeature | ValidValueToken>(n: T) => T; | ||
export type Simplify<T> = { | ||
[KeyType in keyof T]: T[KeyType]; | ||
} & {}; |
@@ -1,43 +0,1 @@ | ||
export const invertParserError = e => { | ||
const t = [e] | ||
for (let d = e.child; void 0 !== d; d = d.child) t.push(d) | ||
for (let e = t.length - 2; e >= 0; e--) t[e + 1].child = t.at(e) | ||
return delete t[0].child, t.at(-1) | ||
} | ||
export const deleteUndefinedValues = e => { | ||
switch (e.type) { | ||
case 'query-list': | ||
for (const t of e.mediaQueries) deleteUndefinedValues(t) | ||
return e | ||
case 'query': | ||
return ( | ||
void 0 === e.prefix && delete e.prefix, | ||
void 0 === e.mediaType && delete e.mediaType, | ||
void 0 === e.mediaCondition | ||
? delete e.mediaCondition | ||
: deleteUndefinedValues(e.mediaCondition), | ||
e | ||
) | ||
case 'condition': | ||
void 0 === e.operator && delete e.operator | ||
for (const t of e.children) deleteUndefinedValues(t) | ||
return e | ||
case 'feature': | ||
return ( | ||
'value' === e.context | ||
? (void 0 === e.prefix && delete e.prefix, deleteUndefinedValues(e.value)) | ||
: 'range' === e.context && | ||
(void 0 === e.range.leftOp && delete e.range.leftOp, | ||
void 0 === e.range.rightOp && delete e.range.rightOp, | ||
void 0 === e.range.leftToken | ||
? delete e.range.leftToken | ||
: deleteUndefinedValues(e.range.leftToken), | ||
void 0 === e.range.rightToken | ||
? delete e.range.rightToken | ||
: deleteUndefinedValues(e.range.rightToken)), | ||
e | ||
) | ||
default: | ||
return e | ||
} | ||
} | ||
export {} |
@@ -1,2 +0,2 @@ | ||
import {isParserError as o} from '../ast/ast.js' | ||
import {isParserError as o} from '../utils.js' | ||
import {readCodepoints as r} from './codepoints.js' | ||
@@ -3,0 +3,0 @@ import {convertToParserTokens as s} from './process.js' |
@@ -1,2 +0,2 @@ | ||
import { CSSToken, ParserToken, ParserError } from "../utils.js"; | ||
export declare const convertToParserTokens: (cssTokens: CSSToken[]) => ParserToken[] | ParserError; | ||
import { LexerToken, ParserToken, ParserError } from "../utils.js"; | ||
export declare const convertToParserTokens: (cssTokens: LexerToken[]) => ParserToken[] | ParserError; |
export const convertToParserTokens = e => { | ||
const t = [] | ||
let r = !1 | ||
const r = [] | ||
let t = !1 | ||
for (const s of e) | ||
@@ -11,3 +11,3 @@ switch (s.type) { | ||
case 'whitespace': | ||
;(r = !0), t.length > 0 && (t[t.length - 1].hasSpaceAfter = !0) | ||
t = !0 | ||
break | ||
@@ -17,5 +17,5 @@ case 'EOF': | ||
default: | ||
t.push({...s, hasSpaceBefore: r, hasSpaceAfter: !1}), (r = !1) | ||
r.push({...s, isAfterSpace: t}), (t = !1) | ||
} | ||
return t | ||
return r | ||
} |
@@ -1,3 +0,3 @@ | ||
import { CSSToken, ParserError } from "../utils.js"; | ||
export declare const codepointsToTokens: (codepoints: number[], index?: number) => CSSToken[] | ParserError; | ||
import { LexerToken, ParserError } from "../utils.js"; | ||
export declare const codepointsToTokens: (codepoints: number[], index?: number) => LexerToken[] | ParserError; | ||
export declare const consumeString: (codepoints: number[], index: number) => [number, string] | null; | ||
@@ -4,0 +4,0 @@ export declare const wouldStartIdentifier: (codepoints: number[], index: number) => boolean; |
@@ -1,10 +0,7 @@ | ||
type Simplify<T> = { | ||
[KeyType in keyof T]: T[KeyType]; | ||
} & {}; | ||
import { Simplify } from "./internals.js"; | ||
type GenericToken = { | ||
type: string; | ||
start: number; | ||
end: number; | ||
}; | ||
export type CSSToken = WhitespaceToken | StringToken | HashToken | DelimToken | CommaToken | LeftParenToken | RightParenToken | DimensionToken | NumberToken | PercentageToken | IdentToken | FunctionToken | UrlToken | CDCToken | ColonToken | SemicolonToken | CDOToken | AtKeywordToken | LeftBracketToken | RightBracketToken | LeftCurlyToken | RightCurlyToken | EOFToken; | ||
export type LexerToken = WhitespaceToken | StringToken | HashToken | DelimToken | CommaToken | LeftParenToken | RightParenToken | DimensionToken | NumberToken | PercentageToken | IdentToken | FunctionToken | UrlToken | CDCToken | ColonToken | SemicolonToken | CDOToken | AtKeywordToken | LeftBracketToken | RightBracketToken | LeftCurlyToken | RightCurlyToken | EOFToken; | ||
export type WhitespaceToken = Simplify<GenericToken & { | ||
@@ -94,85 +91,120 @@ type: "whitespace"; | ||
}>; | ||
export type ParserToken = Simplify<Exclude<CSSToken, EOFToken> & { | ||
hasSpaceBefore: boolean; | ||
hasSpaceAfter: boolean; | ||
export type ParserToken = Simplify<Exclude<LexerToken, WhitespaceToken | EOFToken> & { | ||
isAfterSpace: boolean; | ||
}>; | ||
export type ParserErrId = "EXPECT_LPAREN_OR_TYPE" | "EXPECT_TYPE" | "EXPECT_CONDITION" | "EXPECT_AND" | "EXPECT_LPAREN_OR_TYPE_OR_MODIFIER" | "EXPECT_LPAREN" | "EXPECT_FEATURE_OR_CONDITION" | "EXPECT_AND_OR_OR" | "EXPECT_RPAREN" | "EXPECT_VALUE" | "EXPECT_RANGE" | "MIX_AND_WITH_OR" | "MISMATCH_PARENS" | "EMPTY_QUERY" | "EMPTY_CONDITION" | "EMPTY_FEATURE" | "NO_LCURLY" | "NO_SEMICOLON" | "INVALID_FEATURE" | "INVALID_RANGE" | "INVALID_STRING"; | ||
export type ParserError = { | ||
errid: ParserErrId; | ||
start: number; | ||
end: number; | ||
child?: ParserError; | ||
export type QueryListNode = { | ||
n: "query-list"; | ||
qs: QueryNode[]; | ||
}; | ||
export type MediaQueryList = { | ||
type: "query-list"; | ||
mediaQueries: MediaQuery[]; | ||
}; | ||
export type MediaQuery = { | ||
type: "query"; | ||
export type QueryNode = { | ||
n: "query"; | ||
prefix?: undefined; | ||
type?: undefined; | ||
condition: ConditionNode; | ||
} | { | ||
n: "query"; | ||
prefix?: "not" | "only"; | ||
mediaType?: "screen" | "print"; | ||
mediaCondition?: MediaCondition; | ||
type: string; | ||
condition?: ConditionWithoutOrNode; | ||
}; | ||
export type MediaCondition = { | ||
type: "condition"; | ||
operator?: "not"; | ||
children: [child: MediaCondition | MediaFeature]; | ||
} | { | ||
type: "condition"; | ||
operator: "and" | "or"; | ||
children: [ | ||
child1: MediaCondition | MediaFeature, | ||
child2: MediaCondition | MediaFeature, | ||
...rest: Array<MediaCondition | MediaFeature> | ||
]; | ||
export type FeatureNode = BooleanFeatureNode | PlainFeatureNode | RangeFeatureNode; | ||
export type BooleanFeatureNode = { | ||
n: "feature"; | ||
t: "boolean"; | ||
f: string; | ||
}; | ||
export type MediaFeature = Simplify<{ | ||
type: "feature"; | ||
} & (MediaFeatureBoolean | MediaFeatureValue | MediaFeatureRange)>; | ||
export type MediaFeatureBoolean = { | ||
context: "boolean"; | ||
feature: string; | ||
export type PlainFeatureNode = { | ||
n: "feature"; | ||
t: "value"; | ||
f: string; | ||
v: ValueNode; | ||
}; | ||
export type MediaFeatureValue = { | ||
context: "value"; | ||
prefix?: "min" | "max"; | ||
feature: string; | ||
value: ValidValueToken; | ||
export type RangeFeatureNode = { | ||
n: "feature"; | ||
t: "range"; | ||
f: string; | ||
r: RangeNode; | ||
}; | ||
export type MediaFeatureRange = { | ||
context: "range"; | ||
feature: string; | ||
range: ValidRange; | ||
export type NumberNode = { | ||
n: "number"; | ||
v: number; | ||
isInt: boolean; | ||
}; | ||
export type ValidValueToken = Simplify<Omit<NumberToken, "start" | "end"> | Omit<DimensionToken, "start" | "end"> | Omit<RatioToken, "start" | "end"> | Omit<IdentToken, "start" | "end">>; | ||
export type ValidRange = { | ||
leftToken: ValidRangeToken; | ||
leftOp: "<" | "<="; | ||
rightOp: "<" | "<="; | ||
rightToken: ValidRangeToken; | ||
export type DimensionNode = { | ||
n: "dimension"; | ||
v: number; | ||
u: string; | ||
}; | ||
export type RatioNode = { | ||
n: "ratio"; | ||
l: number; | ||
r: number; | ||
}; | ||
export type IdentNode = { | ||
n: "ident"; | ||
v: string; | ||
}; | ||
export type NumericValueNode = NumberNode | DimensionNode | RatioNode; | ||
export type ValueNode = NumericValueNode | IdentNode; | ||
export type Range1Node = { | ||
a: IdentNode; | ||
op: ">" | ">=" | "<" | "<=" | "="; | ||
b: NumericValueNode; | ||
} | { | ||
leftToken: ValidRangeToken; | ||
leftOp: ">" | ">="; | ||
rightOp: ">" | ">="; | ||
rightToken: ValidRangeToken; | ||
a: NumericValueNode; | ||
op: ">" | ">=" | "<" | "<=" | "="; | ||
b: IdentNode; | ||
}; | ||
export type Range2Node = { | ||
a: NumericValueNode; | ||
op: "<" | "<="; | ||
b: IdentNode; | ||
op2: "<" | "<="; | ||
c: NumericValueNode; | ||
} | { | ||
leftToken: ValidRangeToken; | ||
leftOp: ">" | ">=" | "<" | "<=" | "="; | ||
rightOp?: undefined; | ||
rightToken?: undefined; | ||
} | { | ||
leftToken?: undefined; | ||
leftOp?: undefined; | ||
rightOp: ">" | ">=" | "<" | "<=" | "="; | ||
rightToken: ValidRangeToken; | ||
a: NumericValueNode; | ||
op: ">" | ">="; | ||
b: IdentNode; | ||
op2: ">" | ">="; | ||
c: NumericValueNode; | ||
}; | ||
export type RatioToken = { | ||
type: "ratio"; | ||
numerator: number; | ||
denominator: number; | ||
export type RangeNode = Simplify<Range1Node | Range2Node>; | ||
export type NotConditionNode = { | ||
n: "condition"; | ||
op: "not"; | ||
a: InParensNode; | ||
bs?: undefined; | ||
}; | ||
export type ValidRangeToken = Simplify<Omit<NumberToken, "start" | "end"> | Omit<DimensionToken, "start" | "end"> | Omit<RatioToken, "start" | "end"> | { | ||
type: "ident"; | ||
value: "infinite"; | ||
}>; | ||
export type AndConditionNode = { | ||
n: "condition"; | ||
op: "and"; | ||
a: InParensNode; | ||
bs?: InParensNode[]; | ||
}; | ||
export type OrConditionNode = { | ||
n: "condition"; | ||
op: "or"; | ||
a: InParensNode; | ||
bs?: InParensNode[]; | ||
}; | ||
export type ConditionNode = Simplify<NotConditionNode | AndConditionNode | OrConditionNode>; | ||
export type ConditionWithoutOrNode = Simplify<NotConditionNode | AndConditionNode>; | ||
export type GeneralEnclosedNode = { | ||
n: "general-enclosed"; | ||
}; | ||
export type InParensNode = { | ||
n: "in-parens"; | ||
v: ConditionNode | FeatureNode | GeneralEnclosedNode; | ||
}; | ||
export type Match<T> = { | ||
n: T; | ||
i: number; | ||
} | undefined; | ||
export type ParserErrId = "INVALID_QUERY" | "INVALID_CONDITION" | "INVALID_FEATURE" | "INVALID_STRING" | "NO_LCURLY" | "NO_SEMICOLON"; | ||
export type ParserError = { | ||
errid: ParserErrId; | ||
start: number; | ||
end: number; | ||
child?: ParserError; | ||
}; | ||
/** | ||
@@ -179,0 +211,0 @@ * a type guard that asserts whether `value` is of type ParserError |
{ | ||
"name": "media-query-parser", | ||
"description": "Parse CSS media queries (spec-compliant)", | ||
"version": "3.0.0-beta.1", | ||
"version": "3.0.0-beta.2", | ||
"license": "MIT", | ||
@@ -50,3 +50,3 @@ "keywords": [ | ||
"lint-time": "^0.1.1", | ||
"msg-time": "^0.1.0", | ||
"msg-time": "^0.1.1", | ||
"prettier": "2.8.8", | ||
@@ -53,0 +53,0 @@ "pub-time": "^0.1.0", |
46166
21
1319