@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/src/html/css/values.ts
CHANGED
|
@@ -102,7 +102,7 @@ export interface UnitContext {
|
|
|
102
102
|
em: number;
|
|
103
103
|
/** The root element's `font-size`. */
|
|
104
104
|
rem: number;
|
|
105
|
-
/** Viewport, for `vw`/`vh`/`vmin`/`vmax
|
|
105
|
+
/** Viewport, for `vw`/`vh`/`vmin`/`vmax` and their kin (`viewportUnit`). */
|
|
106
106
|
vw: number;
|
|
107
107
|
vh: number;
|
|
108
108
|
/** Device pixels per CSS pixel — the display scale. */
|
|
@@ -131,9 +131,37 @@ export interface UnitContext {
|
|
|
131
131
|
const NUMBER_SRC = '[+-]?(?:\\d*\\.\\d+|\\d+)(?:e[+-]?\\d+)?';
|
|
132
132
|
|
|
133
133
|
const LENGTH_RE = new RegExp(
|
|
134
|
-
`^(${NUMBER_SRC})(px|em|rem|pt|pc|in|cm|mm|ex|ch|lh|rlh|
|
|
134
|
+
`^(${NUMBER_SRC})(px|em|rem|pt|pc|in|cm|mm|ex|ch|lh|rlh|[sld]?v(?:w|h|i|b|min|max)|q|%)?$`,
|
|
135
135
|
);
|
|
136
136
|
|
|
137
|
+
/**
|
|
138
|
+
* The viewport unit a viewport-percentage length is (CSS Values 4, 6.1.2),
|
|
139
|
+
* or null for another unit. The small, large and dynamic viewports —
|
|
140
|
+
* `svh`, `lvh`, `dvh` and their kin — are the one viewport here, as they
|
|
141
|
+
* are on a desktop, where no toolbar comes and goes over the page; and the
|
|
142
|
+
* inline and block axes, `vi` and `vb`, are the width and the height of
|
|
143
|
+
* the horizontal writing mode every document here is laid out in.
|
|
144
|
+
*/
|
|
145
|
+
export function viewportUnit(
|
|
146
|
+
unit: string,
|
|
147
|
+
): 'vw' | 'vh' | 'vmin' | 'vmax' | null {
|
|
148
|
+
const u = unit.toLowerCase();
|
|
149
|
+
const bare = /^[sld]v/.test(u) ? u.slice(1) : u;
|
|
150
|
+
switch (bare) {
|
|
151
|
+
case 'vw':
|
|
152
|
+
case 'vi':
|
|
153
|
+
return 'vw';
|
|
154
|
+
case 'vh':
|
|
155
|
+
case 'vb':
|
|
156
|
+
return 'vh';
|
|
157
|
+
case 'vmin':
|
|
158
|
+
case 'vmax':
|
|
159
|
+
return bare;
|
|
160
|
+
default:
|
|
161
|
+
return null;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
137
165
|
const NUMBER_RE = new RegExp(`^${NUMBER_SRC}$`, 'i');
|
|
138
166
|
|
|
139
167
|
/** A math function: `calc()`, `min()`, `max()` or `clamp()`. */
|
|
@@ -166,7 +194,7 @@ export function parseLength(
|
|
|
166
194
|
});
|
|
167
195
|
}
|
|
168
196
|
const n = Number(m[1]);
|
|
169
|
-
const unit = m[2];
|
|
197
|
+
const unit = m[2] && (viewportUnit(m[2]) ?? m[2]);
|
|
170
198
|
// a zero needs no unit however it is written — `-0`, `+0`, `0.0`
|
|
171
199
|
if (!unit) return n === 0 ? 0 : bareIsPx ? n * ctx.scale : null;
|
|
172
200
|
if (unit === '%') return { pct: n };
|
package/src/html/css/vars.ts
CHANGED
|
@@ -245,7 +245,7 @@ function findVar(value: string, from: number): number {
|
|
|
245
245
|
|
|
246
246
|
/** The `)` that closes a bracket opened just before `from`, strings and
|
|
247
247
|
* brackets inside it passed over; -1 where none does. */
|
|
248
|
-
function closingParen(value: string, from: number): number {
|
|
248
|
+
export function closingParen(value: string, from: number): number {
|
|
249
249
|
let depth = 0;
|
|
250
250
|
for (let i = from; i < value.length; i += 1) {
|
|
251
251
|
const c = value[i];
|
|
@@ -326,7 +326,7 @@ function topLevel(value: string, ch: string): number {
|
|
|
326
326
|
}
|
|
327
327
|
|
|
328
328
|
/** The first comma not inside a bracket or a string, or -1. */
|
|
329
|
-
function topLevelComma(value: string): number {
|
|
329
|
+
export function topLevelComma(value: string): number {
|
|
330
330
|
let depth = 0;
|
|
331
331
|
for (let i = 0; i < value.length; i += 1) {
|
|
332
332
|
const c = value[i];
|
package/src/html/dom.ts
CHANGED
|
@@ -342,7 +342,9 @@ export class HtmlSource {
|
|
|
342
342
|
tag === 'image' ||
|
|
343
343
|
tag === 'object' ||
|
|
344
344
|
tag === 'embed' ||
|
|
345
|
-
tag === 'video'
|
|
345
|
+
tag === 'video' ||
|
|
346
|
+
(tag === 'input' &&
|
|
347
|
+
(attr(el, 'type') ?? '').trim().toLowerCase() === 'image')
|
|
346
348
|
) {
|
|
347
349
|
if (imageUrlOf(el)) facts.resources.push(el);
|
|
348
350
|
} else if (tag === 'title' && facts.title === null) {
|
|
@@ -572,15 +574,51 @@ function createParser(): { parser: Parser; handler: DomHandler } {
|
|
|
572
574
|
withStartIndices: false,
|
|
573
575
|
withEndIndices: false,
|
|
574
576
|
});
|
|
575
|
-
const parser = new
|
|
577
|
+
const parser = new DocumentParser(handler, {
|
|
576
578
|
lowerCaseTags: true,
|
|
577
579
|
lowerCaseAttributeNames: true,
|
|
578
|
-
|
|
580
|
+
// HTML closes an element written `<x/>` only where it is void, and so
|
|
581
|
+
// closed anyway, or in SVG or MathML (HTML 13.2.6.5, "acknowledge the
|
|
582
|
+
// self-closing flag"). A `<div/>` or an `<a href="" /*target="_blank"*/>`
|
|
583
|
+
// — melbcss.com's, a comment that is no comment in a tag — opens an
|
|
584
|
+
// element like any other, and closing it left the link's text outside
|
|
585
|
+
// the link.
|
|
586
|
+
recognizeSelfClosing: false,
|
|
579
587
|
decodeEntities: true,
|
|
580
588
|
});
|
|
581
589
|
return { parser, handler };
|
|
582
590
|
}
|
|
583
591
|
|
|
592
|
+
/**
|
|
593
|
+
* htmlparser2's parser, deciding a `/>` from the context its tag was read
|
|
594
|
+
* in, as HTML's does. htmlparser2 decides from the context the tag opens,
|
|
595
|
+
* and an integration point — SVG's `<title>`, `<desc>` and
|
|
596
|
+
* `<foreignObject>`, MathML's `<mi>` and its kin — opens an HTML one, so
|
|
597
|
+
* an `<svg><title/><path/>` took its path into the title.
|
|
598
|
+
*/
|
|
599
|
+
class DocumentParser extends Parser {
|
|
600
|
+
private _foreignTag = false;
|
|
601
|
+
private _acknowledging = false;
|
|
602
|
+
|
|
603
|
+
override isInForeignContext(): boolean {
|
|
604
|
+
return this._acknowledging || super.isInForeignContext();
|
|
605
|
+
}
|
|
606
|
+
|
|
607
|
+
override onopentagname(start: number, endIndex: number): void {
|
|
608
|
+
this._foreignTag = this.isInForeignContext();
|
|
609
|
+
super.onopentagname(start, endIndex);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
override onselfclosingtag(endIndex: number): void {
|
|
613
|
+
this._acknowledging = this._foreignTag;
|
|
614
|
+
try {
|
|
615
|
+
super.onselfclosingtag(endIndex);
|
|
616
|
+
} finally {
|
|
617
|
+
this._acknowledging = false;
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
|
|
584
622
|
/**
|
|
585
623
|
* Whether a `media` attribute is one a screen honours. Deliberately not a
|
|
586
624
|
* media-query engine: `screen`, `all` and an empty list apply, `print` and
|
package/src/html/fonts.ts
CHANGED
|
@@ -35,6 +35,18 @@
|
|
|
35
35
|
// keyed by a family list, the text layouts', the metrics', ntk's, that the
|
|
36
36
|
// text has to be set again.
|
|
37
37
|
//
|
|
38
|
+
// **A face the text engine cannot set is not registered.** A face is drawn by
|
|
39
|
+
// the engine, and an engine can read a file it cannot draw every weight of:
|
|
40
|
+
// ntk cuts an instance out of a variable face for the weight and the size a
|
|
41
|
+
// style asks for, and fontkit, which does the cutting, could not cut one out
|
|
42
|
+
// of a WOFF2 — the container nearly every variable web font is served in.
|
|
43
|
+
// The throw came out of the first text layout in the family, and the
|
|
44
|
+
// document it took down was nextjs.org's blog, for Geist. So a face is asked
|
|
45
|
+
// for an instance once, before it is registered (`refusal`), and one the
|
|
46
|
+
// engine refuses is a source that did not load: the next is tried, and with
|
|
47
|
+
// none left the family stays out of the list and the text is set in the
|
|
48
|
+
// next one, as a browser sets it when it cannot use a font.
|
|
49
|
+
//
|
|
38
50
|
// A family split by `unicode-range` is registered a name per range, since the
|
|
39
51
|
// font manager picks among one name's faces by weight and slant alone, and
|
|
40
52
|
// the range that holds the most of the document's characters goes first: the
|
|
@@ -46,7 +58,7 @@
|
|
|
46
58
|
// anywhere in the app (react-x11's `loadFont` says so), and nothing is ever
|
|
47
59
|
// unregistered — the font manager has no way to. A session that visits many
|
|
48
60
|
// sites keeps their faces, one registration per distinct declaration.
|
|
49
|
-
import { loadFont } from 'react-x11';
|
|
61
|
+
import { loadFont, openFont } from 'react-x11';
|
|
50
62
|
import type { Element } from 'domhandler';
|
|
51
63
|
|
|
52
64
|
import type { FontFaceRule } from './css/parse.js';
|
|
@@ -126,6 +138,8 @@ interface Registry {
|
|
|
126
138
|
/** Faces being loaded, by `faceKey`, so a second document waits for the
|
|
127
139
|
* first document's request rather than making its own. */
|
|
128
140
|
pending: Map<string, Promise<boolean>>;
|
|
141
|
+
/** Whether a face the engine refused has been said (`warnRefused`). */
|
|
142
|
+
warned: boolean;
|
|
129
143
|
}
|
|
130
144
|
|
|
131
145
|
const REGISTRIES = new WeakMap<object, Registry>();
|
|
@@ -138,6 +152,7 @@ function registryOf(app: object): Registry {
|
|
|
138
152
|
names: new Map(),
|
|
139
153
|
ready: new Set(),
|
|
140
154
|
pending: new Map(),
|
|
155
|
+
warned: false,
|
|
141
156
|
};
|
|
142
157
|
REGISTRIES.set(app, registry);
|
|
143
158
|
}
|
|
@@ -493,12 +508,12 @@ export class WebFonts implements FontFamilies {
|
|
|
493
508
|
}
|
|
494
509
|
if (isPromise(answer)) {
|
|
495
510
|
answer.then(
|
|
496
|
-
(result) => after(this._register(face, result)),
|
|
511
|
+
(result) => after(this._register(face, result, source.url)),
|
|
497
512
|
() => after(false),
|
|
498
513
|
);
|
|
499
514
|
return 'waiting';
|
|
500
515
|
}
|
|
501
|
-
if (this._register(face, answer)) {
|
|
516
|
+
if (this._register(face, answer, source.url)) {
|
|
502
517
|
finish(true);
|
|
503
518
|
if (sync) face.state = 'ready';
|
|
504
519
|
else this._settled(face, true);
|
|
@@ -529,12 +544,24 @@ export class WebFonts implements FontFamilies {
|
|
|
529
544
|
/** Register a face's bytes under its group's name. False when the host
|
|
530
545
|
* declined, or the font manager could not read them — a `.woff2` on
|
|
531
546
|
* macOS, whose CoreText reads no such container, or a file that is not a
|
|
532
|
-
* font — and
|
|
533
|
-
|
|
547
|
+
* font — or read them and cannot set text in them (`refusal`), and the
|
|
548
|
+
* next source is tried. */
|
|
549
|
+
private _register(
|
|
550
|
+
face: Face,
|
|
551
|
+
result: ResourceResult | null,
|
|
552
|
+
url: string,
|
|
553
|
+
): boolean {
|
|
534
554
|
if (this._destroyed || !this._app || result?.kind !== 'font') return false;
|
|
535
555
|
const { weight, style } = face.rule;
|
|
556
|
+
const app = this._app as Parameters<typeof loadFont>[0];
|
|
536
557
|
try {
|
|
537
|
-
loadFont
|
|
558
|
+
// `loadFont` opens the file first too, and finds this one opened
|
|
559
|
+
const refused = refusal(app, openFont(app, result.bytes), this._fallback);
|
|
560
|
+
if (refused !== null) {
|
|
561
|
+
warnRefused(registryOf(this._app), url, refused);
|
|
562
|
+
return false;
|
|
563
|
+
}
|
|
564
|
+
loadFont(app, result.bytes, {
|
|
538
565
|
family: face.group.name,
|
|
539
566
|
// a range is registered at the weight nearest regular in it: the
|
|
540
567
|
// font manager picks among a group's faces by distance from one
|
|
@@ -560,6 +587,89 @@ export class WebFonts implements FontFamilies {
|
|
|
560
587
|
}
|
|
561
588
|
}
|
|
562
589
|
|
|
590
|
+
/** The slice of an opened face `refusal` reads: react-x11's `Font`. */
|
|
591
|
+
interface OpenedFace {
|
|
592
|
+
variationAxes?: Record<string, { min: number; default: number; max: number }>;
|
|
593
|
+
variation?(settings: Record<string, number>): unknown;
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/** The axes a style moves without naming one: ntk sets `wght` from the
|
|
597
|
+
* weight and `opsz` from the size (its `docs/fonts.md`), and nothing here
|
|
598
|
+
* hands it a `font-variation-settings`. A face with neither is set as its
|
|
599
|
+
* file has it, whatever else varies in it. */
|
|
600
|
+
const DRIVEN_AXES = ['wght', 'opsz'];
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* Why the text engine cannot set text in an opened face, or null when it
|
|
604
|
+
* can: the face is asked for the instance a layout will ask it for, at the
|
|
605
|
+
* far end of each axis a style moves, and the answer is the engine's own.
|
|
606
|
+
* What it cost unasked was the document: ntk instantiates inside `match`,
|
|
607
|
+
* so the throw came out of the first layout in the family, at whatever
|
|
608
|
+
* weight was not the file's default.
|
|
609
|
+
*
|
|
610
|
+
* Only an engine that draws through the face is asked. CoreText and
|
|
611
|
+
* DirectWrite move an axis themselves, and the face react-x11 opens there
|
|
612
|
+
* is fontkit's, for an application to read: what it cannot do says nothing
|
|
613
|
+
* about what they draw.
|
|
614
|
+
*/
|
|
615
|
+
export function refusal(
|
|
616
|
+
app: object,
|
|
617
|
+
font: OpenedFace,
|
|
618
|
+
family: string,
|
|
619
|
+
): string | null {
|
|
620
|
+
const axes = font.variationAxes;
|
|
621
|
+
if (!axes || typeof font.variation !== 'function') return null;
|
|
622
|
+
const settings: Record<string, number> = {};
|
|
623
|
+
for (const tag of DRIVEN_AXES) {
|
|
624
|
+
const axis = axes[tag];
|
|
625
|
+
if (!axis) continue;
|
|
626
|
+
const far = axis.max !== axis.default ? axis.max : axis.min;
|
|
627
|
+
if (far !== axis.default) settings[tag] = far;
|
|
628
|
+
}
|
|
629
|
+
if (!Object.keys(settings).length) return null;
|
|
630
|
+
try {
|
|
631
|
+
font.variation(settings);
|
|
632
|
+
return null;
|
|
633
|
+
} catch (error) {
|
|
634
|
+
return instantiates(app, family)
|
|
635
|
+
? String((error as Error)?.message ?? error)
|
|
636
|
+
: null;
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
|
|
640
|
+
/** Whether the engine's faces are cut into instances as an opened one is:
|
|
641
|
+
* the face it matches a family with has `variation`, as ntk's has and a
|
|
642
|
+
* CoreText or DirectWrite one has not. An engine that cannot say — no
|
|
643
|
+
* family to match — is taken to, since what is at stake is the document. */
|
|
644
|
+
function instantiates(app: object, family: string): boolean {
|
|
645
|
+
try {
|
|
646
|
+
const fonts = (app as { fonts?: { match?(family: string): unknown } })
|
|
647
|
+
.fonts;
|
|
648
|
+
const face = fonts?.match?.(family) as OpenedFace | null | undefined;
|
|
649
|
+
return !face || typeof face.variation === 'function';
|
|
650
|
+
} catch {
|
|
651
|
+
return true;
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
/** Said once a connection, in development: a page set in its fallback
|
|
656
|
+
* family looks like a font that never loaded, and this says it did. */
|
|
657
|
+
function warnRefused(registry: Registry, url: string, why: string): void {
|
|
658
|
+
if (registry.warned) return;
|
|
659
|
+
registry.warned = true;
|
|
660
|
+
const g = globalThis as {
|
|
661
|
+
process?: { env?: Record<string, string | undefined> };
|
|
662
|
+
console?: { warn(message: string): void };
|
|
663
|
+
};
|
|
664
|
+
if (g.process?.env?.NODE_ENV === 'production') return;
|
|
665
|
+
g.console?.warn(
|
|
666
|
+
`@react-x11/components: <Html> loaded the font at ${url} and the text ` +
|
|
667
|
+
'engine cannot set text in it, so its family is left out and the text ' +
|
|
668
|
+
'is set in the next one — as it is for every face the engine refuses. ' +
|
|
669
|
+
`A variable font served as WOFF2 is the usual cause.\n${why}`,
|
|
670
|
+
);
|
|
671
|
+
}
|
|
672
|
+
|
|
563
673
|
/** A face's identity within a registered name. */
|
|
564
674
|
function faceKey(name: string, rule: FontFaceRule): string {
|
|
565
675
|
return `${name}\u0000${faceSignature(rule)}`;
|