@ng-native/fabric 0.14.0 → 0.15.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/css.d.ts +47 -5
- package/dist/css.js +219 -51
- package/dist/css.js.map +1 -1
- package/dist/defer-triggers.js +2 -8
- package/dist/defer-triggers.js.map +1 -1
- package/dist/engine.d.ts +62 -17
- package/dist/engine.js +222 -51
- package/dist/engine.js.map +1 -1
- package/dist/fabric.d.ts +1 -1
- package/dist/fabric.js +25 -0
- package/dist/fabric.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/inline-derived-token.js +56 -7
- package/dist/inline-derived-token.js.map +1 -1
- package/dist/node-global.d.ts +9 -0
- package/dist/node-global.js +41 -0
- package/dist/node-global.js.map +1 -0
- package/dist/relative-colour.d.ts +2 -2
- package/dist/relative-colour.js +4 -0
- package/dist/relative-colour.js.map +1 -1
- package/package.json +1 -1
package/dist/css.d.ts
CHANGED
|
@@ -667,6 +667,8 @@ export declare const styleStats: {
|
|
|
667
667
|
nodesResolved: number;
|
|
668
668
|
/** Rules filed by key selector: each sheet's once, however many sheets come after it. */
|
|
669
669
|
rulesFiled: number;
|
|
670
|
+
/** Nodes asked whether a rule `:has()` was asked for could be for them: see `isFor`. */
|
|
671
|
+
subjectTests: number;
|
|
670
672
|
};
|
|
671
673
|
export declare function resetStyleStats(): void;
|
|
672
674
|
/**
|
|
@@ -721,6 +723,11 @@ export interface PlaceReader {
|
|
|
721
723
|
* from (`.a:first-child + .b`), is that element's own: the rules it matches say.
|
|
722
724
|
*/
|
|
723
725
|
export declare function placeReadElsewhere(sheet: StyleSheet): readonly PlaceReader[];
|
|
726
|
+
/**
|
|
727
|
+
* The props a sheet's rules ask of an element before another in a child list, `[data-on] ~ .x`:
|
|
728
|
+
* those whose change can restyle the elements after it. An id is asked as `nativeID`.
|
|
729
|
+
*/
|
|
730
|
+
export declare function namedBeside(sheet: StyleSheet): ReadonlySet<string>;
|
|
724
731
|
/** One rule in a cascade: the sheet it came from, which `:host` needs, and its weight here. */
|
|
725
732
|
interface RuleEntry {
|
|
726
733
|
readonly rule: StyleRule;
|
|
@@ -789,6 +796,16 @@ export interface Subjects {
|
|
|
789
796
|
* matched again itself. Unset where the rules are only for elements under it.
|
|
790
797
|
*/
|
|
791
798
|
own?: boolean;
|
|
799
|
+
/**
|
|
800
|
+
* In what a class reaches: a rule names it in `:has()`, `.field:has(.on)`, which the boxes
|
|
801
|
+
* above the element that has it are then asked again.
|
|
802
|
+
*/
|
|
803
|
+
beneath?: boolean;
|
|
804
|
+
/**
|
|
805
|
+
* In what a class reaches: a rule names it in `:has(> )` alone, `.field:has(> .on)`, which only
|
|
806
|
+
* the box right above the element that has it is then asked again.
|
|
807
|
+
*/
|
|
808
|
+
parentHas?: boolean;
|
|
792
809
|
}
|
|
793
810
|
/**
|
|
794
811
|
* A box a rule asks `:has()` of that is not the node it styles, `.card:has(.x) .title`, by the
|
|
@@ -801,6 +818,8 @@ export interface HasAbove {
|
|
|
801
818
|
}
|
|
802
819
|
/** Each box a sheet's rules ask `:has()` of above the node they style. */
|
|
803
820
|
export declare function hasAbove(sheet: StyleSheet): readonly HasAbove[];
|
|
821
|
+
/** What all of `each` are for, as one. */
|
|
822
|
+
export declare function joinSubjects(each: readonly Subjects[]): Subjects;
|
|
804
823
|
/** Whether an inline style sets a property children inherit. Allocates nothing: it runs per set. */
|
|
805
824
|
export declare function setsInherited(style: unknown): boolean;
|
|
806
825
|
/**
|
|
@@ -928,8 +947,11 @@ export declare class StyleResolver {
|
|
|
928
947
|
*/
|
|
929
948
|
private readonly deepSheets;
|
|
930
949
|
private readonly deepIndexes;
|
|
931
|
-
/**
|
|
932
|
-
|
|
950
|
+
/**
|
|
951
|
+
* Read the classes a sheet names, once, as soon as any node is given it. One `scoped` to a
|
|
952
|
+
* component or a host asks of its elements for good, global or not.
|
|
953
|
+
*/
|
|
954
|
+
noteSheet(sheet: StyleSheet | null | undefined, scoped?: boolean): void;
|
|
933
955
|
/** The props a selector of some sheet asks about: an id, and each attribute by its name. */
|
|
934
956
|
private readonly named;
|
|
935
957
|
/**
|
|
@@ -937,6 +959,18 @@ export declare class StyleResolver {
|
|
|
937
959
|
* sheet that was ever loaded names it. A sheet loaded later has every element matched again.
|
|
938
960
|
*/
|
|
939
961
|
reads(prop: string): boolean;
|
|
962
|
+
/**
|
|
963
|
+
* By prop, how many sheets in play ask it of an element before another: see `namedBeside`. A
|
|
964
|
+
* global sheet taken away, or replaced, asks no more.
|
|
965
|
+
*/
|
|
966
|
+
private readonly besideNamed;
|
|
967
|
+
private readonly besideNoted;
|
|
968
|
+
/** The sheets a component or a host was given: see `noteSheet`. */
|
|
969
|
+
private readonly scoped;
|
|
970
|
+
private noteBeside;
|
|
971
|
+
private forgetBeside;
|
|
972
|
+
/** Whether a prop changing can change what the elements after its element match. */
|
|
973
|
+
readsBeside(prop: string): boolean;
|
|
940
974
|
private noteReach;
|
|
941
975
|
/** Whether a class's reach names any element under the one that has it. */
|
|
942
976
|
reachesUnder(subjects: Subjects): boolean;
|
|
@@ -947,6 +981,8 @@ export declare class StyleResolver {
|
|
|
947
981
|
* of them and nothing is styled again.
|
|
948
982
|
*/
|
|
949
983
|
reachOf(classes: Iterable<string>): true | Subjects | null;
|
|
984
|
+
/** How far a class reaches by its name, and by each test of the class attribute it answers. */
|
|
985
|
+
private reachesOf;
|
|
950
986
|
/** Whether one of the rules `subjects` stands for could be for a node. */
|
|
951
987
|
isFor(subjects: Subjects, node: StyleTarget): boolean;
|
|
952
988
|
/**
|
|
@@ -972,6 +1008,9 @@ export declare class StyleResolver {
|
|
|
972
1008
|
* change it was marked on the element, its parent's `scope` is the one it was styled under,
|
|
973
1009
|
* and no sheet that could match it has come since. It is being styled again all the same, for
|
|
974
1010
|
* a change of its own that alters nothing under it, or for what it inherits.
|
|
1011
|
+
*
|
|
1012
|
+
* A change beneath it is not one: what it answers `:has()` is asked again, and the elements a
|
|
1013
|
+
* rule asking that of it is for are marked on their own (`markUnderHas`), not all under it.
|
|
975
1014
|
*/
|
|
976
1015
|
private matchesStand;
|
|
977
1016
|
/**
|
|
@@ -1179,9 +1218,12 @@ export declare class StyleResolver {
|
|
|
1179
1218
|
* the compiler writes for the same value in a rule. `token` is the value as a token, which is an
|
|
1180
1219
|
* alias when it is a `var()`; null for any other.
|
|
1181
1220
|
*
|
|
1182
|
-
*
|
|
1183
|
-
*
|
|
1184
|
-
*
|
|
1221
|
+
* A colour made of tokens, `color-mix(in srgb, var(--brand), white 20%)`, is worked out from the
|
|
1222
|
+
* tokens where it is used, as a fallback of the same shape is.
|
|
1223
|
+
*
|
|
1224
|
+
* ponytail: any other value has to be the whole `var()`. One inside a longer value, `calc()`
|
|
1225
|
+
* included, is what the compiler parses at build time and nothing here does; write the sum in a
|
|
1226
|
+
* custom property, `[style.--gap]`, and read that in the stylesheet.
|
|
1185
1227
|
*/
|
|
1186
1228
|
export declare function boundDeclaration(prop: string, token: TokenValue | undefined, on?: string): DeferredDeclaration | null;
|
|
1187
1229
|
/** Whether `text` is a `line-height` below zero, which a browser drops: `-1.5`, `-1em`, `-2px`. */
|
package/dist/css.js
CHANGED
|
@@ -208,12 +208,15 @@ export const styleStats = {
|
|
|
208
208
|
nodesResolved: 0,
|
|
209
209
|
/** Rules filed by key selector: each sheet's once, however many sheets come after it. */
|
|
210
210
|
rulesFiled: 0,
|
|
211
|
+
/** Nodes asked whether a rule `:has()` was asked for could be for them: see `isFor`. */
|
|
212
|
+
subjectTests: 0,
|
|
211
213
|
};
|
|
212
214
|
export function resetStyleStats() {
|
|
213
215
|
styleStats.compoundTests = 0;
|
|
214
216
|
styleStats.ruleTests = 0;
|
|
215
217
|
styleStats.nodesResolved = 0;
|
|
216
218
|
styleStats.rulesFiled = 0;
|
|
219
|
+
styleStats.subjectTests = 0;
|
|
217
220
|
}
|
|
218
221
|
/** A prop's value as an attribute test compares it: in lower case, under the i flag. */
|
|
219
222
|
const attributeText = (actual, test) => test.insensitive ? String(actual).toLowerCase() : String(actual);
|
|
@@ -640,6 +643,36 @@ export function placeReadElsewhere(sheet) {
|
|
|
640
643
|
}
|
|
641
644
|
return known;
|
|
642
645
|
}
|
|
646
|
+
const NAMED_BESIDE = new WeakMap();
|
|
647
|
+
/**
|
|
648
|
+
* The props a sheet's rules ask of an element before another in a child list, `[data-on] ~ .x`:
|
|
649
|
+
* those whose change can restyle the elements after it. An id is asked as `nativeID`.
|
|
650
|
+
*/
|
|
651
|
+
export function namedBeside(sheet) {
|
|
652
|
+
let named = NAMED_BESIDE.get(sheet);
|
|
653
|
+
if (named === undefined) {
|
|
654
|
+
named = new Set();
|
|
655
|
+
for (const rule of sheet.rules) {
|
|
656
|
+
rule.combinators.forEach((joined, at) => {
|
|
657
|
+
if (joined === 'next-sibling' || joined === 'later-sibling') {
|
|
658
|
+
propsNamed(rule.compounds[at], named);
|
|
659
|
+
}
|
|
660
|
+
});
|
|
661
|
+
}
|
|
662
|
+
NAMED_BESIDE.set(sheet, named);
|
|
663
|
+
}
|
|
664
|
+
return named;
|
|
665
|
+
}
|
|
666
|
+
/** Add each prop a compound, or one nested in it at any depth, asks about: an attribute or an id. */
|
|
667
|
+
function propsNamed(compound, into) {
|
|
668
|
+
if (compound.id !== undefined)
|
|
669
|
+
into.add('nativeID');
|
|
670
|
+
for (const test of compound.attributes ?? [])
|
|
671
|
+
into.add(test.name);
|
|
672
|
+
const within = (compound.has ?? []).flatMap((test) => test.any);
|
|
673
|
+
for (const inner of [...nestedCompounds(compound), ...within])
|
|
674
|
+
propsNamed(inner, into);
|
|
675
|
+
}
|
|
643
676
|
/** Whether a compound, or one nested in it at any depth, asks about a place in a child list. */
|
|
644
677
|
function readsPlace(compound) {
|
|
645
678
|
if (compound.nth?.length)
|
|
@@ -1187,6 +1220,13 @@ function importantNames(result, twin) {
|
|
|
1187
1220
|
}
|
|
1188
1221
|
/** What `em` falls back to when nothing in scope has set a font size. The web's default. */
|
|
1189
1222
|
const DEFAULT_FONT_SIZE = 16;
|
|
1223
|
+
/**
|
|
1224
|
+
* The rules a node matched, to style it from again: for a change above it, and not for one of
|
|
1225
|
+
* its own or beneath it, which can change what it matches.
|
|
1226
|
+
*/
|
|
1227
|
+
function rulesKept(cached, node) {
|
|
1228
|
+
return node.ownDirty || node.hasDirty ? undefined : cached.rules;
|
|
1229
|
+
}
|
|
1190
1230
|
/** Shared empty result. Never handed out anywhere that mutates it. */
|
|
1191
1231
|
const EMPTY = {};
|
|
1192
1232
|
/** Stands in for the parent of a root node, so the comparison needs no null case. */
|
|
@@ -1287,14 +1327,19 @@ function classReach(sheet) {
|
|
|
1287
1327
|
for (const rule of sheet.rules) {
|
|
1288
1328
|
const every = new Set();
|
|
1289
1329
|
collectClasses(rule, every, reads, named);
|
|
1290
|
-
const { own, inside } = classPlaces(rule);
|
|
1330
|
+
const { own, inside, beneath, parentHas } = classPlaces(rule);
|
|
1291
1331
|
for (const name of every) {
|
|
1292
|
-
|
|
1332
|
+
const placed = own.has(name) || inside.has(name) || beneath.has(name) || parentHas.has(name);
|
|
1333
|
+
if (!placed)
|
|
1293
1334
|
classes.set(name, true);
|
|
1294
1335
|
if (own.has(name))
|
|
1295
1336
|
noteOwn(classes, name);
|
|
1296
1337
|
if (inside.has(name))
|
|
1297
1338
|
noteInside(classes, name, rule);
|
|
1339
|
+
if (beneath.has(name))
|
|
1340
|
+
noteBeneath(classes, name, 'beneath');
|
|
1341
|
+
if (parentHas.has(name))
|
|
1342
|
+
noteBeneath(classes, name, 'parentHas');
|
|
1298
1343
|
}
|
|
1299
1344
|
}
|
|
1300
1345
|
reaches.set(sheet, (found = { classes, reads, named }));
|
|
@@ -1310,6 +1355,16 @@ function noteOwn(found, name) {
|
|
|
1310
1355
|
else
|
|
1311
1356
|
found.set(name, { ...noSubjects(), own: true });
|
|
1312
1357
|
}
|
|
1358
|
+
/** Note a rule as one that names a class in `:has()`, or in `:has(> )` alone. */
|
|
1359
|
+
function noteBeneath(found, name, how) {
|
|
1360
|
+
const subjects = found.get(name);
|
|
1361
|
+
if (subjects === true)
|
|
1362
|
+
return;
|
|
1363
|
+
if (subjects)
|
|
1364
|
+
subjects[how] = true;
|
|
1365
|
+
else
|
|
1366
|
+
found.set(name, { ...noSubjects(), [how]: true });
|
|
1367
|
+
}
|
|
1313
1368
|
/** Note a rule as one that names a class as what its element is inside. */
|
|
1314
1369
|
function noteInside(found, name, rule) {
|
|
1315
1370
|
let subjects = found.get(name);
|
|
@@ -1333,8 +1388,6 @@ const noSubjects = () => ({
|
|
|
1333
1388
|
inside: new Set(),
|
|
1334
1389
|
any: false,
|
|
1335
1390
|
});
|
|
1336
|
-
/** The reach of classes that rules are for the element of, and for nothing under it. */
|
|
1337
|
-
const OWN_ALONE = { ...noSubjects(), own: true };
|
|
1338
1391
|
/** Add to `into` what `from` is for. */
|
|
1339
1392
|
function addSubjects(into, from) {
|
|
1340
1393
|
for (const name of from.classes)
|
|
@@ -1346,6 +1399,17 @@ function addSubjects(into, from) {
|
|
|
1346
1399
|
into.any ||= from.any;
|
|
1347
1400
|
if (from.own)
|
|
1348
1401
|
into.own = true;
|
|
1402
|
+
if (from.beneath)
|
|
1403
|
+
into.beneath = true;
|
|
1404
|
+
if (from.parentHas)
|
|
1405
|
+
into.parentHas = true;
|
|
1406
|
+
}
|
|
1407
|
+
/** What all of `each` are for, as one. */
|
|
1408
|
+
export function joinSubjects(each) {
|
|
1409
|
+
const all = noSubjects();
|
|
1410
|
+
for (const one of each)
|
|
1411
|
+
addSubjects(all, one);
|
|
1412
|
+
return all;
|
|
1349
1413
|
}
|
|
1350
1414
|
/**
|
|
1351
1415
|
* Where a rule names each class it names, for the classes it names in no other place than these:
|
|
@@ -1354,21 +1418,29 @@ function addSubjects(into, from) {
|
|
|
1354
1418
|
* it, which are asked of that element;
|
|
1355
1419
|
* - `inside`, as what that element is inside: the classes of a compound before the last, with
|
|
1356
1420
|
* nothing but `>` and a space between there and the element, and those of what `:is(.box *)`
|
|
1357
|
-
* and `:is(.box > *)` put over it
|
|
1421
|
+
* and `:is(.box > *)` put over it;
|
|
1422
|
+
* - `beneath`, inside `:has()`, wherever in the rule that is: what it asks of is under the box
|
|
1423
|
+
* that answers it;
|
|
1424
|
+
* - `parentHas`, of what `:has(> )` asks of the box's children themselves, and nowhere else in
|
|
1425
|
+
* `:has()`: the element is right under that box.
|
|
1358
1426
|
*
|
|
1359
|
-
* A class named anywhere else in the rule is in
|
|
1360
|
-
*
|
|
1427
|
+
* A class named anywhere else in the rule is in none, whatever else names it: beside the element,
|
|
1428
|
+
* inside `:host-context()`, or in `:not()` of a box the element is in. A test of the class
|
|
1429
|
+
* attribute is placed as a class is, by `classTestKey`.
|
|
1361
1430
|
*/
|
|
1362
1431
|
function classPlaces(rule) {
|
|
1363
1432
|
const own = new Set();
|
|
1364
1433
|
const inside = new Set();
|
|
1434
|
+
const beneath = new Set();
|
|
1435
|
+
const parentHas = new Set();
|
|
1365
1436
|
const elsewhere = new Set();
|
|
1437
|
+
const below = { beneath, parentHas, elsewhere };
|
|
1366
1438
|
const last = rule.compounds.length - 1;
|
|
1367
1439
|
let under = true;
|
|
1368
1440
|
for (let index = last; index >= 0; index--) {
|
|
1369
1441
|
const compound = rule.compounds[index];
|
|
1370
1442
|
if (index === last) {
|
|
1371
|
-
placeClasses(compound, own, inside,
|
|
1443
|
+
placeClasses(compound, own, inside, below);
|
|
1372
1444
|
continue;
|
|
1373
1445
|
}
|
|
1374
1446
|
const joined = rule.combinators[index];
|
|
@@ -1376,36 +1448,75 @@ function classPlaces(rule) {
|
|
|
1376
1448
|
// A box the element is under, by its classes and by those it is asked to have or not to,
|
|
1377
1449
|
// `.box:not(.busy) .row`: each is asked of that box, as its own are.
|
|
1378
1450
|
const over = under ? inside : elsewhere;
|
|
1379
|
-
placeClasses(compound, over, over,
|
|
1451
|
+
placeClasses(compound, over, over, below);
|
|
1380
1452
|
}
|
|
1381
1453
|
for (const name of elsewhere) {
|
|
1382
1454
|
own.delete(name);
|
|
1383
1455
|
inside.delete(name);
|
|
1456
|
+
beneath.delete(name);
|
|
1457
|
+
parentHas.delete(name);
|
|
1384
1458
|
}
|
|
1385
|
-
return { own, inside };
|
|
1459
|
+
return { own, inside, beneath, parentHas };
|
|
1386
1460
|
}
|
|
1387
1461
|
/**
|
|
1388
1462
|
* The classes of a compound asked of the element a rule is for, into `at`, and of the compounds
|
|
1389
1463
|
* it puts over that element, into `inside`. What any other part of it names goes `elsewhere`:
|
|
1390
1464
|
* a part read here by name is one this knows the reach of, and one added later is not.
|
|
1391
1465
|
*/
|
|
1392
|
-
function placeClasses(compound, at, inside,
|
|
1393
|
-
const { classes, is, not, ancestors, parents, type: _t, id: _i, root: _r, pseudo: _p, ...rest } = compound;
|
|
1394
|
-
for (const name of classes)
|
|
1466
|
+
function placeClasses(compound, at, inside, below) {
|
|
1467
|
+
const { classes, is, not, ancestors, parents, attributes, has, type: _t, id: _i, root: _r, pseudo: _p, ...rest } = compound;
|
|
1468
|
+
for (const name of namesOf(classes, attributes))
|
|
1395
1469
|
at.add(name);
|
|
1396
1470
|
for (const alternatives of is ?? []) {
|
|
1397
1471
|
for (const option of alternatives)
|
|
1398
|
-
placeClasses(option, at, inside,
|
|
1472
|
+
placeClasses(option, at, inside, below);
|
|
1399
1473
|
}
|
|
1400
1474
|
for (const excluded of not ?? [])
|
|
1401
|
-
placeClasses(excluded, at, inside,
|
|
1475
|
+
placeClasses(excluded, at, inside, below);
|
|
1402
1476
|
// What is over the element is over it whichever of these said so, and what is over that is too.
|
|
1403
1477
|
for (const above of [...(ancestors ?? []), ...(parents ?? [])]) {
|
|
1404
|
-
placeClasses(above, inside, inside,
|
|
1478
|
+
placeClasses(above, inside, inside, below);
|
|
1405
1479
|
}
|
|
1406
|
-
|
|
1407
|
-
collectClasses(rest, elsewhere, []);
|
|
1480
|
+
placeHas(has, below);
|
|
1481
|
+
collectClasses(rest, below.elsewhere, []);
|
|
1408
1482
|
}
|
|
1483
|
+
/**
|
|
1484
|
+
* The classes `:has()` asks of what is under the box that answers it, into `beneath`, wherever
|
|
1485
|
+
* in the rule it is written, or into `parentHas` for what `:has(> )` asks of the box's children.
|
|
1486
|
+
* One it can ask of what is above the box goes `elsewhere`: `:is()` in `:has()` is not relative,
|
|
1487
|
+
* so the `.night` of `:has(:is(.night .cell))` can be any element over the cell.
|
|
1488
|
+
*/
|
|
1489
|
+
function placeHas(tests, below) {
|
|
1490
|
+
for (const test of tests ?? []) {
|
|
1491
|
+
const into = test.child ? below.parentHas : below.beneath;
|
|
1492
|
+
for (const compound of test.any)
|
|
1493
|
+
placeBeneath(compound, into, below);
|
|
1494
|
+
}
|
|
1495
|
+
}
|
|
1496
|
+
/** `placeHas` for one compound of a `:has()` argument, whose own classes go `into`. */
|
|
1497
|
+
function placeBeneath(compound, into, below) {
|
|
1498
|
+
const { classes, attributes, is, not, has, type: _t, id: _i, root: _r, pseudo: _p, ...rest } = compound;
|
|
1499
|
+
for (const name of namesOf(classes, attributes))
|
|
1500
|
+
into.add(name);
|
|
1501
|
+
for (const alternatives of is ?? []) {
|
|
1502
|
+
for (const option of alternatives)
|
|
1503
|
+
placeBeneath(option, into, below);
|
|
1504
|
+
}
|
|
1505
|
+
for (const excluded of not ?? [])
|
|
1506
|
+
placeBeneath(excluded, into, below);
|
|
1507
|
+
placeHas(has, below);
|
|
1508
|
+
collectClasses(rest, below.elsewhere, []);
|
|
1509
|
+
}
|
|
1510
|
+
/** A compound's classes, and its tests of the class attribute, which are asked as its classes are. */
|
|
1511
|
+
function namesOf(classes, attributes) {
|
|
1512
|
+
const tests = attributes?.filter((test) => test.name === 'class');
|
|
1513
|
+
return tests?.length ? [...classes, ...tests.map(classTestKey)] : classes;
|
|
1514
|
+
}
|
|
1515
|
+
/**
|
|
1516
|
+
* A test of the class attribute, `[class^="p-"]`, by a name no class can have: it has a reach
|
|
1517
|
+
* as a class does, for what any class it answers can restyle.
|
|
1518
|
+
*/
|
|
1519
|
+
const classTestKey = (test) => `\0${test.operator ?? ''}${test.insensitive ? 'i' : ''}\0${test.value ?? ''}`;
|
|
1409
1520
|
/** What a rule declares, which names no element. */
|
|
1410
1521
|
const DECLARED = new Set(['declarations', 'important', 'tokens']);
|
|
1411
1522
|
/**
|
|
@@ -1425,8 +1536,10 @@ function collectClasses(value, into, reads, named) {
|
|
|
1425
1536
|
if (Array.isArray(part.attributes)) {
|
|
1426
1537
|
for (const test of part.attributes) {
|
|
1427
1538
|
named?.add(test.name);
|
|
1428
|
-
if (test.name
|
|
1429
|
-
|
|
1539
|
+
if (test.name !== 'class')
|
|
1540
|
+
continue;
|
|
1541
|
+
reads.push(test);
|
|
1542
|
+
into.add(classTestKey(test));
|
|
1430
1543
|
}
|
|
1431
1544
|
}
|
|
1432
1545
|
for (const [key, inner] of Object.entries(value)) {
|
|
@@ -1725,8 +1838,11 @@ export class StyleResolver {
|
|
|
1725
1838
|
const at = replacing ? this.addedSheets.indexOf(replacing) : -1;
|
|
1726
1839
|
if (at === -1)
|
|
1727
1840
|
this.addedSheets.push(sheet);
|
|
1728
|
-
else
|
|
1841
|
+
else {
|
|
1729
1842
|
this.addedSheets[at] = sheet;
|
|
1843
|
+
this.forgetBeside(replacing);
|
|
1844
|
+
}
|
|
1845
|
+
this.noteBeside(sheet);
|
|
1730
1846
|
// One added at the end is filed after what is there. One in another's place files them all again.
|
|
1731
1847
|
if (at !== -1)
|
|
1732
1848
|
this.filed = null;
|
|
@@ -1753,7 +1869,7 @@ export class StyleResolver {
|
|
|
1753
1869
|
/** How far each class named by the sheets met so far reaches: see `classReach`. */
|
|
1754
1870
|
reach = new Map();
|
|
1755
1871
|
/** The tests of the `class` attribute itself in those sheets, which any class may answer. */
|
|
1756
|
-
classTests =
|
|
1872
|
+
classTests = new Map();
|
|
1757
1873
|
noted = new WeakSet();
|
|
1758
1874
|
/**
|
|
1759
1875
|
* The sheets with a rule written with `::ng-deep`, which is for what is under the component
|
|
@@ -1761,9 +1877,17 @@ export class StyleResolver {
|
|
|
1761
1877
|
*/
|
|
1762
1878
|
deepSheets = new Set();
|
|
1763
1879
|
deepIndexes = new WeakMap();
|
|
1764
|
-
/**
|
|
1765
|
-
|
|
1766
|
-
|
|
1880
|
+
/**
|
|
1881
|
+
* Read the classes a sheet names, once, as soon as any node is given it. One `scoped` to a
|
|
1882
|
+
* component or a host asks of its elements for good, global or not.
|
|
1883
|
+
*/
|
|
1884
|
+
noteSheet(sheet, scoped = false) {
|
|
1885
|
+
if (!sheet)
|
|
1886
|
+
return;
|
|
1887
|
+
if (scoped)
|
|
1888
|
+
this.scoped.add(sheet);
|
|
1889
|
+
this.noteBeside(sheet);
|
|
1890
|
+
if (this.noted.has(sheet))
|
|
1767
1891
|
return;
|
|
1768
1892
|
this.noted.add(sheet);
|
|
1769
1893
|
if (sheet.rules.some((rule) => rule.deep))
|
|
@@ -1771,7 +1895,8 @@ export class StyleResolver {
|
|
|
1771
1895
|
const { classes, reads, named } = classReach(sheet);
|
|
1772
1896
|
for (const [name, how] of classes)
|
|
1773
1897
|
this.noteReach(name, how);
|
|
1774
|
-
|
|
1898
|
+
for (const test of reads)
|
|
1899
|
+
this.classTests.set(classTestKey(test), test);
|
|
1775
1900
|
for (const name of named)
|
|
1776
1901
|
this.named.add(name);
|
|
1777
1902
|
}
|
|
@@ -1784,6 +1909,37 @@ export class StyleResolver {
|
|
|
1784
1909
|
reads(prop) {
|
|
1785
1910
|
return this.named.has(prop);
|
|
1786
1911
|
}
|
|
1912
|
+
/**
|
|
1913
|
+
* By prop, how many sheets in play ask it of an element before another: see `namedBeside`. A
|
|
1914
|
+
* global sheet taken away, or replaced, asks no more.
|
|
1915
|
+
*/
|
|
1916
|
+
besideNamed = new Map();
|
|
1917
|
+
besideNoted = new WeakSet();
|
|
1918
|
+
/** The sheets a component or a host was given: see `noteSheet`. */
|
|
1919
|
+
scoped = new WeakSet();
|
|
1920
|
+
noteBeside(sheet) {
|
|
1921
|
+
if (this.besideNoted.has(sheet))
|
|
1922
|
+
return;
|
|
1923
|
+
this.besideNoted.add(sheet);
|
|
1924
|
+
for (const name of namedBeside(sheet)) {
|
|
1925
|
+
this.besideNamed.set(name, (this.besideNamed.get(name) ?? 0) + 1);
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
forgetBeside(sheet) {
|
|
1929
|
+
if (this.scoped.has(sheet) || !this.besideNoted.delete(sheet))
|
|
1930
|
+
return;
|
|
1931
|
+
for (const name of namedBeside(sheet)) {
|
|
1932
|
+
const left = this.besideNamed.get(name) - 1;
|
|
1933
|
+
if (left)
|
|
1934
|
+
this.besideNamed.set(name, left);
|
|
1935
|
+
else
|
|
1936
|
+
this.besideNamed.delete(name);
|
|
1937
|
+
}
|
|
1938
|
+
}
|
|
1939
|
+
/** Whether a prop changing can change what the elements after its element match. */
|
|
1940
|
+
readsBeside(prop) {
|
|
1941
|
+
return this.besideNamed.has(prop);
|
|
1942
|
+
}
|
|
1787
1943
|
noteReach(name, how) {
|
|
1788
1944
|
const had = this.reach.get(name);
|
|
1789
1945
|
if (had === true)
|
|
@@ -1807,28 +1963,29 @@ export class StyleResolver {
|
|
|
1807
1963
|
* of them and nothing is styled again.
|
|
1808
1964
|
*/
|
|
1809
1965
|
reachOf(classes) {
|
|
1810
|
-
let
|
|
1811
|
-
let own = false;
|
|
1966
|
+
let found = null;
|
|
1812
1967
|
for (const name of classes) {
|
|
1813
|
-
const how
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1968
|
+
for (const how of this.reachesOf(name)) {
|
|
1969
|
+
if (how === true)
|
|
1970
|
+
return true;
|
|
1971
|
+
addSubjects((found ??= noSubjects()), how);
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1974
|
+
return found;
|
|
1975
|
+
}
|
|
1976
|
+
/** How far a class reaches by its name, and by each test of the class attribute it answers. */
|
|
1977
|
+
*reachesOf(name) {
|
|
1978
|
+
const how = this.reach.get(name);
|
|
1979
|
+
if (how)
|
|
1980
|
+
yield how;
|
|
1981
|
+
for (const [key, test] of this.classTests) {
|
|
1982
|
+
if (answers(test, name))
|
|
1983
|
+
yield this.reach.get(key) ?? true;
|
|
1823
1984
|
}
|
|
1824
|
-
if (!under)
|
|
1825
|
-
return own ? OWN_ALONE : null;
|
|
1826
|
-
if (own)
|
|
1827
|
-
under.own = true;
|
|
1828
|
-
return under;
|
|
1829
1985
|
}
|
|
1830
1986
|
/** Whether one of the rules `subjects` stands for could be for a node. */
|
|
1831
1987
|
isFor(subjects, node) {
|
|
1988
|
+
styleStats.subjectTests++;
|
|
1832
1989
|
return writtenFor(subjects, node);
|
|
1833
1990
|
}
|
|
1834
1991
|
/**
|
|
@@ -1860,6 +2017,7 @@ export class StyleResolver {
|
|
|
1860
2017
|
if (at === -1)
|
|
1861
2018
|
return false;
|
|
1862
2019
|
this.addedSheets.splice(at, 1);
|
|
2020
|
+
this.forgetBeside(sheet);
|
|
1863
2021
|
this.filed = null;
|
|
1864
2022
|
this.additions.length = 0;
|
|
1865
2023
|
this.generation = ++generations;
|
|
@@ -1919,8 +2077,7 @@ export class StyleResolver {
|
|
|
1919
2077
|
return this.unstyled(node, epoch, parent, parentInherited, scope, parentScope);
|
|
1920
2078
|
}
|
|
1921
2079
|
styleStats.nodesResolved++;
|
|
1922
|
-
|
|
1923
|
-
const rules = stands && !node.ownDirty ? cached.rules : undefined;
|
|
2080
|
+
const rules = stands ? rulesKept(cached, node) : undefined;
|
|
1924
2081
|
const matched = found ?? rules ?? this.matchedBy(node);
|
|
1925
2082
|
const parentTokens = parent ? parent.tokens : this.tokensOnRoot;
|
|
1926
2083
|
this.heir(node, parent, matched);
|
|
@@ -1938,11 +2095,13 @@ export class StyleResolver {
|
|
|
1938
2095
|
* change it was marked on the element, its parent's `scope` is the one it was styled under,
|
|
1939
2096
|
* and no sheet that could match it has come since. It is being styled again all the same, for
|
|
1940
2097
|
* a change of its own that alters nothing under it, or for what it inherits.
|
|
2098
|
+
*
|
|
2099
|
+
* A change beneath it is not one: what it answers `:has()` is asked again, and the elements a
|
|
2100
|
+
* rule asking that of it is for are marked on their own (`markUnderHas`), not all under it.
|
|
1941
2101
|
*/
|
|
1942
2102
|
matchesStand(cached, node, parentScope) {
|
|
1943
2103
|
return (cached !== null &&
|
|
1944
2104
|
!node.styleDirty &&
|
|
1945
|
-
!node.hasDirty &&
|
|
1946
2105
|
!node.stateDirty &&
|
|
1947
2106
|
cached.scope !== SHARED_SCOPE &&
|
|
1948
2107
|
parentScope !== SHARED_SCOPE &&
|
|
@@ -3298,14 +3457,17 @@ function boundKind(prop) {
|
|
|
3298
3457
|
* the compiler writes for the same value in a rule. `token` is the value as a token, which is an
|
|
3299
3458
|
* alias when it is a `var()`; null for any other.
|
|
3300
3459
|
*
|
|
3301
|
-
*
|
|
3302
|
-
*
|
|
3303
|
-
*
|
|
3460
|
+
* A colour made of tokens, `color-mix(in srgb, var(--brand), white 20%)`, is worked out from the
|
|
3461
|
+
* tokens where it is used, as a fallback of the same shape is.
|
|
3462
|
+
*
|
|
3463
|
+
* ponytail: any other value has to be the whole `var()`. One inside a longer value, `calc()`
|
|
3464
|
+
* included, is what the compiler parses at build time and nothing here does; write the sum in a
|
|
3465
|
+
* custom property, `[style.--gap]`, and read that in the stylesheet.
|
|
3304
3466
|
*/
|
|
3305
3467
|
export function boundDeclaration(prop, token, on) {
|
|
3306
|
-
if (!token?.alias)
|
|
3307
|
-
return null;
|
|
3308
3468
|
const kind = boundKind(prop);
|
|
3469
|
+
if (!token?.alias)
|
|
3470
|
+
return derivedColour(prop, token, kind, on);
|
|
3309
3471
|
const [reference, ...alternatives] = aliasesOf(token);
|
|
3310
3472
|
for (; token?.alias; token = token.fallback)
|
|
3311
3473
|
;
|
|
@@ -3362,6 +3524,12 @@ export function boundRelativeLength(prop, text, on) {
|
|
|
3362
3524
|
compute: { unit: 'em', factor: Number(unitless[1]), multiple: true },
|
|
3363
3525
|
};
|
|
3364
3526
|
}
|
|
3527
|
+
/** A bound colour made of tokens, worked out where it is used; null for any other value. */
|
|
3528
|
+
function derivedColour(prop, token, kind, on) {
|
|
3529
|
+
if (!token || kind !== 'color' || !isDerived(token))
|
|
3530
|
+
return null;
|
|
3531
|
+
return { props: [prop], ...(on === undefined ? {} : { on }), kind, fallbackToken: token };
|
|
3532
|
+
}
|
|
3365
3533
|
/** The names a `var()` tries in turn: its own, then each `var()` nested as its fallback. */
|
|
3366
3534
|
function aliasesOf(token) {
|
|
3367
3535
|
const names = [];
|