@react-x11/components 0.11.0 → 0.13.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/flow/node.d.ts +14 -6
- package/dist/flow/node.d.ts.map +1 -1
- package/dist/flow/node.js +82 -64
- package/dist/flow/node.js.map +1 -1
- package/dist/html/controls.d.ts +38 -10
- package/dist/html/controls.d.ts.map +1 -1
- package/dist/html/controls.js +43 -58
- 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 +538 -128
- package/dist/html/css/cascade.js.map +1 -1
- package/dist/html/css/color.d.ts +19 -0
- package/dist/html/css/color.d.ts.map +1 -1
- package/dist/html/css/color.js +86 -0
- package/dist/html/css/color.js.map +1 -1
- package/dist/html/css/parse.d.ts +40 -2
- package/dist/html/css/parse.d.ts.map +1 -1
- package/dist/html/css/parse.js +391 -13
- package/dist/html/css/parse.js.map +1 -1
- package/dist/html/css/style.d.ts +52 -1
- package/dist/html/css/style.d.ts.map +1 -1
- package/dist/html/css/style.js +328 -11
- package/dist/html/css/style.js.map +1 -1
- 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 -7
- package/dist/html/css/ua.js.map +1 -1
- package/dist/html/css/values.d.ts +10 -1
- package/dist/html/css/values.d.ts.map +1 -1
- package/dist/html/css/values.js +27 -2
- package/dist/html/css/values.js.map +1 -1
- package/dist/html/css/vars.d.ts +5 -0
- package/dist/html/css/vars.d.ts.map +1 -1
- package/dist/html/css/vars.js +2 -2
- package/dist/html/css/vars.js.map +1 -1
- package/dist/html/dom.d.ts.map +1 -1
- package/dist/html/dom.js +38 -3
- package/dist/html/dom.js.map +1 -1
- package/dist/html/fonts.d.ts +25 -1
- package/dist/html/fonts.d.ts.map +1 -1
- package/dist/html/fonts.js +99 -6
- 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 -264
- package/dist/html/index.js.map +1 -1
- package/dist/html/layout/block.d.ts +11 -2
- package/dist/html/layout/block.d.ts.map +1 -1
- package/dist/html/layout/block.js +186 -19
- package/dist/html/layout/block.js.map +1 -1
- package/dist/html/layout/boxes.d.ts +65 -7
- package/dist/html/layout/boxes.d.ts.map +1 -1
- package/dist/html/layout/boxes.js +87 -22
- package/dist/html/layout/boxes.js.map +1 -1
- package/dist/html/layout/cache.d.ts +2 -2
- package/dist/html/layout/cache.d.ts.map +1 -1
- package/dist/html/layout/cache.js +8 -3
- package/dist/html/layout/cache.js.map +1 -1
- package/dist/html/layout/flex.js +4 -1
- package/dist/html/layout/flex.js.map +1 -1
- package/dist/html/layout/floats.d.ts +4 -0
- package/dist/html/layout/floats.d.ts.map +1 -1
- package/dist/html/layout/floats.js +26 -0
- package/dist/html/layout/floats.js.map +1 -1
- package/dist/html/layout/inline.d.ts +26 -2
- package/dist/html/layout/inline.d.ts.map +1 -1
- package/dist/html/layout/inline.js +1232 -115
- package/dist/html/layout/inline.js.map +1 -1
- package/dist/html/node.d.ts +120 -15
- package/dist/html/node.d.ts.map +1 -1
- package/dist/html/node.js +993 -174
- package/dist/html/node.js.map +1 -1
- package/dist/html/paint.d.ts +75 -2
- package/dist/html/paint.d.ts.map +1 -1
- package/dist/html/paint.js +836 -200
- package/dist/html/paint.js.map +1 -1
- package/dist/html/surfaces.d.ts +7 -2
- package/dist/html/surfaces.d.ts.map +1 -1
- package/dist/html/surfaces.js +16 -0
- package/dist/html/surfaces.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 +620 -0
- package/dist/html/widgets.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/internal/window.d.ts +22 -0
- package/dist/internal/window.d.ts.map +1 -1
- package/dist/internal/window.js +35 -8
- package/dist/internal/window.js.map +1 -1
- package/dist/richtext/node.d.ts +7 -0
- package/dist/richtext/node.d.ts.map +1 -1
- package/dist/richtext/node.js.map +1 -1
- package/package.json +6 -4
- package/src/flow/node.ts +80 -64
- package/src/html/controls.ts +79 -58
- package/src/html/css/cascade.ts +610 -146
- package/src/html/css/color.ts +87 -0
- package/src/html/css/parse.ts +431 -13
- package/src/html/css/style.ts +367 -11
- package/src/html/css/ua.ts +76 -8
- package/src/html/css/values.ts +31 -3
- package/src/html/css/vars.ts +2 -2
- package/src/html/dom.ts +41 -3
- package/src/html/fonts.ts +116 -6
- package/src/html/form.ts +962 -0
- package/src/html/index.ts +49 -300
- package/src/html/layout/block.ts +231 -16
- package/src/html/layout/boxes.ts +133 -32
- package/src/html/layout/cache.ts +8 -3
- package/src/html/layout/flex.ts +4 -1
- package/src/html/layout/floats.ts +24 -0
- package/src/html/layout/inline.ts +1445 -108
- package/src/html/node.ts +1010 -166
- package/src/html/paint.ts +980 -270
- package/src/html/surfaces.ts +21 -1
- package/src/html/widgets.ts +735 -0
- package/src/index.ts +1 -0
- package/src/internal/window.ts +36 -8
- package/src/richtext/node.ts +7 -0
package/dist/html/css/parse.d.ts
CHANGED
|
@@ -38,6 +38,14 @@ export interface Stylesheet {
|
|
|
38
38
|
* keeps these so a resize can tell "the layout changed" from "the
|
|
39
39
|
* *cascade* changed", and restyle only when it crossed one. */
|
|
40
40
|
breakpoints: number[];
|
|
41
|
+
/** Whether a `@media` rule in this sheet tests the viewport's height,
|
|
42
|
+
* which makes a document restyle when the height moves, as a `vh`
|
|
43
|
+
* does. */
|
|
44
|
+
readsHeight?: boolean;
|
|
45
|
+
/** Whether one tests its aspect ratio, which a width that crosses no
|
|
46
|
+
* breakpoint can change: the document restyles as one with a `vw`
|
|
47
|
+
* does. */
|
|
48
|
+
readsWidth?: boolean;
|
|
41
49
|
/** The `@font-face` rules, in order (see `fonts.ts`). */
|
|
42
50
|
fontFaces: FontFaceRule[];
|
|
43
51
|
/** `@counter-style` rules, in order: a name and its descriptors, which
|
|
@@ -72,12 +80,26 @@ export interface FontFaceSource {
|
|
|
72
80
|
url: string;
|
|
73
81
|
format: string | null;
|
|
74
82
|
}
|
|
75
|
-
/** The tests this evaluates live: a width, a colour scheme
|
|
83
|
+
/** The tests this evaluates live: a width, a height, a colour scheme.
|
|
76
84
|
* Anything else — `orientation`, `print`, `prefers-reduced-motion` — is
|
|
77
85
|
* decided once, at parse time, by `staticPass`. */
|
|
78
86
|
export interface MediaCondition {
|
|
79
87
|
min?: number;
|
|
80
88
|
max?: number;
|
|
89
|
+
/** The viewport's height, as `min`/`max` its width: `min-height`,
|
|
90
|
+
* `max-height` and a range on `height` (Media Queries 4, 4.2). */
|
|
91
|
+
minHeight?: number;
|
|
92
|
+
maxHeight?: number;
|
|
93
|
+
/** The display's resolution in dots per CSS pixel, its scale: `min-`
|
|
94
|
+
* and `max-resolution`, and WebKit's `-webkit-min-device-pixel-ratio`,
|
|
95
|
+
* which a design writes to swap in its high-DPI images. */
|
|
96
|
+
minResolution?: number;
|
|
97
|
+
maxResolution?: number;
|
|
98
|
+
/** The viewport's width over its height: `aspect-ratio` and its `min-`
|
|
99
|
+
* and `max-`, the device's the viewport's too, and `orientation`, which
|
|
100
|
+
* is landscape where the width is the greater. */
|
|
101
|
+
minAspect?: number;
|
|
102
|
+
maxAspect?: number;
|
|
81
103
|
/** `prefers-color-scheme`, answered from the palette in force. */
|
|
82
104
|
scheme?: 'light' | 'dark';
|
|
83
105
|
/** Set when the query could not be evaluated as a width or scheme test:
|
|
@@ -173,7 +195,23 @@ export declare function absoluteUrls(value: string, base: string): string;
|
|
|
173
195
|
* does not understand is decided statically by that feature alone.
|
|
174
196
|
*/
|
|
175
197
|
export declare function parseMediaQuery(prelude: string): MediaCondition[];
|
|
198
|
+
/**
|
|
199
|
+
* Whether a `@supports` condition holds (CSS Conditional 3, 6): true or
|
|
200
|
+
* false where it turns on declarations of the properties this answers for
|
|
201
|
+
* (`ANSWERED`), combined by `not`, `and` and `or`; null where it turns on
|
|
202
|
+
* anything else, or is none, and the block is entered as every one was.
|
|
203
|
+
* Answering more is not safe without a list of what this draws: Tailwind 4
|
|
204
|
+
* keeps its variables' starting values under a test for engines without
|
|
205
|
+
* `@property`, which this is, and false there would drop every shadow and
|
|
206
|
+
* gradient it writes.
|
|
207
|
+
*/
|
|
208
|
+
export declare function supportsCondition(prelude: string): boolean | null;
|
|
176
209
|
/** Whether a rule's `@media` blocks all hold at this viewport width, under
|
|
177
210
|
* this colour scheme. */
|
|
178
|
-
export declare function mediaMatches(media: MediaCondition[][] | null, width: number, scheme?: 'light' | 'dark'
|
|
211
|
+
export declare function mediaMatches(media: MediaCondition[][] | null, width: number, scheme?: 'light' | 'dark',
|
|
212
|
+
/** The viewport's height in CSS pixels; a test of it holds at no height
|
|
213
|
+
* where none is given. */
|
|
214
|
+
height?: number,
|
|
215
|
+
/** The display's scale, device pixels to the CSS pixel. */
|
|
216
|
+
resolution?: number): boolean;
|
|
179
217
|
//# 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;sDACkD;IAClD,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B;qCACiC;IACjC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACzB,KAAK,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAC3B,+DAA+D;IAC/D,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,EAAE,GAAG,IAAI,CAAC;IACxC,kEAAkE;IAClE,KAAK,EAAE,cAAc,EAAE,EAAE,GAAG,IAAI,CAAC;CAClC;AAED,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAED;;oDAEoD;AACpD,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kEAAkE;IAClE,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC1B;;iCAE6B;IAC7B,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAwBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,UAAU,SAAI;AACd;;iEAEiE;AACjE,MAAM,GAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAa;AACvC;;2EAE2E;AAC3E,IAAI,GAAE,MAAM,GAAG,IAAW,GACzB,UAAU,
|
|
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
|
@@ -123,6 +123,13 @@ base = null) {
|
|
|
123
123
|
breakpoints.add(c.min);
|
|
124
124
|
if (c.max !== undefined)
|
|
125
125
|
breakpoints.add(c.max + MAX_EDGE);
|
|
126
|
+
if (c.minHeight !== undefined || c.maxHeight !== undefined) {
|
|
127
|
+
sheet.readsHeight = true;
|
|
128
|
+
}
|
|
129
|
+
if (c.minAspect !== undefined || c.maxAspect !== undefined) {
|
|
130
|
+
sheet.readsHeight = true;
|
|
131
|
+
sheet.readsWidth = true;
|
|
132
|
+
}
|
|
126
133
|
}
|
|
127
134
|
// A nested `@media` intersects with the one above it; pushing a
|
|
128
135
|
// level rather than merging keeps "all of these blocks hold" exact
|
|
@@ -132,8 +139,11 @@ base = null) {
|
|
|
132
139
|
else if (name === 'supports' && at.block !== null) {
|
|
133
140
|
// Everything in a `@supports` block is markup this renderer either
|
|
134
141
|
// understands or ignores per-declaration, so entering it is closer
|
|
135
|
-
// to right than skipping it
|
|
136
|
-
|
|
142
|
+
// to right than skipping it — but for a condition it can answer
|
|
143
|
+
// false (`supportsCondition`)
|
|
144
|
+
if (supportsCondition(at.prelude) !== false) {
|
|
145
|
+
walk(at.block, media, layer, path);
|
|
146
|
+
}
|
|
137
147
|
}
|
|
138
148
|
else if (name === 'layer') {
|
|
139
149
|
// `@layer a, b;` names layers, and so fixes their order, and
|
|
@@ -223,11 +233,20 @@ base = null) {
|
|
|
223
233
|
breakpoints.add(c.min);
|
|
224
234
|
if (c.max !== undefined)
|
|
225
235
|
breakpoints.add(c.max + MAX_EDGE);
|
|
236
|
+
if (c.minHeight !== undefined || c.maxHeight !== undefined) {
|
|
237
|
+
sheet.readsHeight = true;
|
|
238
|
+
}
|
|
239
|
+
if (c.minAspect !== undefined || c.maxAspect !== undefined) {
|
|
240
|
+
sheet.readsHeight = true;
|
|
241
|
+
sheet.readsWidth = true;
|
|
242
|
+
}
|
|
226
243
|
}
|
|
227
244
|
styleRule(selectors, item.block, media ? [...media, conditions] : [conditions], layer, path, depth + 1);
|
|
228
245
|
}
|
|
229
246
|
else if (name === 'supports') {
|
|
230
|
-
|
|
247
|
+
if (supportsCondition(item.prelude) !== false) {
|
|
248
|
+
styleRule(selectors, item.block, media, layer, path, depth + 1);
|
|
249
|
+
}
|
|
231
250
|
}
|
|
232
251
|
else if (name === 'layer' && LAYER_NAME.test(item.prelude.trim())) {
|
|
233
252
|
const [ranks, full] = enter(item.prelude.trim(), layer, path);
|
|
@@ -1247,18 +1266,32 @@ function readAtRule(text, at) {
|
|
|
1247
1266
|
* at: a sixty-fourth of a pixel past it, where the widths a display scale
|
|
1248
1267
|
* divides a device width into (`640.5` at 2x) fall on the right side. */
|
|
1249
1268
|
const MAX_EDGE = 1 / 64;
|
|
1269
|
+
/**
|
|
1270
|
+
* The media features that are the viewport's width and its height here.
|
|
1271
|
+
* `device-width` and `device-height` are the Web-exposed screen area's
|
|
1272
|
+
* (Media Queries 4, appendix A), which a user agent may answer with the
|
|
1273
|
+
* viewport's (CSSOM View 2.3), and a document drawn into an element has no
|
|
1274
|
+
* screen of its own to answer with. Deprecated, and still what a page from
|
|
1275
|
+
* before `width` asks with: DuckDuckGo Lite's phone sheet is
|
|
1276
|
+
* `(max-device-width: 700px)`, and a query that went unread held, so a
|
|
1277
|
+
* desktop window got the phone's 12px dropdowns.
|
|
1278
|
+
*/
|
|
1279
|
+
const VIEWPORT_SIDES = {
|
|
1280
|
+
width: new Set(['width', 'device-width']),
|
|
1281
|
+
height: new Set(['height', 'device-height']),
|
|
1282
|
+
};
|
|
1250
1283
|
/**
|
|
1251
1284
|
* A width range in Media Queries 4's syntax — `(width >= 48rem)`, `(60rem >
|
|
1252
1285
|
* width)`, `(40rem <= width < 60rem)` — as the widths it holds between, or
|
|
1253
1286
|
* null for a term that is not one. A strict bound is a sixty-fourth of a
|
|
1254
1287
|
* pixel inside the value, where a viewport's width never lands.
|
|
1255
1288
|
*/
|
|
1256
|
-
function widthRange(term) {
|
|
1289
|
+
function widthRange(term, feature = 'width') {
|
|
1257
1290
|
const inner = /^\(\s*(.*?)\s*\)$/.exec(term)?.[1];
|
|
1258
1291
|
if (!inner || !/[<>=]/.test(inner))
|
|
1259
1292
|
return null;
|
|
1260
1293
|
const parts = inner.split(/\s*(<=|>=|<|>|=)\s*/);
|
|
1261
|
-
const isWidth = (part) => part.toLowerCase()
|
|
1294
|
+
const isWidth = (part) => VIEWPORT_SIDES[feature].has(part.toLowerCase());
|
|
1262
1295
|
const out = {};
|
|
1263
1296
|
// `width OP value`, with the operator read from the width's side
|
|
1264
1297
|
const bound = (op, value) => {
|
|
@@ -1655,8 +1688,15 @@ export function parseMediaQuery(prelude) {
|
|
|
1655
1688
|
const condition = {};
|
|
1656
1689
|
let pass = true;
|
|
1657
1690
|
let sawWidth = false;
|
|
1691
|
+
let sawHeight = false;
|
|
1692
|
+
let sawResolution = false;
|
|
1693
|
+
let sawAspect = false;
|
|
1658
1694
|
const negated = /^\s*not\b/i.test(group);
|
|
1659
|
-
|
|
1695
|
+
// `and` needs white space after it, where a `(` would make it a
|
|
1696
|
+
// function, and none after the `)` it follows: DuckDuckGo writes
|
|
1697
|
+
// `(max-device-width: 701px)and (orientation: landscape)`, which read
|
|
1698
|
+
// as one term that was no feature, and held
|
|
1699
|
+
for (const part of group.split(/(?:\s+|(?<=\)))and\s+/i)) {
|
|
1660
1700
|
const term = part
|
|
1661
1701
|
.trim()
|
|
1662
1702
|
.replace(/^not\s+/i, '')
|
|
@@ -1676,19 +1716,53 @@ export function parseMediaQuery(prelude) {
|
|
|
1676
1716
|
sawWidth = true;
|
|
1677
1717
|
continue;
|
|
1678
1718
|
}
|
|
1679
|
-
const
|
|
1719
|
+
const heights = widthRange(term, 'height');
|
|
1720
|
+
if (heights) {
|
|
1721
|
+
if (heights.min !== undefined) {
|
|
1722
|
+
condition.minHeight = Math.max(condition.minHeight ?? 0, heights.min);
|
|
1723
|
+
}
|
|
1724
|
+
if (heights.max !== undefined) {
|
|
1725
|
+
condition.maxHeight = Math.min(condition.maxHeight ?? Infinity, heights.max);
|
|
1726
|
+
}
|
|
1727
|
+
sawHeight = true;
|
|
1728
|
+
continue;
|
|
1729
|
+
}
|
|
1730
|
+
const feature = mediaFeature(term);
|
|
1680
1731
|
if (feature) {
|
|
1681
1732
|
const key = feature[1].toLowerCase();
|
|
1682
1733
|
const len = parseLength(feature[2], ZERO_UNITS);
|
|
1683
1734
|
const px = typeof len === 'number' ? len : null;
|
|
1684
|
-
if (key === 'min-width'
|
|
1735
|
+
if ((key === 'min-width' || key === 'min-device-width') &&
|
|
1736
|
+
px !== null) {
|
|
1685
1737
|
condition.min = Math.max(condition.min ?? 0, px);
|
|
1686
1738
|
sawWidth = true;
|
|
1687
1739
|
}
|
|
1688
|
-
else if (key === 'max-width'
|
|
1740
|
+
else if ((key === 'max-width' || key === 'max-device-width') &&
|
|
1741
|
+
px !== null) {
|
|
1689
1742
|
condition.max = Math.min(condition.max ?? Infinity, px);
|
|
1690
1743
|
sawWidth = true;
|
|
1691
1744
|
}
|
|
1745
|
+
else if (px === null &&
|
|
1746
|
+
/^(?:min-|max-)?(?:device-)?(?:width|height)$/.test(key)) {
|
|
1747
|
+
// a size that is no length is a query that does not parse, which
|
|
1748
|
+
// Media Queries 4 (3.2) makes `not all`: `(min-width:0\0)`, the
|
|
1749
|
+
// hack that kept a block for Internet Explorer 9 and 10, held
|
|
1750
|
+
// here as a query that asked nothing, and its rules applied
|
|
1751
|
+
pass = false;
|
|
1752
|
+
}
|
|
1753
|
+
else if ((key === 'min-height' || key === 'min-device-height') &&
|
|
1754
|
+
px !== null) {
|
|
1755
|
+
// the viewport's height, answered live as its width is: a
|
|
1756
|
+
// design that sets its heading's size by the window's height
|
|
1757
|
+
// took the tallest step's at every height
|
|
1758
|
+
condition.minHeight = Math.max(condition.minHeight ?? 0, px);
|
|
1759
|
+
sawHeight = true;
|
|
1760
|
+
}
|
|
1761
|
+
else if ((key === 'max-height' || key === 'max-device-height') &&
|
|
1762
|
+
px !== null) {
|
|
1763
|
+
condition.maxHeight = Math.min(condition.maxHeight ?? Infinity, px);
|
|
1764
|
+
sawHeight = true;
|
|
1765
|
+
}
|
|
1692
1766
|
else if (key === 'prefers-color-scheme') {
|
|
1693
1767
|
// Answered live, from the palette in force: a document dropped
|
|
1694
1768
|
// into a dark application takes its dark branch, and follows the
|
|
@@ -1711,7 +1785,67 @@ export function parseMediaQuery(prelude) {
|
|
|
1711
1785
|
pass = false;
|
|
1712
1786
|
}
|
|
1713
1787
|
else if (key === 'orientation') {
|
|
1714
|
-
|
|
1788
|
+
// the viewport's, as its aspect ratio: portrait where its height
|
|
1789
|
+
// is at least its width (Media Queries 4, 4.5)
|
|
1790
|
+
const orientation = feature[2].trim().toLowerCase();
|
|
1791
|
+
if (orientation === 'portrait') {
|
|
1792
|
+
condition.maxAspect = Math.min(condition.maxAspect ?? Infinity, 1);
|
|
1793
|
+
sawAspect = true;
|
|
1794
|
+
}
|
|
1795
|
+
else if (orientation === 'landscape') {
|
|
1796
|
+
condition.minAspect = Math.max(condition.minAspect ?? 0, 1 + ASPECT_EDGE);
|
|
1797
|
+
sawAspect = true;
|
|
1798
|
+
}
|
|
1799
|
+
else
|
|
1800
|
+
pass = false;
|
|
1801
|
+
}
|
|
1802
|
+
else if (ASPECT_FEATURES.test(key)) {
|
|
1803
|
+
const ratio = ratioOf(feature[2]);
|
|
1804
|
+
if (ratio === null)
|
|
1805
|
+
pass = false;
|
|
1806
|
+
else {
|
|
1807
|
+
if (!key.startsWith('max-')) {
|
|
1808
|
+
condition.minAspect = Math.max(condition.minAspect ?? 0, ratio);
|
|
1809
|
+
}
|
|
1810
|
+
if (!key.startsWith('min-')) {
|
|
1811
|
+
condition.maxAspect = Math.min(condition.maxAspect ?? Infinity, ratio);
|
|
1812
|
+
}
|
|
1813
|
+
sawAspect = true;
|
|
1814
|
+
}
|
|
1815
|
+
}
|
|
1816
|
+
else if (RESOLUTION_FEATURES.has(key)) {
|
|
1817
|
+
const dppx = resolutionOf(feature[2], key.startsWith('-webkit-'));
|
|
1818
|
+
if (dppx === null)
|
|
1819
|
+
pass = false;
|
|
1820
|
+
else {
|
|
1821
|
+
if (!key.includes('max-')) {
|
|
1822
|
+
condition.minResolution = Math.max(condition.minResolution ?? 0, dppx);
|
|
1823
|
+
}
|
|
1824
|
+
if (!key.includes('min-')) {
|
|
1825
|
+
condition.maxResolution = Math.min(condition.maxResolution ?? Infinity, dppx);
|
|
1826
|
+
}
|
|
1827
|
+
sawResolution = true;
|
|
1828
|
+
}
|
|
1829
|
+
}
|
|
1830
|
+
else if (desktopFeature(key, feature[2]) !== true) {
|
|
1831
|
+
// any other feature as a desktop screen with a mouse answers
|
|
1832
|
+
// it, and one nothing knows is false (Media Queries 4, 3.2):
|
|
1833
|
+
// Firefox's and Opera's resolution features, which a design lists
|
|
1834
|
+
// beside WebKit's, held here, and a page at one dot to the pixel
|
|
1835
|
+
// took the rules it keeps for two
|
|
1836
|
+
pass = false;
|
|
1837
|
+
}
|
|
1838
|
+
continue;
|
|
1839
|
+
}
|
|
1840
|
+
const flag = /^\(\s*(-?[a-z][a-z0-9-]*)\s*\)$/i.exec(term);
|
|
1841
|
+
if (flag) {
|
|
1842
|
+
// a feature in the boolean context, `(hover)`: true where its value
|
|
1843
|
+
// is anything but zero or none
|
|
1844
|
+
const key = flag[1].toLowerCase();
|
|
1845
|
+
if (!BOOLEAN_TRUE.has(key) &&
|
|
1846
|
+
!RESOLUTION_FEATURES.has(key) &&
|
|
1847
|
+
desktopFeature(key, null) !== true) {
|
|
1848
|
+
pass = false;
|
|
1715
1849
|
}
|
|
1716
1850
|
continue;
|
|
1717
1851
|
}
|
|
@@ -1729,11 +1863,20 @@ export function parseMediaQuery(prelude) {
|
|
|
1729
1863
|
// `not` over a scheme is the other scheme. `not` over a width range
|
|
1730
1864
|
// is not expressible as one range; the honest reduction is to decide
|
|
1731
1865
|
// it statically rather than invert it wrongly.
|
|
1732
|
-
if (!sawWidth &&
|
|
1866
|
+
if (!sawWidth &&
|
|
1867
|
+
!sawHeight &&
|
|
1868
|
+
!sawResolution &&
|
|
1869
|
+
!sawAspect &&
|
|
1870
|
+
pass &&
|
|
1871
|
+
condition.scheme) {
|
|
1733
1872
|
out.push({ scheme: condition.scheme === 'dark' ? 'light' : 'dark' });
|
|
1734
1873
|
continue;
|
|
1735
1874
|
}
|
|
1736
|
-
out.push({
|
|
1875
|
+
out.push({
|
|
1876
|
+
staticPass: !sawWidth && !sawHeight && !sawResolution && !sawAspect && pass
|
|
1877
|
+
? false
|
|
1878
|
+
: !pass,
|
|
1879
|
+
});
|
|
1737
1880
|
continue;
|
|
1738
1881
|
}
|
|
1739
1882
|
if (!pass) {
|
|
@@ -1741,6 +1884,9 @@ export function parseMediaQuery(prelude) {
|
|
|
1741
1884
|
continue;
|
|
1742
1885
|
}
|
|
1743
1886
|
if (!sawWidth &&
|
|
1887
|
+
!sawHeight &&
|
|
1888
|
+
!sawResolution &&
|
|
1889
|
+
!sawAspect &&
|
|
1744
1890
|
condition.scheme === undefined &&
|
|
1745
1891
|
condition.min === undefined &&
|
|
1746
1892
|
condition.max === undefined) {
|
|
@@ -1751,13 +1897,239 @@ export function parseMediaQuery(prelude) {
|
|
|
1751
1897
|
}
|
|
1752
1898
|
return out.length ? out : [{ staticPass: true }];
|
|
1753
1899
|
}
|
|
1900
|
+
/**
|
|
1901
|
+
* The properties whose support a `@supports` condition is answered for:
|
|
1902
|
+
* the mask's, which pages test before they draw an icon as a masked colour
|
|
1903
|
+
* and keep a background image under `not` for an engine without them.
|
|
1904
|
+
* Drawn here, and the fallback drawn too, an icon was its image in black
|
|
1905
|
+
* under the mask, over the colour it was meant to be.
|
|
1906
|
+
*/
|
|
1907
|
+
const ANSWERED = new Set([
|
|
1908
|
+
'mask',
|
|
1909
|
+
'mask-image',
|
|
1910
|
+
'mask-repeat',
|
|
1911
|
+
'mask-position',
|
|
1912
|
+
'mask-size',
|
|
1913
|
+
'mask-origin',
|
|
1914
|
+
'mask-clip',
|
|
1915
|
+
].flatMap((name) => [name, `-webkit-${name}`]));
|
|
1916
|
+
/**
|
|
1917
|
+
* Whether a `@supports` condition holds (CSS Conditional 3, 6): true or
|
|
1918
|
+
* false where it turns on declarations of the properties this answers for
|
|
1919
|
+
* (`ANSWERED`), combined by `not`, `and` and `or`; null where it turns on
|
|
1920
|
+
* anything else, or is none, and the block is entered as every one was.
|
|
1921
|
+
* Answering more is not safe without a list of what this draws: Tailwind 4
|
|
1922
|
+
* keeps its variables' starting values under a test for engines without
|
|
1923
|
+
* `@property`, which this is, and false there would drop every shadow and
|
|
1924
|
+
* gradient it writes.
|
|
1925
|
+
*/
|
|
1926
|
+
export function supportsCondition(prelude) {
|
|
1927
|
+
const text = prelude.trim();
|
|
1928
|
+
if (/^not\b/i.test(text)) {
|
|
1929
|
+
const inner = supportsCondition(text.slice(3));
|
|
1930
|
+
return inner === null ? null : !inner;
|
|
1931
|
+
}
|
|
1932
|
+
// the terms at the top level, and the one operator between them
|
|
1933
|
+
const terms = [];
|
|
1934
|
+
let op = '';
|
|
1935
|
+
let depth = 0;
|
|
1936
|
+
let start = 0;
|
|
1937
|
+
for (let i = 0; i < text.length; i += 1) {
|
|
1938
|
+
const c = text[i];
|
|
1939
|
+
if (c === '(')
|
|
1940
|
+
depth += 1;
|
|
1941
|
+
else if (c === ')')
|
|
1942
|
+
depth -= 1;
|
|
1943
|
+
else if (depth === 0 && /\s/.test(c)) {
|
|
1944
|
+
const word = /^\s+(and|or)\s+/i.exec(text.slice(i));
|
|
1945
|
+
if (!word)
|
|
1946
|
+
continue;
|
|
1947
|
+
const next = word[1].toLowerCase();
|
|
1948
|
+
// `and` and `or` mixed without parentheses is no condition
|
|
1949
|
+
if (op && op !== next)
|
|
1950
|
+
return null;
|
|
1951
|
+
op = next;
|
|
1952
|
+
terms.push(text.slice(start, i));
|
|
1953
|
+
i += word[0].length - 1;
|
|
1954
|
+
start = i + 1;
|
|
1955
|
+
}
|
|
1956
|
+
if (depth < 0)
|
|
1957
|
+
return null;
|
|
1958
|
+
}
|
|
1959
|
+
if (terms.length) {
|
|
1960
|
+
terms.push(text.slice(start));
|
|
1961
|
+
const values = terms.map(supportsCondition);
|
|
1962
|
+
if (op === 'and') {
|
|
1963
|
+
if (values.includes(false))
|
|
1964
|
+
return false;
|
|
1965
|
+
return values.includes(null) ? null : true;
|
|
1966
|
+
}
|
|
1967
|
+
if (values.includes(true))
|
|
1968
|
+
return true;
|
|
1969
|
+
return values.includes(null) ? null : false;
|
|
1970
|
+
}
|
|
1971
|
+
// one term: a condition in parentheses, or a declaration in them
|
|
1972
|
+
if (!(text.startsWith('(') && text.endsWith(')')))
|
|
1973
|
+
return null;
|
|
1974
|
+
const inner = text.slice(1, -1).trim();
|
|
1975
|
+
if (inner.startsWith('(') || /^not\b/i.test(inner)) {
|
|
1976
|
+
return supportsCondition(inner);
|
|
1977
|
+
}
|
|
1978
|
+
const declaration = /^([a-z-]+)\s*:\s*(\S[\s\S]*)$/i.exec(inner);
|
|
1979
|
+
if (!declaration || !ANSWERED.has(declaration[1].toLowerCase()))
|
|
1980
|
+
return null;
|
|
1981
|
+
return true;
|
|
1982
|
+
}
|
|
1983
|
+
/**
|
|
1984
|
+
* A `(name: value)` media feature: the whole term, its name, and its value
|
|
1985
|
+
* read to the parenthesis that closes the feature, or null where the term is
|
|
1986
|
+
* no such thing. A value may hold parentheses of its own: MediaWiki's
|
|
1987
|
+
* breakpoints are `(max-width: calc(640px - 1px))`, and a value read to the
|
|
1988
|
+
* first `)` found no feature there — the term was passed over as though it
|
|
1989
|
+
* said nothing, and every narrow-screen rule held at every width.
|
|
1990
|
+
*/
|
|
1991
|
+
/** `aspect-ratio` and the device's, bare or `min-`/`max-`. */
|
|
1992
|
+
const ASPECT_FEATURES = /^(?:min-|max-)?(?:device-)?aspect-ratio$/;
|
|
1993
|
+
/** How far past square a landscape viewport is: any width over the height. */
|
|
1994
|
+
const ASPECT_EDGE = 1e-9;
|
|
1995
|
+
/** A ratio, `16/9` or `16 / 9` or `1.5`, as a number; null for anything
|
|
1996
|
+
* else, or a ratio of nothing. */
|
|
1997
|
+
function ratioOf(value) {
|
|
1998
|
+
const m = /^\s*(\d*\.?\d+)\s*(?:\/\s*(\d*\.?\d+)\s*)?$/.exec(value);
|
|
1999
|
+
if (!m)
|
|
2000
|
+
return null;
|
|
2001
|
+
const ratio = Number(m[1]) / (m[2] === undefined ? 1 : Number(m[2]));
|
|
2002
|
+
return Number.isFinite(ratio) && ratio > 0 ? ratio : null;
|
|
2003
|
+
}
|
|
2004
|
+
/** The resolution features, the standard's and WebKit's, which Chrome
|
|
2005
|
+
* answers; `min--moz-device-pixel-ratio` and `-o-min-device-pixel-ratio`
|
|
2006
|
+
* are no feature of its, and none of this. */
|
|
2007
|
+
const RESOLUTION_FEATURES = new Set([
|
|
2008
|
+
'resolution',
|
|
2009
|
+
'min-resolution',
|
|
2010
|
+
'max-resolution',
|
|
2011
|
+
'-webkit-device-pixel-ratio',
|
|
2012
|
+
'-webkit-min-device-pixel-ratio',
|
|
2013
|
+
'-webkit-max-device-pixel-ratio',
|
|
2014
|
+
]);
|
|
2015
|
+
/** A resolution in dots per CSS pixel: `2dppx`, `2x`, `192dpi`, `75.6dpcm`,
|
|
2016
|
+
* or WebKit's device pixel ratio, a number. Null for anything else. */
|
|
2017
|
+
function resolutionOf(value, ratio) {
|
|
2018
|
+
const m = /^\s*(\d*\.?\d+(?:e[+-]?\d+)?)\s*(dppx|x|dpi|dpcm)?\s*$/i.exec(value);
|
|
2019
|
+
if (!m)
|
|
2020
|
+
return null;
|
|
2021
|
+
const n = Number(m[1]);
|
|
2022
|
+
const unit = (m[2] ?? '').toLowerCase();
|
|
2023
|
+
if (ratio)
|
|
2024
|
+
return unit ? null : n;
|
|
2025
|
+
if (unit === 'dppx' || unit === 'x')
|
|
2026
|
+
return n;
|
|
2027
|
+
if (unit === 'dpi')
|
|
2028
|
+
return n / 96;
|
|
2029
|
+
if (unit === 'dpcm')
|
|
2030
|
+
return (n * 2.54) / 96;
|
|
2031
|
+
return null;
|
|
2032
|
+
}
|
|
2033
|
+
/** The features true in the boolean context whatever the viewport: a
|
|
2034
|
+
* size, a scheme, an orientation, there is always one. */
|
|
2035
|
+
const BOOLEAN_TRUE = new Set([
|
|
2036
|
+
'width',
|
|
2037
|
+
'height',
|
|
2038
|
+
'device-width',
|
|
2039
|
+
'device-height',
|
|
2040
|
+
'aspect-ratio',
|
|
2041
|
+
'orientation',
|
|
2042
|
+
'prefers-color-scheme',
|
|
2043
|
+
]);
|
|
2044
|
+
/**
|
|
2045
|
+
* A media feature as a desktop screen driven by a mouse answers it — the
|
|
2046
|
+
* device `<Html>` draws on — for the features that do not depend on the
|
|
2047
|
+
* viewport: true, false, or null for a feature nothing knows, which is
|
|
2048
|
+
* false (Media Queries 4, 3.2). `value` is null in the boolean context.
|
|
2049
|
+
* The colour is eight bits a component on no palette and no grid; scripts
|
|
2050
|
+
* never run here, so `scripting` is `none`.
|
|
2051
|
+
*/
|
|
2052
|
+
function desktopFeature(key, value) {
|
|
2053
|
+
const v = value?.trim().toLowerCase() ?? null;
|
|
2054
|
+
const numeric = (feature, has) => {
|
|
2055
|
+
const bare = key.replace(/^(min|max)-/, '');
|
|
2056
|
+
if (bare !== feature)
|
|
2057
|
+
return null;
|
|
2058
|
+
if (v === null)
|
|
2059
|
+
return key === feature ? has !== 0 : null;
|
|
2060
|
+
const n = Number(v);
|
|
2061
|
+
if (!Number.isFinite(n))
|
|
2062
|
+
return false;
|
|
2063
|
+
if (key.startsWith('min-'))
|
|
2064
|
+
return has >= n;
|
|
2065
|
+
if (key.startsWith('max-'))
|
|
2066
|
+
return has <= n;
|
|
2067
|
+
return has === n;
|
|
2068
|
+
};
|
|
2069
|
+
const keyword = (answers, bool) => v === null ? bool : (answers[v] ?? false);
|
|
2070
|
+
switch (key) {
|
|
2071
|
+
case 'hover':
|
|
2072
|
+
case 'any-hover':
|
|
2073
|
+
return keyword({ hover: true, none: false }, true);
|
|
2074
|
+
case 'pointer':
|
|
2075
|
+
case 'any-pointer':
|
|
2076
|
+
return keyword({ fine: true, coarse: false, none: false }, true);
|
|
2077
|
+
case 'update':
|
|
2078
|
+
return keyword({ fast: true, slow: false, none: false }, true);
|
|
2079
|
+
case 'overflow-block':
|
|
2080
|
+
case 'overflow-inline':
|
|
2081
|
+
return keyword({ scroll: true }, true);
|
|
2082
|
+
case 'scan':
|
|
2083
|
+
return false;
|
|
2084
|
+
case 'color-gamut':
|
|
2085
|
+
return keyword({ srgb: true }, true);
|
|
2086
|
+
case 'dynamic-range':
|
|
2087
|
+
case 'video-dynamic-range':
|
|
2088
|
+
return keyword({ standard: true }, true);
|
|
2089
|
+
case 'prefers-contrast':
|
|
2090
|
+
case 'prefers-reduced-transparency':
|
|
2091
|
+
case 'prefers-reduced-data':
|
|
2092
|
+
return keyword({ 'no-preference': true }, false);
|
|
2093
|
+
case 'forced-colors':
|
|
2094
|
+
return keyword({ none: true }, false);
|
|
2095
|
+
case 'scripting':
|
|
2096
|
+
return keyword({ none: true }, false);
|
|
2097
|
+
case 'display-mode':
|
|
2098
|
+
return keyword({ browser: true }, true);
|
|
2099
|
+
case '-webkit-transform-3d':
|
|
2100
|
+
return v === null || v === '1';
|
|
2101
|
+
}
|
|
2102
|
+
return (numeric('color', 8) ??
|
|
2103
|
+
numeric('monochrome', 0) ??
|
|
2104
|
+
numeric('color-index', 0) ??
|
|
2105
|
+
numeric('grid', 0));
|
|
2106
|
+
}
|
|
2107
|
+
function mediaFeature(term) {
|
|
2108
|
+
const m = /^\(\s*([a-z-]+)\s*:([\s\S]*)\)$/i.exec(term);
|
|
2109
|
+
if (!m)
|
|
2110
|
+
return null;
|
|
2111
|
+
let depth = 0;
|
|
2112
|
+
for (const c of m[2]) {
|
|
2113
|
+
if (c === '(')
|
|
2114
|
+
depth += 1;
|
|
2115
|
+
else if (c === ')' && --depth < 0)
|
|
2116
|
+
return null;
|
|
2117
|
+
}
|
|
2118
|
+
const value = m[2].trim();
|
|
2119
|
+
return depth === 0 && value ? [term, m[1], value] : null;
|
|
2120
|
+
}
|
|
1754
2121
|
/** A `@media` width is compared with the viewport in CSS pixels — the
|
|
1755
2122
|
* cascade divides the device width by the scale before asking — so the
|
|
1756
2123
|
* thresholds parse at scale 1 whatever panel the document lands on. */
|
|
1757
2124
|
const ZERO_UNITS = { em: 16, rem: 16, vw: 0, vh: 0, scale: 1 };
|
|
1758
2125
|
/** Whether a rule's `@media` blocks all hold at this viewport width, under
|
|
1759
2126
|
* this colour scheme. */
|
|
1760
|
-
export function mediaMatches(media, width, scheme = 'light'
|
|
2127
|
+
export function mediaMatches(media, width, scheme = 'light',
|
|
2128
|
+
/** The viewport's height in CSS pixels; a test of it holds at no height
|
|
2129
|
+
* where none is given. */
|
|
2130
|
+
height = NaN,
|
|
2131
|
+
/** The display's scale, device pixels to the CSS pixel. */
|
|
2132
|
+
resolution = 1) {
|
|
1761
2133
|
if (!media)
|
|
1762
2134
|
return true;
|
|
1763
2135
|
for (const block of media) {
|
|
@@ -1770,6 +2142,12 @@ export function mediaMatches(media, width, scheme = 'light') {
|
|
|
1770
2142
|
}
|
|
1771
2143
|
if ((c.min === undefined || width >= c.min) &&
|
|
1772
2144
|
(c.max === undefined || width <= c.max) &&
|
|
2145
|
+
(c.minHeight === undefined || height >= c.minHeight) &&
|
|
2146
|
+
(c.maxHeight === undefined || height <= c.maxHeight) &&
|
|
2147
|
+
(c.minResolution === undefined || resolution >= c.minResolution) &&
|
|
2148
|
+
(c.minAspect === undefined || width >= c.minAspect * height) &&
|
|
2149
|
+
(c.maxAspect === undefined || width <= c.maxAspect * height) &&
|
|
2150
|
+
(c.maxResolution === undefined || resolution <= c.maxResolution) &&
|
|
1773
2151
|
(c.scheme === undefined || c.scheme === scheme)) {
|
|
1774
2152
|
any = true;
|
|
1775
2153
|
}
|