@ng-native/fabric 0.6.0 → 0.7.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 +5 -0
- package/dist/css.js +39 -2
- package/dist/css.js.map +1 -1
- package/dist/engine.d.ts +25 -0
- package/dist/engine.js +193 -17
- package/dist/engine.js.map +1 -1
- package/dist/transition.d.ts +25 -1
- package/dist/transition.js +88 -21
- package/dist/transition.js.map +1 -1
- package/package.json +1 -1
package/dist/engine.d.ts
CHANGED
|
@@ -303,6 +303,10 @@ export interface EngineNode extends HostNode {
|
|
|
303
303
|
committedUnder: EngineNode | null;
|
|
304
304
|
/** The hoisted views this node keeps committed for, by element name. See `HoistOptions`. */
|
|
305
305
|
kept?: Map<string, KeptHoist>;
|
|
306
|
+
/** On a text field, the row aligned by baseline that takes a baseline from it: `lineBaseline`. */
|
|
307
|
+
onBaseline?: EngineNode;
|
|
308
|
+
/** On such a row, the fields it has marked, which it unmarks when they are no longer its own. */
|
|
309
|
+
baselineFields?: Set<EngineNode>;
|
|
306
310
|
/** Commit this node again with its children so Fabric measures it again. `remeasureText`. */
|
|
307
311
|
remeasure?: true;
|
|
308
312
|
/**
|
|
@@ -1254,6 +1258,27 @@ export declare class Engine implements HostEngine {
|
|
|
1254
1258
|
* that colour as a number and throws on a string, taking the whole surface down with it.
|
|
1255
1259
|
*/
|
|
1256
1260
|
private processFilters;
|
|
1261
|
+
/**
|
|
1262
|
+
* Mark the text field each box of a row aligned by baseline takes its baseline from, before
|
|
1263
|
+
* the field is merged, and unmark it when the row is aligned another way.
|
|
1264
|
+
*/
|
|
1265
|
+
private noteBaselineFields;
|
|
1266
|
+
private onBaselineOf;
|
|
1267
|
+
/**
|
|
1268
|
+
* Have the text a row aligned by baseline takes a baseline from measured again, where that
|
|
1269
|
+
* text is inside one of the row's boxes and the row is committed again. React Native keeps
|
|
1270
|
+
* what a paragraph measured on the one copy of its node that was measured, and Yoga copies a
|
|
1271
|
+
* node it lays out around: a row that is laid out again asks a box for its baseline, the box
|
|
1272
|
+
* asks the paragraph in it, and a copy that was never measured works it out then, on a node
|
|
1273
|
+
* that is by then not to be changed. A debug build stops there. Committed to be measured
|
|
1274
|
+
* again (`remeasure`), the paragraph is measured in this commit and has the answer.
|
|
1275
|
+
*
|
|
1276
|
+
* ponytail: the first box in the flow at each level, which is the one Yoga asks unless
|
|
1277
|
+
* another is aligned by baseline itself. A row a commit lays out again without the engine
|
|
1278
|
+
* cloning it, as its room changing does, is not reached: clone on a layout event if one is
|
|
1279
|
+
* seen to stop there.
|
|
1280
|
+
*/
|
|
1281
|
+
private freshBaselines;
|
|
1257
1282
|
/**
|
|
1258
1283
|
* Copy a list of gradients, running every stop's colour through the host's converter.
|
|
1259
1284
|
*
|
package/dist/engine.js
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
import { boundDeclaration, faded, fills, inlineInherited, setsInherited, StyleResolver, usesActive, elementsAtEnd, placeReadElsewhere, siblingReach, } from "./css.js";
|
|
11
11
|
import { applyAria } from "./aria-props.js";
|
|
12
12
|
import { STYLED_ELEMENTS } from "./element-styles.js";
|
|
13
|
-
import { animationEvent, bezier, interpolate, readsInheritedColour, sample, step, tracksOf, } from "./transition.js";
|
|
13
|
+
import { animationEvent, bezier, interpolate, readsInheritedColour, sample, step, steppedKeys, tracksOf, } from "./transition.js";
|
|
14
14
|
import { isFormsInput } from "./forms-inputs.js";
|
|
15
15
|
import { transformList } from "./inline-transform.js";
|
|
16
16
|
import { tokenFromValue } from "./inline-token.js";
|
|
@@ -389,6 +389,33 @@ const VIRTUAL_TEXT = 'VirtualText';
|
|
|
389
389
|
const DEFAULT_VIEW = 'View';
|
|
390
390
|
/** A top-level text, the one view that aligns its lines. A nested text is a `VirtualText`. */
|
|
391
391
|
const PARAGRAPH = 'Paragraph';
|
|
392
|
+
/**
|
|
393
|
+
* The box Yoga takes a view's baseline from where the view has none of its own: its first child
|
|
394
|
+
* that is laid out in its flow. Words written straight into the view are the paragraph the
|
|
395
|
+
* engine makes around them, and a child that is not displayed has no view to ask.
|
|
396
|
+
*/
|
|
397
|
+
function firstInFlow(node) {
|
|
398
|
+
for (const child of node.children ?? []) {
|
|
399
|
+
// Not the paragraph itself, which holds the words it was made around.
|
|
400
|
+
if (child.kind === 'text' && child.box)
|
|
401
|
+
return child.box === node ? undefined : child.box;
|
|
402
|
+
if (child.kind !== 'element' || ownLayout(child, 'display') === 'none')
|
|
403
|
+
continue;
|
|
404
|
+
if (ownLayout(child, 'position') !== 'absolute')
|
|
405
|
+
return child;
|
|
406
|
+
}
|
|
407
|
+
return undefined;
|
|
408
|
+
}
|
|
409
|
+
const isNode = (node) => node !== undefined;
|
|
410
|
+
/** Whether a row lays a child out among its others, and so can take its baseline from it. */
|
|
411
|
+
const inFlow = (child) => child.kind === 'element' && ownLayout(child, 'position') !== 'absolute';
|
|
412
|
+
/** The text field a row's box takes its baseline from: itself, or the first in its flow down. */
|
|
413
|
+
function fieldOnBaseline(item) {
|
|
414
|
+
let at = item;
|
|
415
|
+
while (at?.kind === 'element' && !TEXT_INPUTS.has(viewNameOf(at)))
|
|
416
|
+
at = firstInFlow(at);
|
|
417
|
+
return at?.kind === 'element' ? at : undefined;
|
|
418
|
+
}
|
|
392
419
|
const textDirection = (value) => value === 'ltr' || value === 'rtl' ? value : undefined;
|
|
393
420
|
/**
|
|
394
421
|
* What iOS scales a text's `lineHeight` by: the system text size, capped by the text's own
|
|
@@ -433,6 +460,57 @@ function rowsTall(props, fontScale) {
|
|
|
433
460
|
const lines = rows * line * textScale(props, fontScale);
|
|
434
461
|
props['height'] = edges.reduce((sum, part) => sum + part, lines);
|
|
435
462
|
}
|
|
463
|
+
/** A field's own minimum height: none where it says `auto`, which a web element starts with. */
|
|
464
|
+
const ownMinimum = (minHeight) => (minHeight === 'auto' ? 0 : (minHeight ?? 0));
|
|
465
|
+
/** How tall the system's font is, as a share of its size: its rise over the baseline and fall under. */
|
|
466
|
+
const FONT_LINE = 0.95 + 0.24;
|
|
467
|
+
/**
|
|
468
|
+
* How tall a field is by its line: the line, padding and border of a border-box field, Yoga's
|
|
469
|
+
* default, and its content alone for a content-box one, which Yoga adds the padding and border
|
|
470
|
+
* to itself. In a row aligned by baseline some of the line is kept as padding: `lineBaseline`.
|
|
471
|
+
*/
|
|
472
|
+
function lineBox(props, box, onBaseline, fontScale) {
|
|
473
|
+
const half = onBaseline ? lineBaseline(props, box[0], box, fontScale) : 0;
|
|
474
|
+
if (props['boxSizing'] === 'content-box')
|
|
475
|
+
return box[0] - 2 * half;
|
|
476
|
+
return box.reduce((sum, part) => sum + part, 0);
|
|
477
|
+
}
|
|
478
|
+
/**
|
|
479
|
+
* `lineBaseline` for a field a height sizes: the room is what the height leaves its text, and
|
|
480
|
+
* the field stays that height. A content-box field's height is its content's, so what is now
|
|
481
|
+
* padding comes out of it.
|
|
482
|
+
*/
|
|
483
|
+
function heightBaseline(props, height, onBaseline, fontScale) {
|
|
484
|
+
if (!onBaseline)
|
|
485
|
+
return;
|
|
486
|
+
const edges = [...blockEdge(props, 'Top', 'Start'), ...blockEdge(props, 'Bottom', 'End')];
|
|
487
|
+
if (!edges.every((part) => typeof part === 'number'))
|
|
488
|
+
return;
|
|
489
|
+
const content = props['boxSizing'] === 'content-box';
|
|
490
|
+
const room = content ? height : edges.reduce((left, part) => left - part, height);
|
|
491
|
+
const half = lineBaseline(props, room, [room, ...edges], fontScale);
|
|
492
|
+
if (content)
|
|
493
|
+
props['height'] = height - 2 * half;
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Give a field with its line height left out the baseline of a paragraph in a line as tall, for
|
|
497
|
+
* a field in a row aligned by baseline: half the room the line has over the font is kept as
|
|
498
|
+
* padding over and under the text. React Native says a field's baseline from its text and its
|
|
499
|
+
* top padding, so without this it is the font's own, and the row lifts the paragraphs beside the
|
|
500
|
+
* field to it: a form field's prefix and suffix sit higher than what is typed. Answers the half.
|
|
501
|
+
*
|
|
502
|
+
* ponytail: the font is taken to be as tall as the system's, `FONT_LINE` of its size. Read from
|
|
503
|
+
* the font if a field in another face is seen a point off its prefix.
|
|
504
|
+
*/
|
|
505
|
+
function lineBaseline(props, line, [, top, , bottom], fontScale) {
|
|
506
|
+
const size = props['fontSize'];
|
|
507
|
+
if (typeof size !== 'number')
|
|
508
|
+
return 0;
|
|
509
|
+
const half = Math.max(0, (line - size * textScale(props, fontScale) * FONT_LINE) / 2);
|
|
510
|
+
props['paddingTop'] = top + half;
|
|
511
|
+
props['paddingBottom'] = bottom + half;
|
|
512
|
+
return half;
|
|
513
|
+
}
|
|
436
514
|
/**
|
|
437
515
|
* Centre the text of a single-line text field that has a line height, as Chrome centres an
|
|
438
516
|
* input's, keeping the height the line height gives it.
|
|
@@ -453,7 +531,7 @@ function rowsTall(props, fontScale) {
|
|
|
453
531
|
* height alone for a content-box one. A null `height` is no height. A value that is not a number
|
|
454
532
|
* cannot be added up, and leaves the field as it was.
|
|
455
533
|
*/
|
|
456
|
-
function centreSingleLine(viewName, props, fontScale) {
|
|
534
|
+
function centreSingleLine(viewName, props, fontScale, onBaseline = false) {
|
|
457
535
|
const lineHeight = props['lineHeight'];
|
|
458
536
|
if (!TEXT_INPUTS.has(viewName) || typeof lineHeight !== 'number')
|
|
459
537
|
return;
|
|
@@ -462,6 +540,7 @@ function centreSingleLine(viewName, props, fontScale) {
|
|
|
462
540
|
const height = props['height'];
|
|
463
541
|
if (typeof height === 'number') {
|
|
464
542
|
delete props['lineHeight'];
|
|
543
|
+
heightBaseline(props, height, onBaseline, fontScale);
|
|
465
544
|
return;
|
|
466
545
|
}
|
|
467
546
|
// A percentage is a fixed height only where the parent's is definite, known at layout alone.
|
|
@@ -473,15 +552,12 @@ function centreSingleLine(viewName, props, fontScale) {
|
|
|
473
552
|
const edge = (side, logical) => blockEdge(props, side, logical);
|
|
474
553
|
const line = lineHeight * textScale(props, fontScale);
|
|
475
554
|
const box = [line, ...edge('Top', 'Start'), ...edge('Bottom', 'End')];
|
|
476
|
-
const own = props['minHeight']
|
|
555
|
+
const own = ownMinimum(props['minHeight']);
|
|
477
556
|
const max = props['maxHeight'] ?? Infinity;
|
|
478
557
|
if (![...box, own, max].every((part) => typeof part === 'number'))
|
|
479
558
|
return;
|
|
480
559
|
delete props['lineHeight'];
|
|
481
|
-
|
|
482
|
-
const content = props['boxSizing'] === 'content-box'
|
|
483
|
-
? line
|
|
484
|
-
: box.reduce((sum, part) => sum + part, 0);
|
|
560
|
+
const content = lineBox(props, box, onBaseline, fontScale);
|
|
485
561
|
props['minHeight'] = Math.max(own, Math.min(content, max));
|
|
486
562
|
}
|
|
487
563
|
const NO_STYLE = {};
|
|
@@ -544,6 +620,10 @@ const STRETCHES = new Set([undefined, null, 'auto', 'stretch']);
|
|
|
544
620
|
* kept, since it stops the stretch already.
|
|
545
621
|
*/
|
|
546
622
|
function fitContent(node, props) {
|
|
623
|
+
const capped = {
|
|
624
|
+
row: capAtContent(props, 'width', 'maxWidth'),
|
|
625
|
+
column: capAtContent(props, 'height', 'maxHeight'),
|
|
626
|
+
};
|
|
547
627
|
const width = props['width'] === 'fit-content';
|
|
548
628
|
const height = props['height'] === 'fit-content';
|
|
549
629
|
if (!width && !height)
|
|
@@ -558,11 +638,46 @@ function fitContent(node, props) {
|
|
|
558
638
|
const container = containerOf(parent);
|
|
559
639
|
parent.fitContainer = container;
|
|
560
640
|
const [direction, align] = container.split(' ');
|
|
641
|
+
if (capped[direction === 'row' ? 'row' : 'column'])
|
|
642
|
+
withoutGrowth(props);
|
|
561
643
|
const across = direction === 'row' ? height : width;
|
|
562
644
|
if (across && align === 'stretch' && STRETCHES.has(props['alignSelf'])) {
|
|
563
645
|
props['alignSelf'] = 'flex-start';
|
|
564
646
|
}
|
|
565
647
|
}
|
|
648
|
+
/**
|
|
649
|
+
* A box capped at its content along its container's main axis, where it would grow: a browser
|
|
650
|
+
* clamps a growing item by its maximum, and there is no such cap to hand Yoga. So it does not
|
|
651
|
+
* grow, and starts from its content, which is as far as the cap would let it get. It may still
|
|
652
|
+
* shrink.
|
|
653
|
+
*/
|
|
654
|
+
function withoutGrowth(props) {
|
|
655
|
+
if (typeof props['flex'] === 'number' && props['flex'] > 0) {
|
|
656
|
+
delete props['flex'];
|
|
657
|
+
props['flexShrink'] ??= 1;
|
|
658
|
+
}
|
|
659
|
+
delete props['flexGrow'];
|
|
660
|
+
delete props['flexBasis'];
|
|
661
|
+
}
|
|
662
|
+
/**
|
|
663
|
+
* `max-width: max-content`, and the same of a height: no bigger than its content, which for a
|
|
664
|
+
* box that would fill its container is `fit-content`. Yoga has no such cap. Answers whether the
|
|
665
|
+
* box is the size of its content for it: one that would fill, or one that was `fit-content` as
|
|
666
|
+
* written.
|
|
667
|
+
*
|
|
668
|
+
* ponytail: a size in points is left as it is, since nothing here knows how big the content
|
|
669
|
+
* is. Measure it if a box is ever given both.
|
|
670
|
+
*/
|
|
671
|
+
function capAtContent(props, size, cap) {
|
|
672
|
+
if (props[cap] !== 'max-content')
|
|
673
|
+
return false;
|
|
674
|
+
delete props[cap];
|
|
675
|
+
const own = props[size];
|
|
676
|
+
const fills = own == null || own === 'auto' || (typeof own === 'string' && own.endsWith('%'));
|
|
677
|
+
if (fills)
|
|
678
|
+
props[size] = 'fit-content';
|
|
679
|
+
return fills || own === 'fit-content';
|
|
680
|
+
}
|
|
566
681
|
const isPercent = (value) => typeof value === 'string' && value.endsWith('%');
|
|
567
682
|
/** Whether a `flex-basis` is a length or a percentage of something: not zero, and not `auto`. */
|
|
568
683
|
const isSizedBasis = (basis) => isPercent(basis)
|
|
@@ -1759,6 +1874,16 @@ const now = () => globalThis.performance?.now?.() ?? Date.now();
|
|
|
1759
1874
|
function sameHandles(a, b) {
|
|
1760
1875
|
return a.length === b.length && a.every((handle, i) => handle === b[i]);
|
|
1761
1876
|
}
|
|
1877
|
+
/**
|
|
1878
|
+
* Whether a node could be the element a compound is written for, by its classes alone: its own,
|
|
1879
|
+
* and those of one alternative of each `:is()` on it, which is where Tailwind names a group or
|
|
1880
|
+
* a peer. A compound with no class in either could be any element.
|
|
1881
|
+
*/
|
|
1882
|
+
function couldBe(compound, node) {
|
|
1883
|
+
if (!compound.classes.every((name) => node.classes?.has(name)))
|
|
1884
|
+
return false;
|
|
1885
|
+
return (compound.is ?? []).every((alternatives) => alternatives.some((option) => couldBe(option, node)));
|
|
1886
|
+
}
|
|
1762
1887
|
const FRAME_BUDGET_MS = 8;
|
|
1763
1888
|
export class Engine {
|
|
1764
1889
|
/** Scopes the CSS resolver's memo. Bumped once per commit. */
|
|
@@ -1959,9 +2084,7 @@ export class Engine {
|
|
|
1959
2084
|
const { own, elsewhere } = this.activeUse;
|
|
1960
2085
|
if (!own && !elsewhere.length)
|
|
1961
2086
|
return;
|
|
1962
|
-
|
|
1963
|
-
const asked = elsewhere.some((compound) => compound.classes.every((name) => node.classes?.has(name)));
|
|
1964
|
-
if (asked)
|
|
2087
|
+
if (elsewhere.some((compound) => couldBe(compound, node)))
|
|
1965
2088
|
return this.markProps(node);
|
|
1966
2089
|
node.stateDirty = true;
|
|
1967
2090
|
this.markPath(node.parent ?? node);
|
|
@@ -3054,7 +3177,11 @@ export class Engine {
|
|
|
3054
3177
|
alignMultiline(viewName, style);
|
|
3055
3178
|
rowsTall(style, this.fontScale);
|
|
3056
3179
|
const merged = composeTransform(node, this.animated(node, this.transitioned(node, style)));
|
|
3057
|
-
|
|
3180
|
+
// On iOS: Android's field says the baseline of the line it is sized and centred by.
|
|
3181
|
+
// Still under the row that marked it: a row taken away is not committed again to unmark it.
|
|
3182
|
+
const row = node.onBaseline;
|
|
3183
|
+
const onBaseline = viewName === 'TextInput' && row !== undefined && isWithin(node, row);
|
|
3184
|
+
centreSingleLine(viewName, merged, this.fontScale, onBaseline);
|
|
3058
3185
|
// After a transition, which eases the basis as the basis it was written as.
|
|
3059
3186
|
basisAsSize(node, merged);
|
|
3060
3187
|
// After the basis, which is a size given where it is committed as one.
|
|
@@ -3693,12 +3820,7 @@ export class Engine {
|
|
|
3693
3820
|
return props;
|
|
3694
3821
|
const state = (node.transitions ??= new Map());
|
|
3695
3822
|
const now = this.now();
|
|
3696
|
-
|
|
3697
|
-
// transitioned once it has been seen settling, and one that does not exist is never seen - so
|
|
3698
|
-
// `transition: transform` with no transform until a class adds one would arrive instantly,
|
|
3699
|
-
// which is the commonest way to write one. `all` names nothing, so it keeps the old rule.
|
|
3700
|
-
const named = spec ? Object.keys(spec).filter((key) => key !== 'all') : [];
|
|
3701
|
-
for (const key of new Set([...Object.keys(props), ...named])) {
|
|
3823
|
+
for (const key of steppedKeys(props, spec, state)) {
|
|
3702
3824
|
if (step(state, key, props, spec?.[key] ?? spec?.['all'], now)) {
|
|
3703
3825
|
this.running.add(node);
|
|
3704
3826
|
this.emitTransition(node, 'topTransitionstart', key);
|
|
@@ -3867,6 +3989,58 @@ export class Engine {
|
|
|
3867
3989
|
};
|
|
3868
3990
|
});
|
|
3869
3991
|
}
|
|
3992
|
+
/**
|
|
3993
|
+
* Mark the text field each box of a row aligned by baseline takes its baseline from, before
|
|
3994
|
+
* the field is merged, and unmark it when the row is aligned another way.
|
|
3995
|
+
*/
|
|
3996
|
+
noteBaselineFields(row) {
|
|
3997
|
+
const aligned = ownLayout(row, 'alignItems') === 'baseline';
|
|
3998
|
+
const before = row.baselineFields;
|
|
3999
|
+
if (!aligned && !before)
|
|
4000
|
+
return;
|
|
4001
|
+
const now = new Set(aligned ? row.children.filter(inFlow).map(fieldOnBaseline).filter(isNode) : []);
|
|
4002
|
+
// One that is no longer this row's, and that no other row has marked since.
|
|
4003
|
+
for (const field of before ?? []) {
|
|
4004
|
+
if (!now.has(field) && field.onBaseline === row)
|
|
4005
|
+
this.onBaselineOf(field, undefined);
|
|
4006
|
+
}
|
|
4007
|
+
for (const field of now)
|
|
4008
|
+
if (field.onBaseline !== row)
|
|
4009
|
+
this.onBaselineOf(field, row);
|
|
4010
|
+
row.baselineFields = now.size ? now : undefined;
|
|
4011
|
+
}
|
|
4012
|
+
onBaselineOf(field, row) {
|
|
4013
|
+
field.onBaseline = row;
|
|
4014
|
+
this.markProps(field, false);
|
|
4015
|
+
}
|
|
4016
|
+
/**
|
|
4017
|
+
* Have the text a row aligned by baseline takes a baseline from measured again, where that
|
|
4018
|
+
* text is inside one of the row's boxes and the row is committed again. React Native keeps
|
|
4019
|
+
* what a paragraph measured on the one copy of its node that was measured, and Yoga copies a
|
|
4020
|
+
* node it lays out around: a row that is laid out again asks a box for its baseline, the box
|
|
4021
|
+
* asks the paragraph in it, and a copy that was never measured works it out then, on a node
|
|
4022
|
+
* that is by then not to be changed. A debug build stops there. Committed to be measured
|
|
4023
|
+
* again (`remeasure`), the paragraph is measured in this commit and has the answer.
|
|
4024
|
+
*
|
|
4025
|
+
* ponytail: the first box in the flow at each level, which is the one Yoga asks unless
|
|
4026
|
+
* another is aligned by baseline itself. A row a commit lays out again without the engine
|
|
4027
|
+
* cloning it, as its room changing does, is not reached: clone on a layout event if one is
|
|
4028
|
+
* seen to stop there.
|
|
4029
|
+
*/
|
|
4030
|
+
freshBaselines(row) {
|
|
4031
|
+
if (!row.committed || ownLayout(row, 'alignItems') !== 'baseline')
|
|
4032
|
+
return;
|
|
4033
|
+
for (const item of row.children) {
|
|
4034
|
+
let at = firstInFlow(item);
|
|
4035
|
+
while (at?.committed && committedViewName(at) !== PARAGRAPH)
|
|
4036
|
+
at = firstInFlow(at);
|
|
4037
|
+
if (!at?.committed)
|
|
4038
|
+
continue;
|
|
4039
|
+
at.remeasure = true;
|
|
4040
|
+
for (let up = at; up && up !== row; up = up.parent)
|
|
4041
|
+
up.subtreeDirty = true;
|
|
4042
|
+
}
|
|
4043
|
+
}
|
|
3870
4044
|
/**
|
|
3871
4045
|
* Copy a list of gradients, running every stop's colour through the host's converter.
|
|
3872
4046
|
*
|
|
@@ -3910,6 +4084,8 @@ export class Engine {
|
|
|
3910
4084
|
this.refitChildren(node);
|
|
3911
4085
|
const viewName = committedViewName(node);
|
|
3912
4086
|
this.forgetRenamed(node, viewName);
|
|
4087
|
+
this.noteBaselineFields(node);
|
|
4088
|
+
this.freshBaselines(node);
|
|
3913
4089
|
const childHandles = this.reconcileChildren(node, viewName, style);
|
|
3914
4090
|
noteTouches(node, style);
|
|
3915
4091
|
const previous = node.committed;
|