@react-x11/components 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/html/controls.d.ts +41 -5
- package/dist/html/controls.d.ts.map +1 -1
- package/dist/html/controls.js +85 -57
- package/dist/html/controls.js.map +1 -1
- package/dist/html/css/cascade.d.ts +134 -20
- package/dist/html/css/cascade.d.ts.map +1 -1
- package/dist/html/css/cascade.js +545 -126
- package/dist/html/css/cascade.js.map +1 -1
- package/dist/html/css/color.d.ts +18 -0
- package/dist/html/css/color.d.ts.map +1 -1
- package/dist/html/css/color.js +27 -0
- package/dist/html/css/color.js.map +1 -1
- package/dist/html/css/parse.d.ts +47 -6
- package/dist/html/css/parse.d.ts.map +1 -1
- package/dist/html/css/parse.js +336 -30
- package/dist/html/css/parse.js.map +1 -1
- package/dist/html/css/style.d.ts +142 -15
- package/dist/html/css/style.d.ts.map +1 -1
- package/dist/html/css/style.js +563 -147
- package/dist/html/css/style.js.map +1 -1
- package/dist/html/css/transform.d.ts +85 -0
- package/dist/html/css/transform.d.ts.map +1 -0
- package/dist/html/css/transform.js +425 -0
- package/dist/html/css/transform.js.map +1 -0
- package/dist/html/css/ua.d.ts +11 -1
- package/dist/html/css/ua.d.ts.map +1 -1
- package/dist/html/css/ua.js +73 -9
- package/dist/html/css/ua.js.map +1 -1
- package/dist/html/css/values.d.ts +4 -0
- package/dist/html/css/values.d.ts.map +1 -1
- package/dist/html/css/values.js.map +1 -1
- package/dist/html/dom.d.ts.map +1 -1
- package/dist/html/dom.js +3 -1
- package/dist/html/dom.js.map +1 -1
- package/dist/html/fonts.d.ts +78 -4
- package/dist/html/fonts.d.ts.map +1 -1
- package/dist/html/fonts.js +373 -19
- package/dist/html/fonts.js.map +1 -1
- package/dist/html/form.d.ts +200 -0
- package/dist/html/form.d.ts.map +1 -0
- package/dist/html/form.js +801 -0
- package/dist/html/form.js.map +1 -0
- package/dist/html/index.d.ts +12 -0
- package/dist/html/index.d.ts.map +1 -1
- package/dist/html/index.js +30 -301
- package/dist/html/index.js.map +1 -1
- package/dist/html/layout/axes.d.ts +14 -0
- package/dist/html/layout/axes.d.ts.map +1 -0
- package/dist/html/layout/axes.js +28 -0
- package/dist/html/layout/axes.js.map +1 -0
- package/dist/html/layout/block.d.ts +93 -12
- package/dist/html/layout/block.d.ts.map +1 -1
- package/dist/html/layout/block.js +393 -39
- package/dist/html/layout/block.js.map +1 -1
- package/dist/html/layout/boxes.d.ts +90 -2
- package/dist/html/layout/boxes.d.ts.map +1 -1
- package/dist/html/layout/boxes.js +74 -10
- package/dist/html/layout/boxes.js.map +1 -1
- package/dist/html/layout/cache.d.ts +1 -1
- package/dist/html/layout/cache.d.ts.map +1 -1
- package/dist/html/layout/cache.js +6 -0
- package/dist/html/layout/cache.js.map +1 -1
- package/dist/html/layout/css-grid.d.ts.map +1 -1
- package/dist/html/layout/css-grid.js +90 -18
- package/dist/html/layout/css-grid.js.map +1 -1
- package/dist/html/layout/flex.d.ts.map +1 -1
- package/dist/html/layout/flex.js +574 -84
- package/dist/html/layout/flex.js.map +1 -1
- package/dist/html/layout/inline.d.ts +3 -0
- package/dist/html/layout/inline.d.ts.map +1 -1
- package/dist/html/layout/inline.js +154 -54
- package/dist/html/layout/inline.js.map +1 -1
- package/dist/html/layout/multicol.d.ts +42 -0
- package/dist/html/layout/multicol.d.ts.map +1 -0
- package/dist/html/layout/multicol.js +897 -0
- package/dist/html/layout/multicol.js.map +1 -0
- package/dist/html/layout/shaping.d.ts +7 -0
- package/dist/html/layout/shaping.d.ts.map +1 -1
- package/dist/html/layout/shaping.js +25 -20
- package/dist/html/layout/shaping.js.map +1 -1
- package/dist/html/layout/table.d.ts.map +1 -1
- package/dist/html/layout/table.js +62 -18
- package/dist/html/layout/table.js.map +1 -1
- package/dist/html/node.d.ts +90 -15
- package/dist/html/node.d.ts.map +1 -1
- package/dist/html/node.js +771 -186
- package/dist/html/node.js.map +1 -1
- package/dist/html/paint.d.ts +101 -5
- package/dist/html/paint.d.ts.map +1 -1
- package/dist/html/paint.js +1502 -160
- package/dist/html/paint.js.map +1 -1
- package/dist/html/svg.d.ts +15 -2
- package/dist/html/svg.d.ts.map +1 -1
- package/dist/html/svg.js +249 -17
- package/dist/html/svg.js.map +1 -1
- package/dist/html/widgets.d.ts +29 -0
- package/dist/html/widgets.d.ts.map +1 -0
- package/dist/html/widgets.js +700 -0
- package/dist/html/widgets.js.map +1 -0
- package/dist/html/woff2.d.ts +14 -0
- package/dist/html/woff2.d.ts.map +1 -0
- package/dist/html/woff2.js +608 -0
- package/dist/html/woff2.js.map +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/maps/controller.d.ts +17 -1
- package/dist/maps/controller.d.ts.map +1 -1
- package/dist/maps/controller.js +27 -7
- package/dist/maps/controller.js.map +1 -1
- package/dist/richtext/node.d.ts +8 -1
- package/dist/richtext/node.d.ts.map +1 -1
- package/dist/richtext/node.js +5 -1
- package/dist/richtext/node.js.map +1 -1
- package/dist/richtext/runs.d.ts +25 -6
- package/dist/richtext/runs.d.ts.map +1 -1
- package/dist/richtext/runs.js +240 -24
- package/dist/richtext/runs.js.map +1 -1
- package/package.json +2 -2
- package/src/html/controls.ts +114 -51
- package/src/html/css/cascade.ts +614 -140
- package/src/html/css/color.ts +29 -0
- package/src/html/css/parse.ts +388 -33
- package/src/html/css/style.ts +688 -150
- package/src/html/css/transform.ts +459 -0
- package/src/html/css/ua.ts +77 -10
- package/src/html/css/values.ts +4 -0
- package/src/html/dom.ts +3 -1
- package/src/html/fonts.ts +417 -24
- package/src/html/form.ts +962 -0
- package/src/html/index.ts +49 -338
- package/src/html/layout/axes.ts +62 -0
- package/src/html/layout/block.ts +447 -37
- package/src/html/layout/boxes.ts +143 -14
- package/src/html/layout/cache.ts +6 -0
- package/src/html/layout/css-grid.ts +95 -22
- package/src/html/layout/flex.ts +675 -78
- package/src/html/layout/inline.ts +159 -55
- package/src/html/layout/multicol.ts +977 -0
- package/src/html/layout/shaping.ts +27 -18
- package/src/html/layout/table.ts +62 -19
- package/src/html/node.ts +798 -172
- package/src/html/paint.ts +1742 -241
- package/src/html/svg.ts +277 -19
- package/src/html/widgets.ts +821 -0
- package/src/html/woff2.ts +612 -0
- package/src/index.ts +1 -0
- package/src/maps/controller.ts +28 -7
- package/src/richtext/node.ts +13 -2
- package/src/richtext/runs.ts +313 -35
package/dist/html/css/parse.d.ts
CHANGED
|
@@ -34,10 +34,22 @@ export interface Stylesheet {
|
|
|
34
34
|
* resource seam and splices the result in ahead of this sheet. Absolute
|
|
35
35
|
* when the sheet was parsed with a base. */
|
|
36
36
|
imports: string[];
|
|
37
|
+
/** Each import's media query list, where it has one: the condition the
|
|
38
|
+
* sheet it brings in is under, as though an `@media` block were around
|
|
39
|
+
* all of it (CSS Cascade 4, 2). Null for an import with none. */
|
|
40
|
+
importConditions: (MediaCondition[] | null)[];
|
|
37
41
|
/** Every width a `@media` rule in this sheet switches on. The renderer
|
|
38
42
|
* keeps these so a resize can tell "the layout changed" from "the
|
|
39
43
|
* *cascade* changed", and restyle only when it crossed one. */
|
|
40
44
|
breakpoints: number[];
|
|
45
|
+
/** Whether a `@media` rule in this sheet tests the viewport's height,
|
|
46
|
+
* which makes a document restyle when the height moves, as a `vh`
|
|
47
|
+
* does. */
|
|
48
|
+
readsHeight?: boolean;
|
|
49
|
+
/** Whether one tests its aspect ratio, which a width that crosses no
|
|
50
|
+
* breakpoint can change: the document restyles as one with a `vw`
|
|
51
|
+
* does. */
|
|
52
|
+
readsWidth?: boolean;
|
|
41
53
|
/** The `@font-face` rules, in order (see `fonts.ts`). */
|
|
42
54
|
fontFaces: FontFaceRule[];
|
|
43
55
|
/** `@counter-style` rules, in order: a name and its descriptors, which
|
|
@@ -56,8 +68,9 @@ export interface Stylesheet {
|
|
|
56
68
|
export interface FontFaceRule {
|
|
57
69
|
/** The family as the document names it, unquoted. */
|
|
58
70
|
family: string;
|
|
59
|
-
/** The
|
|
60
|
-
*
|
|
71
|
+
/** The entries of `src`, in order, which is the order they are tried in:
|
|
72
|
+
* a `url()` with its `format()` hint lowercased, or the name a `local()`
|
|
73
|
+
* asks the system for. */
|
|
61
74
|
sources: FontFaceSource[];
|
|
62
75
|
/** The weights the face covers: `[400, 400]` for a static regular, a
|
|
63
76
|
* range for a variable face. */
|
|
@@ -68,16 +81,34 @@ export interface FontFaceRule {
|
|
|
68
81
|
/** The `@media` blocks the rule sits under, as a style rule's. */
|
|
69
82
|
media: MediaCondition[][] | null;
|
|
70
83
|
}
|
|
71
|
-
export
|
|
84
|
+
export type FontFaceSource = {
|
|
72
85
|
url: string;
|
|
73
86
|
format: string | null;
|
|
74
87
|
}
|
|
75
|
-
/**
|
|
88
|
+
/** `local(Arial)`: a face the system has, by name and unquoted. */
|
|
89
|
+
| {
|
|
90
|
+
local: string;
|
|
91
|
+
};
|
|
92
|
+
/** The tests this evaluates live: a width, a height, a colour scheme.
|
|
76
93
|
* Anything else — `orientation`, `print`, `prefers-reduced-motion` — is
|
|
77
94
|
* decided once, at parse time, by `staticPass`. */
|
|
78
95
|
export interface MediaCondition {
|
|
79
96
|
min?: number;
|
|
80
97
|
max?: number;
|
|
98
|
+
/** The viewport's height, as `min`/`max` its width: `min-height`,
|
|
99
|
+
* `max-height` and a range on `height` (Media Queries 4, 4.2). */
|
|
100
|
+
minHeight?: number;
|
|
101
|
+
maxHeight?: number;
|
|
102
|
+
/** The display's resolution in dots per CSS pixel, its scale: `min-`
|
|
103
|
+
* and `max-resolution`, and WebKit's `-webkit-min-device-pixel-ratio`,
|
|
104
|
+
* which a design writes to swap in its high-DPI images. */
|
|
105
|
+
minResolution?: number;
|
|
106
|
+
maxResolution?: number;
|
|
107
|
+
/** The viewport's width over its height: `aspect-ratio` and its `min-`
|
|
108
|
+
* and `max-`, the device's the viewport's too, and `orientation`, which
|
|
109
|
+
* is landscape where the width is the greater. */
|
|
110
|
+
minAspect?: number;
|
|
111
|
+
maxAspect?: number;
|
|
81
112
|
/** `prefers-color-scheme`, answered from the palette in force. */
|
|
82
113
|
scheme?: 'light' | 'dark';
|
|
83
114
|
/** Set when the query could not be evaluated as a width or scheme test:
|
|
@@ -106,7 +137,12 @@ layers?: Map<string, number>,
|
|
|
106
137
|
/** The URL the sheet's own relative URLs resolve against — its own, or
|
|
107
138
|
* the document's for a `<style>` — or null to leave them as written.
|
|
108
139
|
* Every `url()`, `@import` and `@font-face` source comes out absolute. */
|
|
109
|
-
base?: string | null
|
|
140
|
+
base?: string | null,
|
|
141
|
+
/** The media queries the whole sheet is under, outermost first: the ones
|
|
142
|
+
* of the `@import` that brought it in, and of the imports that brought
|
|
143
|
+
* that sheet in. Every rule and face in it is under them, as one inside
|
|
144
|
+
* an `@media` block is under the block's. */
|
|
145
|
+
under?: MediaCondition[][] | null): Stylesheet;
|
|
110
146
|
/**
|
|
111
147
|
* Parse a declaration block — also the parser for a `style=""` attribute,
|
|
112
148
|
* which is the same grammar with no braces around it. CSS Syntax's list of
|
|
@@ -186,5 +222,10 @@ export declare function parseMediaQuery(prelude: string): MediaCondition[];
|
|
|
186
222
|
export declare function supportsCondition(prelude: string): boolean | null;
|
|
187
223
|
/** Whether a rule's `@media` blocks all hold at this viewport width, under
|
|
188
224
|
* this colour scheme. */
|
|
189
|
-
export declare function mediaMatches(media: MediaCondition[][] | null, width: number, scheme?: 'light' | 'dark'
|
|
225
|
+
export declare function mediaMatches(media: MediaCondition[][] | null, width: number, scheme?: 'light' | 'dark',
|
|
226
|
+
/** The viewport's height in CSS pixels; a test of it holds at no height
|
|
227
|
+
* where none is given. */
|
|
228
|
+
height?: number,
|
|
229
|
+
/** The display's scale, device pixels to the CSS pixel. */
|
|
230
|
+
resolution?: number): boolean;
|
|
190
231
|
//# sourceMappingURL=parse.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../src/html/css/parse.ts"],"names":[],"mappings":"AAoBA,6EAA6E;AAC7E,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,IAAI,CAAC;IACd,4DAA4D;IAC5D,IAAI,CAAC,EAAE,IAAI,CAAC;CACb;AAED,MAAM,WAAW,SAAS;IACxB;yDACqD;IACrD,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,WAAW,EAAE,MAAM,CAAC;IACpB,sDAAsD;IACtD,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B;;;;sDAIkD;IAClD,KAAK,EAAE,cAAc,EAAE,EAAE,GAAG,IAAI,CAAC;IACjC;;+EAE2E;IAC3E,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB;;iDAE6C;IAC7C,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB;;oEAEgE;IAChE,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,yDAAyD;IACzD,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B;2EACuE;IACvE,aAAa,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,YAAY,EAAE,WAAW,EAAE,CAAA;KAAE,EAAE,CAAC;CACpE;AAED;;;;;GAKG;AACH,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,MAAM,EAAE,MAAM,CAAC;IACf;
|
|
1
|
+
{"version":3,"file":"parse.d.ts","sourceRoot":"","sources":["../../../src/html/css/parse.ts"],"names":[],"mappings":"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"}
|
package/dist/html/css/parse.js
CHANGED
|
@@ -56,16 +56,41 @@ layers = new Map(),
|
|
|
56
56
|
/** The URL the sheet's own relative URLs resolve against — its own, or
|
|
57
57
|
* the document's for a `<style>` — or null to leave them as written.
|
|
58
58
|
* Every `url()`, `@import` and `@font-face` source comes out absolute. */
|
|
59
|
-
base = null
|
|
59
|
+
base = null,
|
|
60
|
+
/** The media queries the whole sheet is under, outermost first: the ones
|
|
61
|
+
* of the `@import` that brought it in, and of the imports that brought
|
|
62
|
+
* that sheet in. Every rule and face in it is under them, as one inside
|
|
63
|
+
* an `@media` block is under the block's. */
|
|
64
|
+
under = null) {
|
|
60
65
|
text = withoutComments(text);
|
|
61
66
|
const sheet = {
|
|
62
67
|
rules: [],
|
|
63
68
|
imports: [],
|
|
69
|
+
importConditions: [],
|
|
64
70
|
breakpoints: [],
|
|
65
71
|
fontFaces: [],
|
|
66
72
|
};
|
|
67
73
|
let order = startOrder;
|
|
68
74
|
const breakpoints = new Set();
|
|
75
|
+
/** What a media query list tests that a resize has to restyle for: the
|
|
76
|
+
* widths it changes its mind at, and whether it reads the height. */
|
|
77
|
+
const note = (conditions) => {
|
|
78
|
+
for (const c of conditions) {
|
|
79
|
+
if (c.min !== undefined)
|
|
80
|
+
breakpoints.add(c.min);
|
|
81
|
+
if (c.max !== undefined)
|
|
82
|
+
breakpoints.add(c.max + MAX_EDGE);
|
|
83
|
+
if (c.minHeight !== undefined || c.maxHeight !== undefined) {
|
|
84
|
+
sheet.readsHeight = true;
|
|
85
|
+
}
|
|
86
|
+
if (c.minAspect !== undefined || c.maxAspect !== undefined) {
|
|
87
|
+
sheet.readsHeight = true;
|
|
88
|
+
sheet.readsWidth = true;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
for (const conditions of under ?? [])
|
|
93
|
+
note(conditions);
|
|
69
94
|
// `@import` counts only ahead of every other rule, `@charset` aside
|
|
70
95
|
let importsAllowed = true;
|
|
71
96
|
/** A layer's rank, named for the first time if it has not been. */
|
|
@@ -103,10 +128,12 @@ base = null) {
|
|
|
103
128
|
if (name === 'charset')
|
|
104
129
|
continue;
|
|
105
130
|
if (name === 'import') {
|
|
106
|
-
if (importsAllowed && media ===
|
|
131
|
+
if (importsAllowed && media === under) {
|
|
107
132
|
const url = importUrl(at.prelude);
|
|
108
|
-
|
|
133
|
+
const conditions = importConditions(at.prelude);
|
|
134
|
+
if (url && conditions !== false) {
|
|
109
135
|
sheet.imports.push(resolveUrl(url, base));
|
|
136
|
+
sheet.importConditions.push(conditions);
|
|
110
137
|
}
|
|
111
138
|
}
|
|
112
139
|
continue;
|
|
@@ -118,12 +145,7 @@ base = null) {
|
|
|
118
145
|
}
|
|
119
146
|
if (name === 'media' && at.block !== null) {
|
|
120
147
|
const conditions = parseMediaQuery(at.prelude);
|
|
121
|
-
|
|
122
|
-
if (c.min !== undefined)
|
|
123
|
-
breakpoints.add(c.min);
|
|
124
|
-
if (c.max !== undefined)
|
|
125
|
-
breakpoints.add(c.max + MAX_EDGE);
|
|
126
|
-
}
|
|
148
|
+
note(conditions);
|
|
127
149
|
// A nested `@media` intersects with the one above it; pushing a
|
|
128
150
|
// level rather than merging keeps "all of these blocks hold" exact
|
|
129
151
|
// when two of them overlap.
|
|
@@ -226,6 +248,13 @@ base = null) {
|
|
|
226
248
|
breakpoints.add(c.min);
|
|
227
249
|
if (c.max !== undefined)
|
|
228
250
|
breakpoints.add(c.max + MAX_EDGE);
|
|
251
|
+
if (c.minHeight !== undefined || c.maxHeight !== undefined) {
|
|
252
|
+
sheet.readsHeight = true;
|
|
253
|
+
}
|
|
254
|
+
if (c.minAspect !== undefined || c.maxAspect !== undefined) {
|
|
255
|
+
sheet.readsHeight = true;
|
|
256
|
+
sheet.readsWidth = true;
|
|
257
|
+
}
|
|
229
258
|
}
|
|
230
259
|
styleRule(selectors, item.block, media ? [...media, conditions] : [conditions], layer, path, depth + 1);
|
|
231
260
|
}
|
|
@@ -259,7 +288,7 @@ base = null) {
|
|
|
259
288
|
});
|
|
260
289
|
}
|
|
261
290
|
};
|
|
262
|
-
walk(text,
|
|
291
|
+
walk(text, under);
|
|
263
292
|
sheet.breakpoints = [...breakpoints].sort((a, b) => a - b);
|
|
264
293
|
return sheet;
|
|
265
294
|
}
|
|
@@ -1252,18 +1281,32 @@ function readAtRule(text, at) {
|
|
|
1252
1281
|
* at: a sixty-fourth of a pixel past it, where the widths a display scale
|
|
1253
1282
|
* divides a device width into (`640.5` at 2x) fall on the right side. */
|
|
1254
1283
|
const MAX_EDGE = 1 / 64;
|
|
1284
|
+
/**
|
|
1285
|
+
* The media features that are the viewport's width and its height here.
|
|
1286
|
+
* `device-width` and `device-height` are the Web-exposed screen area's
|
|
1287
|
+
* (Media Queries 4, appendix A), which a user agent may answer with the
|
|
1288
|
+
* viewport's (CSSOM View 2.3), and a document drawn into an element has no
|
|
1289
|
+
* screen of its own to answer with. Deprecated, and still what a page from
|
|
1290
|
+
* before `width` asks with: DuckDuckGo Lite's phone sheet is
|
|
1291
|
+
* `(max-device-width: 700px)`, and a query that went unread held, so a
|
|
1292
|
+
* desktop window got the phone's 12px dropdowns.
|
|
1293
|
+
*/
|
|
1294
|
+
const VIEWPORT_SIDES = {
|
|
1295
|
+
width: new Set(['width', 'device-width']),
|
|
1296
|
+
height: new Set(['height', 'device-height']),
|
|
1297
|
+
};
|
|
1255
1298
|
/**
|
|
1256
1299
|
* A width range in Media Queries 4's syntax — `(width >= 48rem)`, `(60rem >
|
|
1257
1300
|
* width)`, `(40rem <= width < 60rem)` — as the widths it holds between, or
|
|
1258
1301
|
* null for a term that is not one. A strict bound is a sixty-fourth of a
|
|
1259
1302
|
* pixel inside the value, where a viewport's width never lands.
|
|
1260
1303
|
*/
|
|
1261
|
-
function widthRange(term) {
|
|
1304
|
+
function widthRange(term, feature = 'width') {
|
|
1262
1305
|
const inner = /^\(\s*(.*?)\s*\)$/.exec(term)?.[1];
|
|
1263
1306
|
if (!inner || !/[<>=]/.test(inner))
|
|
1264
1307
|
return null;
|
|
1265
1308
|
const parts = inner.split(/\s*(<=|>=|<|>|=)\s*/);
|
|
1266
|
-
const isWidth = (part) => part.toLowerCase()
|
|
1309
|
+
const isWidth = (part) => VIEWPORT_SIDES[feature].has(part.toLowerCase());
|
|
1267
1310
|
const out = {};
|
|
1268
1311
|
// `width OP value`, with the operator read from the width's side
|
|
1269
1312
|
const bound = (op, value) => {
|
|
@@ -1432,16 +1475,27 @@ function importUrl(prelude) {
|
|
|
1432
1475
|
const m = /^\s*(?:url\(\s*)?["']?([^"')\s]+)["']?\s*\)?/.exec(prelude);
|
|
1433
1476
|
return m ? m[1] : null;
|
|
1434
1477
|
}
|
|
1435
|
-
/**
|
|
1436
|
-
*
|
|
1437
|
-
*
|
|
1438
|
-
*
|
|
1439
|
-
|
|
1478
|
+
/**
|
|
1479
|
+
* An `@import`'s media query list, the rest of its prelude after the URL:
|
|
1480
|
+
* null where it has none, and false where no query in it can ever hold
|
|
1481
|
+
* here — a list that only names other media, `print` or `braille` — which
|
|
1482
|
+
* leaves the sheet out, unasked for (CSS 2.1 6.3). Any other list is the
|
|
1483
|
+
* condition the sheet it imports is under (CSS Cascade 4, 2): the sheet is
|
|
1484
|
+
* fetched once, and its rules hold at the widths the list does. Taken to
|
|
1485
|
+
* hold at every width, as it was, a design that imports a sheet a
|
|
1486
|
+
* breakpoint — the Zen Garden's 219, `@import url("219-1367.css") all and
|
|
1487
|
+
* (min-width: 1367px)` — had all of them at once.
|
|
1488
|
+
*/
|
|
1489
|
+
function importConditions(prelude) {
|
|
1440
1490
|
const m = /^\s*(?:url\(\s*(?:"[^"]*"|'[^']*'|[^)]*)\s*\)|"[^"]*"|'[^']*')(.*)$/s.exec(prelude);
|
|
1441
1491
|
const list = m?.[1].trim();
|
|
1442
1492
|
if (!list)
|
|
1443
|
-
return
|
|
1444
|
-
|
|
1493
|
+
return null;
|
|
1494
|
+
const conditions = parseMediaQuery(list);
|
|
1495
|
+
if (!conditions.some((c) => c.staticPass !== false))
|
|
1496
|
+
return false;
|
|
1497
|
+
// one that always holds is no condition
|
|
1498
|
+
return conditions.some((c) => c.staticPass === true) ? null : conditions;
|
|
1445
1499
|
}
|
|
1446
1500
|
/**
|
|
1447
1501
|
* A declaration value with every `url()` in it made absolute against `base`
|
|
@@ -1516,10 +1570,13 @@ const GENERIC_FAMILIES = new Set([
|
|
|
1516
1570
|
'default',
|
|
1517
1571
|
]);
|
|
1518
1572
|
/**
|
|
1519
|
-
* A `@font-face` block, or null when it names no family
|
|
1520
|
-
*
|
|
1521
|
-
*
|
|
1522
|
-
*
|
|
1573
|
+
* A `@font-face` block, or null when it names no family or no source — a
|
|
1574
|
+
* rule CSS Fonts 4 (4.3) drops whole. A rule whose sources are all
|
|
1575
|
+
* `local()`s is a rule like any other: its family is the document's, and
|
|
1576
|
+
* left out here, `"GeistSans Fallback"` — next/font's `src: local("Arial")`
|
|
1577
|
+
* with the metrics adjusted — reached the text engine as a name to look up,
|
|
1578
|
+
* where fontconfig's nearest guess for a family nobody has set a site's
|
|
1579
|
+
* headings in Gill Sans Ultra Bold.
|
|
1523
1580
|
*/
|
|
1524
1581
|
function parseFontFace(block, base, media) {
|
|
1525
1582
|
let family = null;
|
|
@@ -1555,6 +1612,15 @@ function parseFontFace(block, base, media) {
|
|
|
1555
1612
|
const sources = [];
|
|
1556
1613
|
for (const part of splitTopLevel(src, ',')) {
|
|
1557
1614
|
const item = part.trim();
|
|
1615
|
+
// `local(Gentium Bold)`, `local("Gentium Bold")`: a name as a family's
|
|
1616
|
+
// is written, and like one never a keyword (`local(inherit)`)
|
|
1617
|
+
const local = /^local\(([\s\S]*)\)$/i.exec(item);
|
|
1618
|
+
if (local) {
|
|
1619
|
+
const name = faceFamily(local[1]);
|
|
1620
|
+
if (name)
|
|
1621
|
+
sources.push({ local: name });
|
|
1622
|
+
continue;
|
|
1623
|
+
}
|
|
1558
1624
|
if (!/^url\(/i.test(item))
|
|
1559
1625
|
continue;
|
|
1560
1626
|
const end = urlEnd(item, 3);
|
|
@@ -1660,8 +1726,15 @@ export function parseMediaQuery(prelude) {
|
|
|
1660
1726
|
const condition = {};
|
|
1661
1727
|
let pass = true;
|
|
1662
1728
|
let sawWidth = false;
|
|
1729
|
+
let sawHeight = false;
|
|
1730
|
+
let sawResolution = false;
|
|
1731
|
+
let sawAspect = false;
|
|
1663
1732
|
const negated = /^\s*not\b/i.test(group);
|
|
1664
|
-
|
|
1733
|
+
// `and` needs white space after it, where a `(` would make it a
|
|
1734
|
+
// function, and none after the `)` it follows: DuckDuckGo writes
|
|
1735
|
+
// `(max-device-width: 701px)and (orientation: landscape)`, which read
|
|
1736
|
+
// as one term that was no feature, and held
|
|
1737
|
+
for (const part of group.split(/(?:\s+|(?<=\)))and\s+/i)) {
|
|
1665
1738
|
const term = part
|
|
1666
1739
|
.trim()
|
|
1667
1740
|
.replace(/^not\s+/i, '')
|
|
@@ -1681,19 +1754,53 @@ export function parseMediaQuery(prelude) {
|
|
|
1681
1754
|
sawWidth = true;
|
|
1682
1755
|
continue;
|
|
1683
1756
|
}
|
|
1757
|
+
const heights = widthRange(term, 'height');
|
|
1758
|
+
if (heights) {
|
|
1759
|
+
if (heights.min !== undefined) {
|
|
1760
|
+
condition.minHeight = Math.max(condition.minHeight ?? 0, heights.min);
|
|
1761
|
+
}
|
|
1762
|
+
if (heights.max !== undefined) {
|
|
1763
|
+
condition.maxHeight = Math.min(condition.maxHeight ?? Infinity, heights.max);
|
|
1764
|
+
}
|
|
1765
|
+
sawHeight = true;
|
|
1766
|
+
continue;
|
|
1767
|
+
}
|
|
1684
1768
|
const feature = mediaFeature(term);
|
|
1685
1769
|
if (feature) {
|
|
1686
1770
|
const key = feature[1].toLowerCase();
|
|
1687
1771
|
const len = parseLength(feature[2], ZERO_UNITS);
|
|
1688
1772
|
const px = typeof len === 'number' ? len : null;
|
|
1689
|
-
if (key === 'min-width'
|
|
1773
|
+
if ((key === 'min-width' || key === 'min-device-width') &&
|
|
1774
|
+
px !== null) {
|
|
1690
1775
|
condition.min = Math.max(condition.min ?? 0, px);
|
|
1691
1776
|
sawWidth = true;
|
|
1692
1777
|
}
|
|
1693
|
-
else if (key === 'max-width'
|
|
1778
|
+
else if ((key === 'max-width' || key === 'max-device-width') &&
|
|
1779
|
+
px !== null) {
|
|
1694
1780
|
condition.max = Math.min(condition.max ?? Infinity, px);
|
|
1695
1781
|
sawWidth = true;
|
|
1696
1782
|
}
|
|
1783
|
+
else if (px === null &&
|
|
1784
|
+
/^(?:min-|max-)?(?:device-)?(?:width|height)$/.test(key)) {
|
|
1785
|
+
// a size that is no length is a query that does not parse, which
|
|
1786
|
+
// Media Queries 4 (3.2) makes `not all`: `(min-width:0\0)`, the
|
|
1787
|
+
// hack that kept a block for Internet Explorer 9 and 10, held
|
|
1788
|
+
// here as a query that asked nothing, and its rules applied
|
|
1789
|
+
pass = false;
|
|
1790
|
+
}
|
|
1791
|
+
else if ((key === 'min-height' || key === 'min-device-height') &&
|
|
1792
|
+
px !== null) {
|
|
1793
|
+
// the viewport's height, answered live as its width is: a
|
|
1794
|
+
// design that sets its heading's size by the window's height
|
|
1795
|
+
// took the tallest step's at every height
|
|
1796
|
+
condition.minHeight = Math.max(condition.minHeight ?? 0, px);
|
|
1797
|
+
sawHeight = true;
|
|
1798
|
+
}
|
|
1799
|
+
else if ((key === 'max-height' || key === 'max-device-height') &&
|
|
1800
|
+
px !== null) {
|
|
1801
|
+
condition.maxHeight = Math.min(condition.maxHeight ?? Infinity, px);
|
|
1802
|
+
sawHeight = true;
|
|
1803
|
+
}
|
|
1697
1804
|
else if (key === 'prefers-color-scheme') {
|
|
1698
1805
|
// Answered live, from the palette in force: a document dropped
|
|
1699
1806
|
// into a dark application takes its dark branch, and follows the
|
|
@@ -1716,7 +1823,67 @@ export function parseMediaQuery(prelude) {
|
|
|
1716
1823
|
pass = false;
|
|
1717
1824
|
}
|
|
1718
1825
|
else if (key === 'orientation') {
|
|
1719
|
-
|
|
1826
|
+
// the viewport's, as its aspect ratio: portrait where its height
|
|
1827
|
+
// is at least its width (Media Queries 4, 4.5)
|
|
1828
|
+
const orientation = feature[2].trim().toLowerCase();
|
|
1829
|
+
if (orientation === 'portrait') {
|
|
1830
|
+
condition.maxAspect = Math.min(condition.maxAspect ?? Infinity, 1);
|
|
1831
|
+
sawAspect = true;
|
|
1832
|
+
}
|
|
1833
|
+
else if (orientation === 'landscape') {
|
|
1834
|
+
condition.minAspect = Math.max(condition.minAspect ?? 0, 1 + ASPECT_EDGE);
|
|
1835
|
+
sawAspect = true;
|
|
1836
|
+
}
|
|
1837
|
+
else
|
|
1838
|
+
pass = false;
|
|
1839
|
+
}
|
|
1840
|
+
else if (ASPECT_FEATURES.test(key)) {
|
|
1841
|
+
const ratio = ratioOf(feature[2]);
|
|
1842
|
+
if (ratio === null)
|
|
1843
|
+
pass = false;
|
|
1844
|
+
else {
|
|
1845
|
+
if (!key.startsWith('max-')) {
|
|
1846
|
+
condition.minAspect = Math.max(condition.minAspect ?? 0, ratio);
|
|
1847
|
+
}
|
|
1848
|
+
if (!key.startsWith('min-')) {
|
|
1849
|
+
condition.maxAspect = Math.min(condition.maxAspect ?? Infinity, ratio);
|
|
1850
|
+
}
|
|
1851
|
+
sawAspect = true;
|
|
1852
|
+
}
|
|
1853
|
+
}
|
|
1854
|
+
else if (RESOLUTION_FEATURES.has(key)) {
|
|
1855
|
+
const dppx = resolutionOf(feature[2], key.startsWith('-webkit-'));
|
|
1856
|
+
if (dppx === null)
|
|
1857
|
+
pass = false;
|
|
1858
|
+
else {
|
|
1859
|
+
if (!key.includes('max-')) {
|
|
1860
|
+
condition.minResolution = Math.max(condition.minResolution ?? 0, dppx);
|
|
1861
|
+
}
|
|
1862
|
+
if (!key.includes('min-')) {
|
|
1863
|
+
condition.maxResolution = Math.min(condition.maxResolution ?? Infinity, dppx);
|
|
1864
|
+
}
|
|
1865
|
+
sawResolution = true;
|
|
1866
|
+
}
|
|
1867
|
+
}
|
|
1868
|
+
else if (desktopFeature(key, feature[2]) !== true) {
|
|
1869
|
+
// any other feature as a desktop screen with a mouse answers
|
|
1870
|
+
// it, and one nothing knows is false (Media Queries 4, 3.2):
|
|
1871
|
+
// Firefox's and Opera's resolution features, which a design lists
|
|
1872
|
+
// beside WebKit's, held here, and a page at one dot to the pixel
|
|
1873
|
+
// took the rules it keeps for two
|
|
1874
|
+
pass = false;
|
|
1875
|
+
}
|
|
1876
|
+
continue;
|
|
1877
|
+
}
|
|
1878
|
+
const flag = /^\(\s*(-?[a-z][a-z0-9-]*)\s*\)$/i.exec(term);
|
|
1879
|
+
if (flag) {
|
|
1880
|
+
// a feature in the boolean context, `(hover)`: true where its value
|
|
1881
|
+
// is anything but zero or none
|
|
1882
|
+
const key = flag[1].toLowerCase();
|
|
1883
|
+
if (!BOOLEAN_TRUE.has(key) &&
|
|
1884
|
+
!RESOLUTION_FEATURES.has(key) &&
|
|
1885
|
+
desktopFeature(key, null) !== true) {
|
|
1886
|
+
pass = false;
|
|
1720
1887
|
}
|
|
1721
1888
|
continue;
|
|
1722
1889
|
}
|
|
@@ -1734,11 +1901,20 @@ export function parseMediaQuery(prelude) {
|
|
|
1734
1901
|
// `not` over a scheme is the other scheme. `not` over a width range
|
|
1735
1902
|
// is not expressible as one range; the honest reduction is to decide
|
|
1736
1903
|
// it statically rather than invert it wrongly.
|
|
1737
|
-
if (!sawWidth &&
|
|
1904
|
+
if (!sawWidth &&
|
|
1905
|
+
!sawHeight &&
|
|
1906
|
+
!sawResolution &&
|
|
1907
|
+
!sawAspect &&
|
|
1908
|
+
pass &&
|
|
1909
|
+
condition.scheme) {
|
|
1738
1910
|
out.push({ scheme: condition.scheme === 'dark' ? 'light' : 'dark' });
|
|
1739
1911
|
continue;
|
|
1740
1912
|
}
|
|
1741
|
-
out.push({
|
|
1913
|
+
out.push({
|
|
1914
|
+
staticPass: !sawWidth && !sawHeight && !sawResolution && !sawAspect && pass
|
|
1915
|
+
? false
|
|
1916
|
+
: !pass,
|
|
1917
|
+
});
|
|
1742
1918
|
continue;
|
|
1743
1919
|
}
|
|
1744
1920
|
if (!pass) {
|
|
@@ -1746,6 +1922,9 @@ export function parseMediaQuery(prelude) {
|
|
|
1746
1922
|
continue;
|
|
1747
1923
|
}
|
|
1748
1924
|
if (!sawWidth &&
|
|
1925
|
+
!sawHeight &&
|
|
1926
|
+
!sawResolution &&
|
|
1927
|
+
!sawAspect &&
|
|
1749
1928
|
condition.scheme === undefined &&
|
|
1750
1929
|
condition.min === undefined &&
|
|
1751
1930
|
condition.max === undefined) {
|
|
@@ -1847,6 +2026,122 @@ export function supportsCondition(prelude) {
|
|
|
1847
2026
|
* first `)` found no feature there — the term was passed over as though it
|
|
1848
2027
|
* said nothing, and every narrow-screen rule held at every width.
|
|
1849
2028
|
*/
|
|
2029
|
+
/** `aspect-ratio` and the device's, bare or `min-`/`max-`. */
|
|
2030
|
+
const ASPECT_FEATURES = /^(?:min-|max-)?(?:device-)?aspect-ratio$/;
|
|
2031
|
+
/** How far past square a landscape viewport is: any width over the height. */
|
|
2032
|
+
const ASPECT_EDGE = 1e-9;
|
|
2033
|
+
/** A ratio, `16/9` or `16 / 9` or `1.5`, as a number; null for anything
|
|
2034
|
+
* else, or a ratio of nothing. */
|
|
2035
|
+
function ratioOf(value) {
|
|
2036
|
+
const m = /^\s*(\d*\.?\d+)\s*(?:\/\s*(\d*\.?\d+)\s*)?$/.exec(value);
|
|
2037
|
+
if (!m)
|
|
2038
|
+
return null;
|
|
2039
|
+
const ratio = Number(m[1]) / (m[2] === undefined ? 1 : Number(m[2]));
|
|
2040
|
+
return Number.isFinite(ratio) && ratio > 0 ? ratio : null;
|
|
2041
|
+
}
|
|
2042
|
+
/** The resolution features, the standard's and WebKit's, which Chrome
|
|
2043
|
+
* answers; `min--moz-device-pixel-ratio` and `-o-min-device-pixel-ratio`
|
|
2044
|
+
* are no feature of its, and none of this. */
|
|
2045
|
+
const RESOLUTION_FEATURES = new Set([
|
|
2046
|
+
'resolution',
|
|
2047
|
+
'min-resolution',
|
|
2048
|
+
'max-resolution',
|
|
2049
|
+
'-webkit-device-pixel-ratio',
|
|
2050
|
+
'-webkit-min-device-pixel-ratio',
|
|
2051
|
+
'-webkit-max-device-pixel-ratio',
|
|
2052
|
+
]);
|
|
2053
|
+
/** A resolution in dots per CSS pixel: `2dppx`, `2x`, `192dpi`, `75.6dpcm`,
|
|
2054
|
+
* or WebKit's device pixel ratio, a number. Null for anything else. */
|
|
2055
|
+
function resolutionOf(value, ratio) {
|
|
2056
|
+
const m = /^\s*(\d*\.?\d+(?:e[+-]?\d+)?)\s*(dppx|x|dpi|dpcm)?\s*$/i.exec(value);
|
|
2057
|
+
if (!m)
|
|
2058
|
+
return null;
|
|
2059
|
+
const n = Number(m[1]);
|
|
2060
|
+
const unit = (m[2] ?? '').toLowerCase();
|
|
2061
|
+
if (ratio)
|
|
2062
|
+
return unit ? null : n;
|
|
2063
|
+
if (unit === 'dppx' || unit === 'x')
|
|
2064
|
+
return n;
|
|
2065
|
+
if (unit === 'dpi')
|
|
2066
|
+
return n / 96;
|
|
2067
|
+
if (unit === 'dpcm')
|
|
2068
|
+
return (n * 2.54) / 96;
|
|
2069
|
+
return null;
|
|
2070
|
+
}
|
|
2071
|
+
/** The features true in the boolean context whatever the viewport: a
|
|
2072
|
+
* size, a scheme, an orientation, there is always one. */
|
|
2073
|
+
const BOOLEAN_TRUE = new Set([
|
|
2074
|
+
'width',
|
|
2075
|
+
'height',
|
|
2076
|
+
'device-width',
|
|
2077
|
+
'device-height',
|
|
2078
|
+
'aspect-ratio',
|
|
2079
|
+
'orientation',
|
|
2080
|
+
'prefers-color-scheme',
|
|
2081
|
+
]);
|
|
2082
|
+
/**
|
|
2083
|
+
* A media feature as a desktop screen driven by a mouse answers it — the
|
|
2084
|
+
* device `<Html>` draws on — for the features that do not depend on the
|
|
2085
|
+
* viewport: true, false, or null for a feature nothing knows, which is
|
|
2086
|
+
* false (Media Queries 4, 3.2). `value` is null in the boolean context.
|
|
2087
|
+
* The colour is eight bits a component on no palette and no grid; scripts
|
|
2088
|
+
* never run here, so `scripting` is `none`.
|
|
2089
|
+
*/
|
|
2090
|
+
function desktopFeature(key, value) {
|
|
2091
|
+
const v = value?.trim().toLowerCase() ?? null;
|
|
2092
|
+
const numeric = (feature, has) => {
|
|
2093
|
+
const bare = key.replace(/^(min|max)-/, '');
|
|
2094
|
+
if (bare !== feature)
|
|
2095
|
+
return null;
|
|
2096
|
+
if (v === null)
|
|
2097
|
+
return key === feature ? has !== 0 : null;
|
|
2098
|
+
const n = Number(v);
|
|
2099
|
+
if (!Number.isFinite(n))
|
|
2100
|
+
return false;
|
|
2101
|
+
if (key.startsWith('min-'))
|
|
2102
|
+
return has >= n;
|
|
2103
|
+
if (key.startsWith('max-'))
|
|
2104
|
+
return has <= n;
|
|
2105
|
+
return has === n;
|
|
2106
|
+
};
|
|
2107
|
+
const keyword = (answers, bool) => v === null ? bool : (answers[v] ?? false);
|
|
2108
|
+
switch (key) {
|
|
2109
|
+
case 'hover':
|
|
2110
|
+
case 'any-hover':
|
|
2111
|
+
return keyword({ hover: true, none: false }, true);
|
|
2112
|
+
case 'pointer':
|
|
2113
|
+
case 'any-pointer':
|
|
2114
|
+
return keyword({ fine: true, coarse: false, none: false }, true);
|
|
2115
|
+
case 'update':
|
|
2116
|
+
return keyword({ fast: true, slow: false, none: false }, true);
|
|
2117
|
+
case 'overflow-block':
|
|
2118
|
+
case 'overflow-inline':
|
|
2119
|
+
return keyword({ scroll: true }, true);
|
|
2120
|
+
case 'scan':
|
|
2121
|
+
return false;
|
|
2122
|
+
case 'color-gamut':
|
|
2123
|
+
return keyword({ srgb: true }, true);
|
|
2124
|
+
case 'dynamic-range':
|
|
2125
|
+
case 'video-dynamic-range':
|
|
2126
|
+
return keyword({ standard: true }, true);
|
|
2127
|
+
case 'prefers-contrast':
|
|
2128
|
+
case 'prefers-reduced-transparency':
|
|
2129
|
+
case 'prefers-reduced-data':
|
|
2130
|
+
return keyword({ 'no-preference': true }, false);
|
|
2131
|
+
case 'forced-colors':
|
|
2132
|
+
return keyword({ none: true }, false);
|
|
2133
|
+
case 'scripting':
|
|
2134
|
+
return keyword({ none: true }, false);
|
|
2135
|
+
case 'display-mode':
|
|
2136
|
+
return keyword({ browser: true }, true);
|
|
2137
|
+
case '-webkit-transform-3d':
|
|
2138
|
+
return v === null || v === '1';
|
|
2139
|
+
}
|
|
2140
|
+
return (numeric('color', 8) ??
|
|
2141
|
+
numeric('monochrome', 0) ??
|
|
2142
|
+
numeric('color-index', 0) ??
|
|
2143
|
+
numeric('grid', 0));
|
|
2144
|
+
}
|
|
1850
2145
|
function mediaFeature(term) {
|
|
1851
2146
|
const m = /^\(\s*([a-z-]+)\s*:([\s\S]*)\)$/i.exec(term);
|
|
1852
2147
|
if (!m)
|
|
@@ -1867,7 +2162,12 @@ function mediaFeature(term) {
|
|
|
1867
2162
|
const ZERO_UNITS = { em: 16, rem: 16, vw: 0, vh: 0, scale: 1 };
|
|
1868
2163
|
/** Whether a rule's `@media` blocks all hold at this viewport width, under
|
|
1869
2164
|
* this colour scheme. */
|
|
1870
|
-
export function mediaMatches(media, width, scheme = 'light'
|
|
2165
|
+
export function mediaMatches(media, width, scheme = 'light',
|
|
2166
|
+
/** The viewport's height in CSS pixels; a test of it holds at no height
|
|
2167
|
+
* where none is given. */
|
|
2168
|
+
height = NaN,
|
|
2169
|
+
/** The display's scale, device pixels to the CSS pixel. */
|
|
2170
|
+
resolution = 1) {
|
|
1871
2171
|
if (!media)
|
|
1872
2172
|
return true;
|
|
1873
2173
|
for (const block of media) {
|
|
@@ -1880,6 +2180,12 @@ export function mediaMatches(media, width, scheme = 'light') {
|
|
|
1880
2180
|
}
|
|
1881
2181
|
if ((c.min === undefined || width >= c.min) &&
|
|
1882
2182
|
(c.max === undefined || width <= c.max) &&
|
|
2183
|
+
(c.minHeight === undefined || height >= c.minHeight) &&
|
|
2184
|
+
(c.maxHeight === undefined || height <= c.maxHeight) &&
|
|
2185
|
+
(c.minResolution === undefined || resolution >= c.minResolution) &&
|
|
2186
|
+
(c.minAspect === undefined || width >= c.minAspect * height) &&
|
|
2187
|
+
(c.maxAspect === undefined || width <= c.maxAspect * height) &&
|
|
2188
|
+
(c.maxResolution === undefined || resolution <= c.maxResolution) &&
|
|
1883
2189
|
(c.scheme === undefined || c.scheme === scheme)) {
|
|
1884
2190
|
any = true;
|
|
1885
2191
|
}
|