gesso-core 0.4.2 → 0.5.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/CHANGELOG.md +59 -0
- package/dist/{CanvasSurface-BMOmE_dD.js → CanvasSurface-CDjWI3EH.js} +4417 -2711
- package/dist/CanvasSurface-CDjWI3EH.js.map +1 -0
- package/dist/{index-BiN3WdTh.d.ts → index-DBnLGexp.d.ts} +1303 -460
- package/dist/index.d.ts +2 -2
- package/dist/index.js +609 -87
- package/dist/index.js.map +1 -1
- package/dist/testing.d.ts +13 -1
- package/dist/testing.js +42 -2
- package/dist/testing.js.map +1 -1
- package/package.json +1 -1
- package/dist/CanvasSurface-BMOmE_dD.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as pointerDeviceOf, $a as UiKeyboardEvent, $i as boxShadow, $n as caretRectFor, $r as radialGradient, $t as DEFAULT_FONT_SIZE, A as withOverrideSource, Aa as rgb8, Ai as darkTheme, An as linkRunAtPointIn, Ar as UiProperties, At as edgeField, B as FlexDirection, Ba as writeDeclaredProperty, Bi as withThemeExtension, Bn as isReadOnly, Br as validateSubgrid, Bt as fillTextRects, C as SCROLLBAR_LINGER_MS, Ca as UiBasicColors, Ci as insetsEqual, Cn as isNodeTabStop, Cr as findPropertyDefinition, Ct as offsetAtPointIn, D as formatExplanation, Da as colorsEqual, Di as bandOf, Dn as hasTextLinks, Dr as propertyEffects, Dt as wordRangeIn, E as formatConstraints, Ea as colorValuesEqual, Ei as UiContainerSizeSource, En as clearLinkHover, Er as inheritedPropertyNames, Et as selectionRectsIn, F as clampSize, Fa as UiNode, Fi as defineThemeExtension, Fn as caretVisibleAt, Fr as normalizeStates, Ft as EditableLayout, G as CrossAxisAlignment, Ga as visualState, Gi as densityFactors, Gn as videoFrameSize, Gr as parseTransform, Gt as textMeasureRequest, H as placeGridItems, Ha as UiVisualState, Hi as highContrastColors, Hn as syncEditorValue, Hr as paintValuesEqual, Ht as runCanvasStyleInto, I as constraintsEqual, Ia as DirtyNodeSet, Ii as hasThemeExtension, In as editorFor, Ir as statesEqual, It as applyCanvasTextStyle, J as parseCrossAxisAlignment, Ja as UiBeforeInputEvent, Ji as spacingEqual, Jn as spannedRunsFor, Jr as transformsEqual, Jt as bumpFontStack, K as MainAxisAlignment, Ka as visualStatesEqual, Ki as defaultSpacing, Kn as CharacterCountTextMeasurer, Kr as transform, Kt as textRunBackgrounds, L as tightenConstraints, La as clearOverrideProperty, Li as noThemeExtensions, Ln as editorOf, Lr as validateRole, Lt as buildFontString, M as contentOffset, Ma as createEnvironmentKey, Mi as themesEqual, Mn as CARET_BLINK_MS, Mr as UI_SEMANTIC_STATES, Mt as commandForKey, N as LayoutRecord, Na as findEnvironmentKey, Ni as withContrast, Nn as CARET_WIDTH, Nr as isUiRole, Nt as detectEditingPlatform, O as formatNumber, Oa as normalizeColor, Oi as containerBands, On as linkHoverOf, Or as propertyIsInherited, Ot as adjacentField, P as Constraints, Pa as UiEnvironment, Pi as withDensity, Pn as EDITOR_PROP, Pr as isUiSemanticState, Pt as isPrintable, Q as capturePointer, Qa as UiInputEvent, Qi as BOX_SHADOW_BLUR_REACH, Qn as DEFAULT_LINE_HEIGHT_FACTOR, Qr as linearGradient, Qt as DEFAULT_FONT_FAMILY, R as MAX_MEASURES_PER_CHILD, Ra as overrideSources, Ri as themeExtension, Rn as isEditableNode, Rr as validateStates, Rt as createCanvasTextStyle, S as SCROLLBAR_FADE_MS, Sa as lightColors, Si as UiInsetRegistry, Sn as isNodeSelectable, Sr as closestPropertyName, St as hasDrawnText, T as describeOverrides, Ta as colorToRgba, Ti as observeViewportInsets, Tn as resolveCursor, Tr as inheritedPropertyFlags, Tt as paragraphGeometryFrom, U as sizeGridTracks, Ua as defaultVisualState, Ui as raiseContrast, Un as resolveColorValue, Ur as pathValuesEqual, Ut as runFontString, V as parseFlexDirection, Va as writeOverrideProperty, Vi as contrastRatio, Vn as nextCaretToggle, Vr as inputsEqual, Vt as layoutTextLines, W as AlignContent, Wa as hasVisualState, Wi as relativeLuminance, Wn as isVideoSurface, Wr as UiTransforms, Wt as spanOf, X as CanvasPlatformSurface, Xa as UiFocusEvent, Xi as defaultShadows, Xn as layoutParagraph, Xr as gradientPaint, Xt as fontStackFor, Y as parseMainAxisAlignment, Ya as UiEventType, Yi as spacingSteps, Yn as ELLIPSIS, Yr as MAX_GRADIENT_STOPS, Yt as clearFontStacks, Z as UiPlatformAdapter, Za as UiGestureEvent, Zi as shadowsEqual, Zn as proportionalFontMetrics, Zr as gradientsEqual, Zt as registerFontStack, _ as LABEL_PADDING_X, _a as textContentOf, _i as normalizeBorderRadius, _n as selectionRangeOf, _r as resolveNumber, _t as scrollRange, a as PaintPictureCache, aa as isShapeName, ai as isMinMaxTrack, an as isPaintVisible, ao as UiWheelDeltaMode, ar as offsetForVerticalMove, at as UiPinchRecognizer, b as snapScroll, ba as colorsEqualPalette, bi as propertyValuesEqual, bn as isNodeHitTestable, br as resolveString, bt as scrollbarZoneAt, c as EMPTY_RECORDING, ca as isTypographyRole, ci as percent, cn as resolvePaintState, co as wheelDeltaYOf, cr as graphemeBoundaries, ct as UiKeyboardController, d as tracePathData, da as editableSpansOf, di as UiBorderRadiuses, dn as matchRangesOf, do as UiBinding, dr as nextGraphemeEnd, dt as UiHitTester, ea as boxShadowArraysEqual, ei as validateGradient, en as DEFAULT_FONT_WEIGHT, eo as UiPasteEvent, er as lineIndexAtY, et as prepareInputSurface, f as ScaledImageCache, fa as flattenTextSpans, fi as borderRadius, fn as setMatchRanges, fr as nextWordEnd, ft as SCROLLBAR_HOVER_ZONE, g as paintsAfterChildren, ga as spannedTextOf, gi as borderRadiusValuesEqual, gn as selectableTextOf, gr as resolveBoolean, gt as scrollLeaderOf, h as hasDecorationPhase, ha as spanAtOffset, hi as borderRadiusIsZero, hn as selectableTextNodes, hr as wordRangeAt, ht as SCROLLBAR_THICKNESS, i as traceRoundedRect, ia as defaultShapes, ii as isFrLength, in as createPaintState, io as UiTextChangeEvent, ir as offsetAtX, it as UiGestureRecognizer, j as accumulatedOffsetTo, ja as rgba, ji as lightTheme, jn as setLinkHover, jr as UI_ROLES, jt as editingGroupOf, k as labelNode, ka as parseColor, ki as unknownContainerSize, kn as linkOf, kr as propertyValuesEqualByName, kt as comparePositions, l as PaintRecorder, la as typographyEqual, li as repeat, ln as TEXT_MATCHES_PROP, lo as UiNodeType, lr as lineEndAt, lt as UiPointerController, m as decorationRect, ma as resolvedSpansOf, mi as borderRadiusEqual, mn as clearSelectionRange, mr as previousWordStart, mt as SCROLLBAR_MIN_THUMB, n as createCanvasSurface, na as boxShadowReach, ni as fr, nn as colorToCss, no as UiPointerEvent, nr as lineLimit, nt as UiEditingController, o as paintPictures, oa as shapesEqual, oi as isPercentLength, on as normalizeTextAlign, oo as UiWheelEvent, or as selectionRects, ot as UiWheelController, p as decorationColor, pa as hiddenRangesOf, pi as borderRadiusCorners, pn as TEXT_SELECTION_PROP, pr as previousGraphemeStart, pt as SCROLLBAR_INSET, q as parseAlignContent, qa as MOUSE_POINTER, qi as scaleSpacing, qn as ParagraphTextMeasurer, qr as transformIsIdentity, qt as textRunDecorations, r as Canvas2DRenderer, ra as boxShadowsEqual, ri as isAutoLength, rn as computeObjectFitRect, ro as UiSelectionChangeEvent, rr as offsetAtPoint, rt as UiTouchScroller, s as PaintTarget, sa as defaultTypography, si as minmax, sn as normalizeVerticalAlign, so as noKeyModifiers, sr as EditableTextModel, st as isScrollContainer, t as CanvasSurface, ta as boxShadowRadius, ti as auto, tn as DEFAULT_TEXT_COLOR, to as UiPinchEvent, tr as lineIndexForOffset, tt as touchActionFor, u as replayPaint, ua as defaultTextStyle, ui as resolveLength, un as clearMatchRanges, uo as DirtyFlags, ur as lineStartAt, ut as UiFocusManager, v as drawOverlayShapes, va as textSpansEqual, vi as uniformBorderRadius, vn as setSelectionRange, vr as resolveProperty, vt as scrollbarThumb, w as describeLength, wa as colorToHex, wi as noInsets, wn as isPressable, wr as getPropertyNames, wt as paragraphGeometry, x as LayoutEngine, xa as darkColors, xi as UiEnvironmentKeys, xn as isNodeInert, xr as UiGraph, xt as UiInputDispatcher, y as labelOrigin, ya as textStylesEqual, yi as defineProperty, yn as isNodeFocusable, yr as resolvePropertyByName, yt as scrollbarThumbs, z as isLayoutProtocol, za as resetOverrideWarnings, zi as themeExtensionsEqual, zn as isMultiline, zr as UI_SUBGRID_AXES, zt as drawText } from "./CanvasSurface-CDjWI3EH.js";
|
|
2
2
|
import { BehaviorSubject, EMPTY, Subject, combineLatest, distinctUntilChanged, isObservable as isObservable$1, map, of } from "rxjs";
|
|
3
3
|
//#region src/animation/UiEasing.ts
|
|
4
4
|
/** Progress equals time. What a spinner and a sweep want. */
|
|
@@ -836,11 +836,12 @@ var UiSharedElements = class {
|
|
|
836
836
|
* But it must not disappear *yet*. A claim happens during
|
|
837
837
|
* reconciliation, and the arriving node has no box until the frame
|
|
838
838
|
* lays out — so yielding here leaves a window in which neither
|
|
839
|
-
* element is drawn.
|
|
840
|
-
*
|
|
841
|
-
*
|
|
842
|
-
*
|
|
843
|
-
*
|
|
839
|
+
* element is drawn. The window closes within the frame now, for a
|
|
840
|
+
* geometry morph as for a transform one, but only because the
|
|
841
|
+
* arriving element takes its place in that frame's layout pass; when
|
|
842
|
+
* a geometry morph's box waited for the next frame, a whole frame
|
|
843
|
+
* with neither the old card nor the new one was a flash of the page
|
|
844
|
+
* behind them, and it was exactly that visible.
|
|
844
845
|
*
|
|
845
846
|
* So the caller yields the previous holder at the moment it actually
|
|
846
847
|
* takes its place. Until then both are on screen, in the same
|
|
@@ -1199,7 +1200,7 @@ const PRESS_ONLY = Object.freeze({
|
|
|
1199
1200
|
hover: false,
|
|
1200
1201
|
press: true
|
|
1201
1202
|
});
|
|
1202
|
-
const kind$
|
|
1203
|
+
const kind$5 = defineModifier({
|
|
1203
1204
|
name: "interactive",
|
|
1204
1205
|
attach(host, options) {
|
|
1205
1206
|
let hovered = false;
|
|
@@ -1246,15 +1247,15 @@ const kind$4 = defineModifier({
|
|
|
1246
1247
|
});
|
|
1247
1248
|
/** Hover and press. */
|
|
1248
1249
|
function interactive(options = BOTH) {
|
|
1249
|
-
return kind$
|
|
1250
|
+
return kind$5(options);
|
|
1250
1251
|
}
|
|
1251
1252
|
/** Hover only. */
|
|
1252
1253
|
function hoverable() {
|
|
1253
|
-
return kind$
|
|
1254
|
+
return kind$5(HOVER_ONLY);
|
|
1254
1255
|
}
|
|
1255
1256
|
/** Press only. */
|
|
1256
1257
|
function pressable() {
|
|
1257
|
-
return kind$
|
|
1258
|
+
return kind$5(PRESS_ONLY);
|
|
1258
1259
|
}
|
|
1259
1260
|
/**
|
|
1260
1261
|
* What every Button carries. One shared value, so `sameArgs` matches it
|
|
@@ -1263,7 +1264,7 @@ function pressable() {
|
|
|
1263
1264
|
* that genuinely differ do detach and re-attach it, losing the hover and
|
|
1264
1265
|
* press state with them, which is the reason this one is a constant.
|
|
1265
1266
|
*/
|
|
1266
|
-
const BUTTON_INTERACTION = kind$
|
|
1267
|
+
const BUTTON_INTERACTION = kind$5(BOTH);
|
|
1267
1268
|
function sameStates(a, b) {
|
|
1268
1269
|
if (a.size !== b.size) return false;
|
|
1269
1270
|
for (const state of b) if (!a.has(state)) return false;
|
|
@@ -1769,13 +1770,13 @@ var Host = class {
|
|
|
1769
1770
|
}
|
|
1770
1771
|
this.own(environment.onChange(this.node, listener));
|
|
1771
1772
|
}
|
|
1772
|
-
focus() {
|
|
1773
|
+
focus(options) {
|
|
1773
1774
|
const focus = this.services.focus;
|
|
1774
1775
|
if (focus === void 0) {
|
|
1775
1776
|
warnMissing(this.name, "move focus", "focus");
|
|
1776
1777
|
return;
|
|
1777
1778
|
}
|
|
1778
|
-
focus.focus(this.node);
|
|
1779
|
+
focus.focus(this.node, options);
|
|
1779
1780
|
}
|
|
1780
1781
|
isFocused() {
|
|
1781
1782
|
return this.services.focus?.isFocused(this.node) ?? false;
|
|
@@ -2497,15 +2498,30 @@ var UiGraphBuilder = class {
|
|
|
2497
2498
|
* instance is unchanged and torn down when a property stops
|
|
2498
2499
|
* being reactive.
|
|
2499
2500
|
*/
|
|
2501
|
+
/**
|
|
2502
|
+
* The properties each node's element declared last time, so a render
|
|
2503
|
+
* that stops declaring one takes it off the node.
|
|
2504
|
+
*
|
|
2505
|
+
* Only bindings used to be torn down that way. A plain value stayed:
|
|
2506
|
+
* a conditional that swapped `<scrollview padding={20}>` for a
|
|
2507
|
+
* `<scrollview>` reused the node and kept the padding, and an editor
|
|
2508
|
+
* switching from its source view back to its document came back
|
|
2509
|
+
* twenty pixels narrower. Only what the builder declared is tracked,
|
|
2510
|
+
* so what modifiers and the runtime write on a node is left alone.
|
|
2511
|
+
*/
|
|
2512
|
+
declaredProps = /* @__PURE__ */ new WeakMap();
|
|
2500
2513
|
reconcileProps(node, props, parent) {
|
|
2501
2514
|
this.reconcileTransitions(node, props[TRANSITION_PROP]);
|
|
2502
2515
|
const present = /* @__PURE__ */ new Set();
|
|
2503
2516
|
const presentEvents = /* @__PURE__ */ new Set();
|
|
2504
2517
|
let declaredModifiers;
|
|
2518
|
+
let declaredRef;
|
|
2519
|
+
let hasRef = false;
|
|
2505
2520
|
for (const [property, value] of Object.entries(props)) {
|
|
2506
2521
|
if (property === KEY_PROP) continue;
|
|
2507
2522
|
if (property === REF_PROP) {
|
|
2508
|
-
|
|
2523
|
+
declaredRef = value;
|
|
2524
|
+
hasRef = true;
|
|
2509
2525
|
continue;
|
|
2510
2526
|
}
|
|
2511
2527
|
if (property === MODIFIERS_PROP) {
|
|
@@ -2532,7 +2548,13 @@ var UiGraphBuilder = class {
|
|
|
2532
2548
|
}
|
|
2533
2549
|
for (const binding of this.graph.getBindingsForNode(node)) if (!present.has(binding.property)) this.graph.unbind(binding);
|
|
2534
2550
|
for (const binding of this.graph.getEventBindingsForNode(node)) if (!presentEvents.has(binding.type)) this.graph.unbindEvent(node, binding);
|
|
2551
|
+
const previous = this.declaredProps.get(node);
|
|
2552
|
+
if (previous !== void 0) {
|
|
2553
|
+
for (const property of previous) if (!present.has(property)) this.graph.removeNodeProperty(node, property, propertyEffects(property));
|
|
2554
|
+
}
|
|
2555
|
+
this.declaredProps.set(node, present);
|
|
2535
2556
|
if (node.environment === null && parent?.environment != null) node.environment = this.graph.buildNodeEnvironment(node, parent);
|
|
2557
|
+
if (hasRef) this.reconcileRef(node, declaredRef);
|
|
2536
2558
|
this.reconcileModifiers(node, declaredModifiers);
|
|
2537
2559
|
}
|
|
2538
2560
|
/**
|
|
@@ -3183,6 +3205,9 @@ function lazyList(axis, props, renderItem, grid) {
|
|
|
3183
3205
|
* padding, and a layout that switched arms at 600 px would otherwise
|
|
3184
3206
|
* switch at 600 px of border box and lay itself out in 560.
|
|
3185
3207
|
*
|
|
3208
|
+
* What a subtree builds from the size it reports is laid out on the
|
|
3209
|
+
* same frame, before anything paints; see `UiModifierHost.onLayout`.
|
|
3210
|
+
*
|
|
3186
3211
|
* `Responsive` attaches this for you. Attach it by hand when the
|
|
3187
3212
|
* source has to be reachable somewhere the helper's own children are
|
|
3188
3213
|
* not, and put the same object on the node's `containerSize` prop.
|
|
@@ -3218,9 +3243,15 @@ const sizeContainer = defineModifier({
|
|
|
3218
3243
|
* about it and the thing a media query cannot do: a card in a sidebar
|
|
3219
3244
|
* asks how wide the card is, not how wide the window is.
|
|
3220
3245
|
*
|
|
3221
|
-
* Nothing is written until the node has been laid out once,
|
|
3222
|
-
* first frame
|
|
3223
|
-
*
|
|
3246
|
+
* Nothing is written until the node has been laid out once, but the
|
|
3247
|
+
* first frame is already right: the runtime lays out again before it
|
|
3248
|
+
* paints when a layout listener changes layout (see
|
|
3249
|
+
* `UiModifierHost.onLayout`), so the frame a node first appears on,
|
|
3250
|
+
* and the frame a resize crosses a width on, are drawn with the band's
|
|
3251
|
+
* values. The element's own values are what that first pass measures
|
|
3252
|
+
* with; give it the narrowest band's values as its declared props so a
|
|
3253
|
+
* layout nothing settles (a headless one, a spec driving layout by
|
|
3254
|
+
* hand) starts from the right band.
|
|
3224
3255
|
*/
|
|
3225
3256
|
const breakpoint = defineModifier({
|
|
3226
3257
|
name: "breakpoint",
|
|
@@ -3273,7 +3304,9 @@ const breakpoint = defineModifier({
|
|
|
3273
3304
|
* The first build happens before any layout, when the size is zero, so
|
|
3274
3305
|
* `build` must return something sensible for a container whose room is
|
|
3275
3306
|
* not yet known. Zero picks the narrowest arm, which is the right
|
|
3276
|
-
* guess and also what a phone gets.
|
|
3307
|
+
* guess and also what a phone gets. It is never what a wider container
|
|
3308
|
+
* paints: the first layout reports the real size, the arm for it is
|
|
3309
|
+
* built, and the runtime lays that out before the frame paints.
|
|
3277
3310
|
*/
|
|
3278
3311
|
function Responsive(props, build) {
|
|
3279
3312
|
const { at, as = "column", modifiers, ...rest } = props;
|
|
@@ -4375,6 +4408,12 @@ const MODIFIER_KEYS = /* @__PURE__ */ new Set([
|
|
|
4375
4408
|
* Without that rule an application with a `n` for "new note" becomes an
|
|
4376
4409
|
* application you cannot type the letter n into, which is the failure
|
|
4377
4410
|
* every home-grown key handler eventually ships.
|
|
4411
|
+
*
|
|
4412
|
+
* ## Pressing is not a shortcut
|
|
4413
|
+
*
|
|
4414
|
+
* A bare Enter or Space is skipped while a button or link has focus,
|
|
4415
|
+
* unless the shortcut is that control's own: the control is focused, so
|
|
4416
|
+
* it has the key first, as it would in a browser.
|
|
4378
4417
|
*/
|
|
4379
4418
|
var UiShortcutRegistry = class {
|
|
4380
4419
|
bindings = [];
|
|
@@ -4390,10 +4429,11 @@ var UiShortcutRegistry = class {
|
|
|
4390
4429
|
/** Adds a shortcut. The returned function removes it again. */
|
|
4391
4430
|
register(shortcut) {
|
|
4392
4431
|
const steps = parseShortcut(shortcut.keys);
|
|
4432
|
+
this.platform ??= detectEditingPlatform();
|
|
4393
4433
|
const binding = {
|
|
4394
4434
|
...shortcut,
|
|
4395
4435
|
steps,
|
|
4396
|
-
display: formatShortcut(steps)
|
|
4436
|
+
display: formatShortcut(steps, this.platform)
|
|
4397
4437
|
};
|
|
4398
4438
|
this.bindings.push(binding);
|
|
4399
4439
|
return () => {
|
|
@@ -4434,6 +4474,10 @@ var UiShortcutRegistry = class {
|
|
|
4434
4474
|
*/
|
|
4435
4475
|
handleKey(key, modifiers, focused) {
|
|
4436
4476
|
if (MODIFIER_KEYS.has(key)) return false;
|
|
4477
|
+
if (focused !== null && isTypingInto(focused) && this.isEditingKey(key, modifiers)) {
|
|
4478
|
+
this.pending = [];
|
|
4479
|
+
return false;
|
|
4480
|
+
}
|
|
4437
4481
|
const step = stepFor(key, modifiers);
|
|
4438
4482
|
const at = this.now();
|
|
4439
4483
|
if (this.pending.length > 0 && at - this.pendingAt > this.chordTimeout) this.pending = [];
|
|
@@ -4456,6 +4500,13 @@ var UiShortcutRegistry = class {
|
|
|
4456
4500
|
this.pending = [];
|
|
4457
4501
|
return false;
|
|
4458
4502
|
}
|
|
4503
|
+
platform = null;
|
|
4504
|
+
/** Whether a field would take this key as an edit of its own, rather than as text or as Enter. */
|
|
4505
|
+
isEditingKey(key, modifiers) {
|
|
4506
|
+
this.platform ??= detectEditingPlatform();
|
|
4507
|
+
const command = commandForKey(key, modifiers, this.platform, false);
|
|
4508
|
+
return command !== null && command.kind !== "newline" && command.kind !== "insert";
|
|
4509
|
+
}
|
|
4459
4510
|
/** Forgets a half-typed chord, for a route change or a lost focus. */
|
|
4460
4511
|
reset() {
|
|
4461
4512
|
this.pending = [];
|
|
@@ -4463,17 +4514,20 @@ var UiShortcutRegistry = class {
|
|
|
4463
4514
|
/**
|
|
4464
4515
|
* Whether a binding would fire for a key going to `focused`.
|
|
4465
4516
|
*
|
|
4466
|
-
*
|
|
4467
|
-
* focused node, its own `when` says no,
|
|
4468
|
-
* modifier at all
|
|
4469
|
-
*
|
|
4470
|
-
*
|
|
4517
|
+
* Four things take a shortcut out: its scope does not contain the
|
|
4518
|
+
* focused node, its own `when` says no, for a shortcut with no
|
|
4519
|
+
* modifier at all the focused node is somewhere text is being typed,
|
|
4520
|
+
* and for a bare Enter or Space the focused node is a button that
|
|
4521
|
+
* isn't the shortcut's own. The third keeps a single-letter shortcut
|
|
4522
|
+
* from making a text field unusable; the fourth keeps a list's Enter
|
|
4523
|
+
* from opening a row when the button focused inside it was pressed.
|
|
4471
4524
|
*/
|
|
4472
4525
|
isLive(binding, focused) {
|
|
4473
4526
|
const scope = binding.scope ?? null;
|
|
4474
4527
|
if (scope !== null && (focused === null || !containsNode(scope, focused))) return false;
|
|
4475
4528
|
if (binding.when !== void 0 && !binding.when()) return false;
|
|
4476
4529
|
if (focused !== null && isTypingInto(focused) && binding.steps.every((step) => isBare(step))) return false;
|
|
4530
|
+
if (focused !== null && scope !== focused && isPressing(binding.steps) && isPressable(focused)) return false;
|
|
4477
4531
|
return true;
|
|
4478
4532
|
}
|
|
4479
4533
|
};
|
|
@@ -4508,6 +4562,11 @@ function isTypingInto(node) {
|
|
|
4508
4562
|
for (let current = node; current !== null; current = current.parent) if (current.type === "editable-text" && !isNodeInert(current)) return true;
|
|
4509
4563
|
return false;
|
|
4510
4564
|
}
|
|
4565
|
+
/** A bare Enter or Space on its own: what presses a focused button. */
|
|
4566
|
+
function isPressing(steps) {
|
|
4567
|
+
const [step] = steps;
|
|
4568
|
+
return steps.length === 1 && step !== void 0 && isBare(step) && !step.shift && (step.key === "Enter" || step.key === " ");
|
|
4569
|
+
}
|
|
4511
4570
|
/** A press with no modifier at all: an ordinary character. */
|
|
4512
4571
|
function isBare(step) {
|
|
4513
4572
|
return !step.mod && !step.ctrl && !step.meta && !step.alt;
|
|
@@ -4569,10 +4628,24 @@ function parseStep(text) {
|
|
|
4569
4628
|
* `'Mod+K'` and `'Mod+k'` are the same shortcut, and the browser
|
|
4570
4629
|
* reports whichever the shift state produced. Anything longer than one
|
|
4571
4630
|
* character is a named key (`'Enter'`, `'ArrowUp'`) and keeps its case.
|
|
4631
|
+
*
|
|
4632
|
+
* The space bar is the exception that has to be spelled out. The
|
|
4633
|
+
* platform reports it as `' '`, which a shortcut string cannot contain
|
|
4634
|
+
* because space separates the steps of a chord, so the name `Space`
|
|
4635
|
+
* stands for it. Before this, `'Space'` was kept as the literal name and
|
|
4636
|
+
* never matched a press: the board's keyboard drag in the issue tracker
|
|
4637
|
+
* was the first thing to need it.
|
|
4572
4638
|
*/
|
|
4573
4639
|
function normalizeKey(key) {
|
|
4640
|
+
const named = NAMED_KEYS[key.toLowerCase()];
|
|
4641
|
+
if (named !== void 0) return named;
|
|
4574
4642
|
return key.length === 1 ? key.toLowerCase() : key;
|
|
4575
4643
|
}
|
|
4644
|
+
/** Key names a shortcut string uses for keys it cannot spell. */
|
|
4645
|
+
const NAMED_KEYS = {
|
|
4646
|
+
space: " ",
|
|
4647
|
+
spacebar: " "
|
|
4648
|
+
};
|
|
4576
4649
|
/** Whether the presses so far could still complete this shortcut. */
|
|
4577
4650
|
function matchesPrefix(steps, sequence) {
|
|
4578
4651
|
if (sequence.length > steps.length) return false;
|
|
@@ -4595,15 +4668,29 @@ function stepFor(key, modifiers) {
|
|
|
4595
4668
|
};
|
|
4596
4669
|
}
|
|
4597
4670
|
/**
|
|
4598
|
-
* The shortcut as a palette should print it
|
|
4599
|
-
*
|
|
4600
|
-
* `
|
|
4601
|
-
*
|
|
4602
|
-
*
|
|
4603
|
-
* format the `steps` itself.
|
|
4671
|
+
* The shortcut as a palette should print it, the way the platform
|
|
4672
|
+
* writes its own: `⇧⌘K` on a Mac, where `Mod` is Command, and
|
|
4673
|
+
* `Ctrl+Shift+K` elsewhere, where it is Control. The platform is the
|
|
4674
|
+
* one the editing keys follow (`detectEditingPlatform`, from the user
|
|
4675
|
+
* agent, which a worker can read too).
|
|
4604
4676
|
*/
|
|
4605
|
-
function formatShortcut(steps) {
|
|
4606
|
-
return steps.map(formatStep).join(" ");
|
|
4677
|
+
function formatShortcut(steps, platform = detectEditingPlatform()) {
|
|
4678
|
+
return steps.map((step) => platform === "mac" ? formatMacStep(step) : formatStep(step)).join(" ");
|
|
4679
|
+
}
|
|
4680
|
+
/** In the order the Mac's menus print them: Control, Option, Shift, Command. */
|
|
4681
|
+
function formatMacStep(step) {
|
|
4682
|
+
return `${step.ctrl ? "⌃" : ""}${step.alt ? "⌥" : ""}${step.shift ? "⇧" : ""}${step.mod || step.meta ? "⌘" : ""}${keyName(step.key)}`;
|
|
4683
|
+
}
|
|
4684
|
+
/** The arrows as arrows, which every keyboard prints them as. */
|
|
4685
|
+
const KEY_NAMES = {
|
|
4686
|
+
" ": "Space",
|
|
4687
|
+
ArrowUp: "↑",
|
|
4688
|
+
ArrowDown: "↓",
|
|
4689
|
+
ArrowLeft: "←",
|
|
4690
|
+
ArrowRight: "→"
|
|
4691
|
+
};
|
|
4692
|
+
function keyName(key) {
|
|
4693
|
+
return KEY_NAMES[key] ?? (key.length === 1 ? key.toUpperCase() : key);
|
|
4607
4694
|
}
|
|
4608
4695
|
function formatStep(step) {
|
|
4609
4696
|
const parts = [];
|
|
@@ -4611,7 +4698,7 @@ function formatStep(step) {
|
|
|
4611
4698
|
if (step.meta) parts.push("Meta");
|
|
4612
4699
|
if (step.alt) parts.push("Alt");
|
|
4613
4700
|
if (step.shift) parts.push("Shift");
|
|
4614
|
-
parts.push(
|
|
4701
|
+
parts.push(keyName(step.key));
|
|
4615
4702
|
return parts.join("+");
|
|
4616
4703
|
}
|
|
4617
4704
|
function defaultClock() {
|
|
@@ -4656,6 +4743,8 @@ var UiDragSession = class {
|
|
|
4656
4743
|
zones = [];
|
|
4657
4744
|
current = null;
|
|
4658
4745
|
inside = null;
|
|
4746
|
+
/** Every zone the point is in that would take the payload, winner or not. */
|
|
4747
|
+
hovering = /* @__PURE__ */ new Set();
|
|
4659
4748
|
/** Registers a drop target. The returned function unregisters it. */
|
|
4660
4749
|
addZone(zone) {
|
|
4661
4750
|
this.zones.push(zone);
|
|
@@ -4719,6 +4808,7 @@ var UiDragSession = class {
|
|
|
4719
4808
|
}
|
|
4720
4809
|
const effect = zone.drop(state);
|
|
4721
4810
|
zone.leave();
|
|
4811
|
+
this.unhover();
|
|
4722
4812
|
return {
|
|
4723
4813
|
node: zone.node,
|
|
4724
4814
|
effect
|
|
@@ -4729,6 +4819,12 @@ var UiDragSession = class {
|
|
|
4729
4819
|
this.inside?.leave();
|
|
4730
4820
|
this.inside = null;
|
|
4731
4821
|
this.current = null;
|
|
4822
|
+
this.unhover();
|
|
4823
|
+
}
|
|
4824
|
+
/** Tells every zone the drag was hovering over that it no longer is. */
|
|
4825
|
+
unhover() {
|
|
4826
|
+
for (const zone of this.hovering) zone.hover?.(null);
|
|
4827
|
+
this.hovering.clear();
|
|
4732
4828
|
}
|
|
4733
4829
|
/**
|
|
4734
4830
|
* Turns a shell's file-drop message into an ordinary drag.
|
|
@@ -4779,10 +4875,12 @@ var UiDragSession = class {
|
|
|
4779
4875
|
if (state === null) return;
|
|
4780
4876
|
let best = null;
|
|
4781
4877
|
let bestDepth = -1;
|
|
4878
|
+
const containing = /* @__PURE__ */ new Set();
|
|
4782
4879
|
for (const zone of this.zones) {
|
|
4783
4880
|
if (!zone.accepts(state.payload)) continue;
|
|
4784
4881
|
const box = zone.boxOf();
|
|
4785
4882
|
if (box === null || !contains$1(box, state.x, state.y)) continue;
|
|
4883
|
+
containing.add(zone);
|
|
4786
4884
|
const depth = depthOf(zone.node);
|
|
4787
4885
|
if (depth > bestDepth) {
|
|
4788
4886
|
best = zone;
|
|
@@ -4793,9 +4891,10 @@ var UiDragSession = class {
|
|
|
4793
4891
|
this.inside?.leave();
|
|
4794
4892
|
this.inside = best;
|
|
4795
4893
|
best?.enter(state);
|
|
4796
|
-
|
|
4797
|
-
|
|
4798
|
-
|
|
4894
|
+
} else best?.over(state);
|
|
4895
|
+
for (const zone of this.hovering) if (!containing.has(zone)) zone.hover?.(null);
|
|
4896
|
+
for (const zone of containing) zone.hover?.(state);
|
|
4897
|
+
this.hovering = containing;
|
|
4799
4898
|
}
|
|
4800
4899
|
};
|
|
4801
4900
|
function contains$1(box, x, y) {
|
|
@@ -5007,7 +5106,7 @@ function ringShapes(options) {
|
|
|
5007
5106
|
* costs nothing here because the options of a focus ring do not
|
|
5008
5107
|
* change while it is attached.
|
|
5009
5108
|
*/
|
|
5010
|
-
const kind$
|
|
5109
|
+
const kind$4 = defineModifier({
|
|
5011
5110
|
name: "focusRing",
|
|
5012
5111
|
attach(host, options) {
|
|
5013
5112
|
const shapes = ringShapes(options);
|
|
@@ -5018,7 +5117,7 @@ const kind$3 = defineModifier({
|
|
|
5018
5117
|
host.onFocusChange(sync);
|
|
5019
5118
|
}
|
|
5020
5119
|
});
|
|
5021
|
-
const DEFAULT_RING = kind$
|
|
5120
|
+
const DEFAULT_RING = kind$4(Object.freeze({}));
|
|
5022
5121
|
/**
|
|
5023
5122
|
* The ring, with the theme's own colour and spacing.
|
|
5024
5123
|
*
|
|
@@ -5029,7 +5128,7 @@ const DEFAULT_RING = kind$3(Object.freeze({}));
|
|
|
5029
5128
|
* attachment.
|
|
5030
5129
|
*/
|
|
5031
5130
|
function focusRing(options) {
|
|
5032
|
-
return options === void 0 ? DEFAULT_RING : kind$
|
|
5131
|
+
return options === void 0 ? DEFAULT_RING : kind$4(options);
|
|
5033
5132
|
}
|
|
5034
5133
|
/**
|
|
5035
5134
|
* A border per edge, as paint rather than as layout.
|
|
@@ -5138,24 +5237,62 @@ function borderShapes(options) {
|
|
|
5138
5237
|
//#endregion
|
|
5139
5238
|
//#region src/modifiers/focus.ts
|
|
5140
5239
|
/**
|
|
5141
|
-
*
|
|
5142
|
-
*
|
|
5143
|
-
*
|
|
5240
|
+
* Takes focus the first time the node is laid out.
|
|
5241
|
+
*
|
|
5242
|
+
* The one a dialog needs: an overlay that opens with the caret already
|
|
5243
|
+
* in its first field, without the component that opened it reaching
|
|
5244
|
+
* for a `ref` and a focus store.
|
|
5245
|
+
*
|
|
5246
|
+
* **Why the first layout and not the attach.** A modifier attaches
|
|
5247
|
+
* while its node is still being built, before the builder inserts it
|
|
5248
|
+
* into its parent, so at attach time the node has no parent and is not
|
|
5249
|
+
* under the focus manager's traversal root. `UiFocusManager.focus`
|
|
5250
|
+
* would accept it anyway (it asks whether the node is focusable, not
|
|
5251
|
+
* where it is), and the result would be a focused node that Tab cannot
|
|
5252
|
+
* reach and that no ancestor sees the focus event from. The first
|
|
5253
|
+
* layout is the first moment the node is demonstrably on screen, and
|
|
5254
|
+
* it is the same frame in every case that matters, because a node
|
|
5255
|
+
* mounted into a live tree is laid out on the frame that mounted it.
|
|
5256
|
+
*
|
|
5257
|
+
* It fires once. A node that is autofocused, loses focus to something
|
|
5258
|
+
* the person clicked, and is then laid out again does not steal the
|
|
5259
|
+
* focus back; that would make an autofocus a focus trap.
|
|
5260
|
+
*
|
|
5261
|
+
* A node that cannot take focus is left alone and no error is raised:
|
|
5262
|
+
* `focus()` refuses a node that is inert, not focusable, or outside an
|
|
5263
|
+
* active focus scope, which is exactly the set of cases where an
|
|
5264
|
+
* application would not want the focus moved either.
|
|
5144
5265
|
*/
|
|
5145
|
-
const
|
|
5266
|
+
const kind$3 = defineModifier({
|
|
5146
5267
|
name: "autoFocus",
|
|
5147
|
-
attach(host) {
|
|
5268
|
+
attach(host, options) {
|
|
5148
5269
|
let done = false;
|
|
5149
5270
|
host.onLayout(() => {
|
|
5150
5271
|
if (done) return;
|
|
5151
5272
|
done = true;
|
|
5152
|
-
host.focus();
|
|
5273
|
+
host.focus(options);
|
|
5153
5274
|
});
|
|
5154
5275
|
}
|
|
5155
|
-
})
|
|
5156
|
-
/**
|
|
5157
|
-
|
|
5158
|
-
|
|
5276
|
+
});
|
|
5277
|
+
/**
|
|
5278
|
+
* One shared instance of each, so the arguments keep their identity
|
|
5279
|
+
* across renders and the modifier is never detached and re-attached
|
|
5280
|
+
* (which would autofocus a second time).
|
|
5281
|
+
*/
|
|
5282
|
+
const AUTO_FOCUS = kind$3({});
|
|
5283
|
+
const AUTO_FOCUS_IN_PLACE = kind$3({ preventScroll: true });
|
|
5284
|
+
/**
|
|
5285
|
+
* Takes focus the first time the node is laid out.
|
|
5286
|
+
*
|
|
5287
|
+
* The node is scrolled into view, as focus from code always is, once
|
|
5288
|
+
* the frame's layout has settled. Pass `{ preventScroll: true }` to
|
|
5289
|
+
* leave the page where it is, as `element.focus({ preventScroll: true })`
|
|
5290
|
+
* does: for a region focused when a page opens so a screen reader reads
|
|
5291
|
+
* it, where revealing it would scroll a tall region to a few pixels
|
|
5292
|
+
* short of its own top instead of leaving the page at its start.
|
|
5293
|
+
*/
|
|
5294
|
+
function autoFocus(options = {}) {
|
|
5295
|
+
return options.preventScroll === true ? AUTO_FOCUS_IN_PLACE : AUTO_FOCUS;
|
|
5159
5296
|
}
|
|
5160
5297
|
//#endregion
|
|
5161
5298
|
//#region src/modifiers/clickOutside.ts
|
|
@@ -5485,13 +5622,20 @@ var DropTarget = class {
|
|
|
5485
5622
|
x: state.x,
|
|
5486
5623
|
y: state.y
|
|
5487
5624
|
});
|
|
5488
|
-
this.updateAutoScroll(state);
|
|
5489
5625
|
}
|
|
5490
5626
|
leave() {
|
|
5491
5627
|
for (const property of Object.keys(this.options.over ?? {})) this.host.clear(property);
|
|
5492
|
-
this.stopScrolling();
|
|
5493
5628
|
this.options.onLeave?.();
|
|
5494
5629
|
}
|
|
5630
|
+
/**
|
|
5631
|
+
* Auto-scroll follows the point being inside this zone, not this zone
|
|
5632
|
+
* winning the drop: a list covered in row zones is never the winner,
|
|
5633
|
+
* and still has to scroll when a card is held at its edge.
|
|
5634
|
+
*/
|
|
5635
|
+
hover(state) {
|
|
5636
|
+
if (state === null) this.stopScrolling();
|
|
5637
|
+
else this.updateAutoScroll(state);
|
|
5638
|
+
}
|
|
5495
5639
|
drop(state) {
|
|
5496
5640
|
return this.options.onDrop(state.payload, {
|
|
5497
5641
|
x: state.x,
|
|
@@ -6780,15 +6924,15 @@ var SharedElementController = class {
|
|
|
6780
6924
|
*
|
|
6781
6925
|
* Held rather than called on arrival: see `UiSharedElements.claim`.
|
|
6782
6926
|
* Between claiming a name and taking the departing element's place
|
|
6783
|
-
* there is at least one layout
|
|
6784
|
-
* frame
|
|
6785
|
-
*
|
|
6927
|
+
* there is at least one layout pass — and hiding it up front, on a
|
|
6928
|
+
* frame painted between the two, would leave neither element on
|
|
6929
|
+
* screen, which reads as a flash of the page behind them.
|
|
6786
6930
|
*/
|
|
6787
6931
|
yieldPrevious = null;
|
|
6788
6932
|
yielded = false;
|
|
6789
6933
|
/** Whether a morph is running, so `onMorph` is never told twice. */
|
|
6790
6934
|
morphing = false;
|
|
6791
|
-
/** Set
|
|
6935
|
+
/** Set between a geometry morph writing its first box and that box being laid out. */
|
|
6792
6936
|
geometryTarget = null;
|
|
6793
6937
|
constructor(host, args) {
|
|
6794
6938
|
this.host = host;
|
|
@@ -8294,6 +8438,40 @@ function onDeviceLost(listener) {
|
|
|
8294
8438
|
onDeviceLostListeners.delete(listener);
|
|
8295
8439
|
};
|
|
8296
8440
|
}
|
|
8441
|
+
//#endregion
|
|
8442
|
+
//#region src/rendering/webgpu/WebGPUShader.ts
|
|
8443
|
+
/**
|
|
8444
|
+
* WGSL sources for the two WebGPU pipelines.
|
|
8445
|
+
*
|
|
8446
|
+
* Both draw one unit quad per instance. An instance carries the
|
|
8447
|
+
* rectangle it covers in absolute layout coordinates and the affine
|
|
8448
|
+
* transform that maps those coordinates to logical screen pixels, so
|
|
8449
|
+
* every instance under one node shares the node's transform and the
|
|
8450
|
+
* rectangle is honest — a scrollbar thumb sits where its geometry says.
|
|
8451
|
+
*
|
|
8452
|
+
* Clipping is two-layered. The rectangular part is a scissor set per
|
|
8453
|
+
* draw command. The rounded part is a **clip chain**: a storage buffer
|
|
8454
|
+
* of clipping boxes with corner radii, each holding its parent's index
|
|
8455
|
+
* and the inverse of its own transform. An instance names its
|
|
8456
|
+
* innermost rounded clip; the fragment shader carries the pixel back
|
|
8457
|
+
* into each clip's space up the chain and multiplies their coverages,
|
|
8458
|
+
* so every rounded ancestor applies.
|
|
8459
|
+
*
|
|
8460
|
+
* Edges are anti-aliased by coverage rather than cut by `discard`: a
|
|
8461
|
+
* pixel's alpha is scaled by how far its centre sits inside the shape,
|
|
8462
|
+
* in physical pixels. A box on integer coordinates is still crisp —
|
|
8463
|
+
* every pixel centre is half a pixel from its edge — and rounded
|
|
8464
|
+
* corners match the anti-aliased paths Canvas2D draws.
|
|
8465
|
+
*
|
|
8466
|
+
* A box shadow is a primitive too, drawn analytically: the coverage of
|
|
8467
|
+
* a Gaussian-blurred rounded rectangle is integrated in closed form
|
|
8468
|
+
* across one axis (an error function) and sampled along the other, as
|
|
8469
|
+
* in Evan Wallace's "Fast rounded rectangle shadows". It is exact for
|
|
8470
|
+
* square corners and within a fraction of a percent for round ones,
|
|
8471
|
+
* which is closer than browsers' own blur gets to a Gaussian.
|
|
8472
|
+
*/
|
|
8473
|
+
/** Mirrors `BOX_SHADOW_BLUR_REACH`: a shadow's quad reaches this many blur radii past its shape. */
|
|
8474
|
+
const SHADOW_REACH = BOX_SHADOW_BLUR_REACH;
|
|
8297
8475
|
const SHARED = `
|
|
8298
8476
|
// x: logical width, y: logical height, z: device pixel ratio.
|
|
8299
8477
|
@group(0) @binding(0) var<uniform> uView: vec4f;
|
|
@@ -8438,6 +8616,86 @@ fn gradientColor(index: u32, local: vec2f) -> vec4f {
|
|
|
8438
8616
|
return unpremultiply(previousColor);
|
|
8439
8617
|
}
|
|
8440
8618
|
|
|
8619
|
+
// PrimitiveKind: 0 fill, 1 border, 2 shadow, 3 inset shadow.
|
|
8620
|
+
const KIND_BORDER = 1u;
|
|
8621
|
+
const KIND_SHADOW = 2u;
|
|
8622
|
+
const SHADOW_REACH = ${SHADOW_REACH};
|
|
8623
|
+
|
|
8624
|
+
// Abramowitz and Stegun's approximation, to about 5e-4, for two values.
|
|
8625
|
+
fn erf2(x: vec2f) -> vec2f {
|
|
8626
|
+
let s = sign(x);
|
|
8627
|
+
let a = abs(x);
|
|
8628
|
+
var t = 1.0 + (0.278393 + (0.230389 + 0.078108 * (a * a)) * a) * a;
|
|
8629
|
+
t = t * t;
|
|
8630
|
+
return s - s / (t * t);
|
|
8631
|
+
}
|
|
8632
|
+
|
|
8633
|
+
fn gaussian(x: f32, sigma: f32) -> f32 {
|
|
8634
|
+
return exp(-(x * x) / (2.0 * sigma * sigma)) / (2.5066283 * sigma);
|
|
8635
|
+
}
|
|
8636
|
+
|
|
8637
|
+
// The blurred shape's coverage along x at one height y, both relative
|
|
8638
|
+
// to its centre: an error function across the row the rounded corner
|
|
8639
|
+
// leaves at that height.
|
|
8640
|
+
fn shadowRow(x: f32, y: f32, sigma: f32, corner: f32, halfSize: vec2f) -> f32 {
|
|
8641
|
+
let delta = min(halfSize.y - corner - abs(y), 0.0);
|
|
8642
|
+
let curved = halfSize.x - corner + sqrt(max(0.0, corner * corner - delta * delta));
|
|
8643
|
+
let integral = 0.5 + 0.5 * erf2((x + vec2f(-curved, curved)) * (0.70710678 / sigma));
|
|
8644
|
+
return integral.y - integral.x;
|
|
8645
|
+
}
|
|
8646
|
+
|
|
8647
|
+
// Coverage at a point of a rounded rectangle blurred by a Gaussian of
|
|
8648
|
+
// the given standard deviation. The row integral is weighted by the
|
|
8649
|
+
// Gaussian over the three deviations either side that it reaches.
|
|
8650
|
+
fn blurredRoundedRect(point: vec2f, origin: vec2f, size: vec2f, radius: f32, sigma: f32, dpr: f32) -> f32 {
|
|
8651
|
+
if (size.x <= 0.0 || size.y <= 0.0) {
|
|
8652
|
+
return 0.0;
|
|
8653
|
+
}
|
|
8654
|
+
if (sigma * dpr < 0.25) {
|
|
8655
|
+
// Under a quarter of a device pixel: the sharp shape, anti-aliased.
|
|
8656
|
+
return coverage(roundedRectDistance(point, origin, size, radius), dpr);
|
|
8657
|
+
}
|
|
8658
|
+
let halfSize = size * 0.5;
|
|
8659
|
+
let corner = min(radius, min(halfSize.x, halfSize.y));
|
|
8660
|
+
let p = point - (origin + halfSize);
|
|
8661
|
+
let low = p.y - halfSize.y;
|
|
8662
|
+
let high = p.y + halfSize.y;
|
|
8663
|
+
let first = clamp(-3.0 * sigma, low, high);
|
|
8664
|
+
let last = clamp(3.0 * sigma, low, high);
|
|
8665
|
+
let stride = (last - first) / 4.0;
|
|
8666
|
+
var y = first + stride * 0.5;
|
|
8667
|
+
var value = 0.0;
|
|
8668
|
+
for (var i = 0; i < 4; i = i + 1) {
|
|
8669
|
+
value = value + shadowRow(p.x, p.y - y, sigma, corner, halfSize) * gaussian(y, sigma) * stride;
|
|
8670
|
+
y = y + stride;
|
|
8671
|
+
}
|
|
8672
|
+
return clamp(value, 0.0, 1.0);
|
|
8673
|
+
}
|
|
8674
|
+
|
|
8675
|
+
// A shadow's alpha at a point of its quad; see the instance layout in
|
|
8676
|
+
// WebGPURenderData.ts for what each field holds.
|
|
8677
|
+
fn shadowAlpha(kind: u32, local: vec2f, size: vec2f, radius: f32, blur: f32, shadow: vec4f, dpr: f32) -> f32 {
|
|
8678
|
+
let sigma = blur * 0.5;
|
|
8679
|
+
let offset = shadow.xy;
|
|
8680
|
+
let spread = shadow.z;
|
|
8681
|
+
if (kind == KIND_SHADOW) {
|
|
8682
|
+
// The quad is the blurred shape grown by the blur's reach; the box
|
|
8683
|
+
// sits back by the offset and in by the spread, and hides it.
|
|
8684
|
+
let reach = blur * SHADOW_REACH;
|
|
8685
|
+
let shapeOrigin = vec2f(reach, reach);
|
|
8686
|
+
let shapeSize = size - vec2f(reach, reach) * 2.0;
|
|
8687
|
+
let boxOrigin = shapeOrigin - offset + vec2f(spread, spread);
|
|
8688
|
+
let boxSize = shapeSize - vec2f(spread, spread) * 2.0;
|
|
8689
|
+
let blurred = blurredRoundedRect(local, shapeOrigin, shapeSize, radius, sigma, dpr);
|
|
8690
|
+
return blurred * (1.0 - coverage(roundedRectDistance(local, boxOrigin, boxSize, shadow.w), dpr));
|
|
8691
|
+
}
|
|
8692
|
+
// Inset: the quad is the box; everything but the blurred hole is shadow.
|
|
8693
|
+
let holeOrigin = offset + vec2f(spread, spread);
|
|
8694
|
+
let holeSize = size - vec2f(spread, spread) * 2.0;
|
|
8695
|
+
let inside = coverage(roundedRectDistance(local, vec2f(0.0, 0.0), size, radius), dpr);
|
|
8696
|
+
return inside * (1.0 - blurredRoundedRect(local, holeOrigin, holeSize, shadow.w, sigma, dpr));
|
|
8697
|
+
}
|
|
8698
|
+
|
|
8441
8699
|
struct VertexOutput {
|
|
8442
8700
|
@builtin(position) position: vec4f,
|
|
8443
8701
|
@location(0) localPos: vec2f,
|
|
@@ -8447,6 +8705,7 @@ struct VertexOutput {
|
|
|
8447
8705
|
@location(4) @interpolate(flat) kind: u32,
|
|
8448
8706
|
@location(5) @interpolate(flat) clipIndex: f32,
|
|
8449
8707
|
@location(6) @interpolate(flat) gradientIndex: f32,
|
|
8708
|
+
@location(7) @interpolate(flat) shadow: vec4f,
|
|
8450
8709
|
};
|
|
8451
8710
|
|
|
8452
8711
|
@vertex
|
|
@@ -8456,12 +8715,13 @@ fn vs(
|
|
|
8456
8715
|
@location(2) instanceSize: vec2f,
|
|
8457
8716
|
@location(3) instanceColor: vec4f,
|
|
8458
8717
|
@location(4) radiusOpacityBorder: vec3f,
|
|
8459
|
-
@location(5) instanceKind:
|
|
8718
|
+
@location(5) instanceKind: f32,
|
|
8460
8719
|
@location(6) transformA: vec2f,
|
|
8461
8720
|
@location(7) transformB: vec2f,
|
|
8462
8721
|
@location(8) transformC: vec2f,
|
|
8463
8722
|
@location(9) clipIndex: f32,
|
|
8464
8723
|
@location(10) gradientIndex: f32,
|
|
8724
|
+
@location(11) shadow: vec4f,
|
|
8465
8725
|
) -> VertexOutput {
|
|
8466
8726
|
var out: VertexOutput;
|
|
8467
8727
|
// The quad is inflated by one physical pixel on every side so the
|
|
@@ -8480,9 +8740,10 @@ fn vs(
|
|
|
8480
8740
|
out.size = instanceSize;
|
|
8481
8741
|
out.color = instanceColor;
|
|
8482
8742
|
out.radiusOpacityBorder = radiusOpacityBorder;
|
|
8483
|
-
out.kind = instanceKind;
|
|
8743
|
+
out.kind = u32(instanceKind + 0.5);
|
|
8484
8744
|
out.clipIndex = clipIndex;
|
|
8485
8745
|
out.gradientIndex = gradientIndex;
|
|
8746
|
+
out.shadow = shadow;
|
|
8486
8747
|
return out;
|
|
8487
8748
|
}
|
|
8488
8749
|
|
|
@@ -8492,7 +8753,17 @@ fn fs(in: VertexOutput) -> @location(0) vec4f {
|
|
|
8492
8753
|
let dist = roundedRectDistance(in.localPos, vec2f(0.0, 0.0), in.size, in.radiusOpacityBorder.x);
|
|
8493
8754
|
|
|
8494
8755
|
var shape = coverage(dist, dpr);
|
|
8495
|
-
if (in.kind
|
|
8756
|
+
if (in.kind >= KIND_SHADOW) {
|
|
8757
|
+
shape = shadowAlpha(
|
|
8758
|
+
in.kind,
|
|
8759
|
+
in.localPos,
|
|
8760
|
+
in.size,
|
|
8761
|
+
in.radiusOpacityBorder.x,
|
|
8762
|
+
in.radiusOpacityBorder.z,
|
|
8763
|
+
in.shadow,
|
|
8764
|
+
dpr
|
|
8765
|
+
);
|
|
8766
|
+
} else if (in.kind == KIND_BORDER) {
|
|
8496
8767
|
// Border: the band between the outer edge and the inner edge inset
|
|
8497
8768
|
// by borderWidth.
|
|
8498
8769
|
let bw = max(in.radiusOpacityBorder.z, 0.0);
|
|
@@ -9319,14 +9590,25 @@ function createWebGPUSurface(host) {
|
|
|
9319
9590
|
* 2 size.xy
|
|
9320
9591
|
* 4 color.rgba
|
|
9321
9592
|
* 8 radius, opacity, borderWidth
|
|
9322
|
-
* 11 kind (
|
|
9593
|
+
* 11 kind (PrimitiveKind, as a float)
|
|
9323
9594
|
* 12 transform 3x2 affine, absolute layout → logical screen
|
|
9324
9595
|
* 18 clipIndex index into the clip chain, -1 for none
|
|
9325
9596
|
* 19 gradientIndex index into the frame's gradients, -1 for none
|
|
9326
|
-
* 20
|
|
9327
|
-
|
|
9328
|
-
|
|
9329
|
-
|
|
9597
|
+
* 20 shadow offsetX, offsetY, spread, the other shape's radius
|
|
9598
|
+
* 24 (end)
|
|
9599
|
+
*
|
|
9600
|
+
* A shadow is two rounded rectangles, the blurred one and the box it
|
|
9601
|
+
* is cut by, and an instance describes the first. For an outer shadow
|
|
9602
|
+
* the rectangle is the blurred shape grown by the blur's reach
|
|
9603
|
+
* (`BOX_SHADOW_BLUR_REACH` × blur), `radius` its corners, `borderWidth`
|
|
9604
|
+
* the blur, and the box it must not show under is recovered from the
|
|
9605
|
+
* offset and spread, with the box's own radius last. An inset shadow's
|
|
9606
|
+
* rectangle is the box, and the hole it is cast from is the box moved
|
|
9607
|
+
* by the offset and shrunk by the spread, with the hole's radius last.
|
|
9608
|
+
* Every other instance writes zeros there.
|
|
9609
|
+
*/
|
|
9610
|
+
const INSTANCE_STRIDE_FLOATS = 24;
|
|
9611
|
+
const INSTANCE_STRIDE_BYTES = 96;
|
|
9330
9612
|
/**
|
|
9331
9613
|
* Textured instance layout (glyphs and images), in floats:
|
|
9332
9614
|
*
|
|
@@ -9362,6 +9644,10 @@ const NO_CLIP_INDEX = -1;
|
|
|
9362
9644
|
let PrimitiveKind = /* @__PURE__ */ function(PrimitiveKind) {
|
|
9363
9645
|
PrimitiveKind[PrimitiveKind["Fill"] = 0] = "Fill";
|
|
9364
9646
|
PrimitiveKind[PrimitiveKind["Border"] = 1] = "Border";
|
|
9647
|
+
/** A `boxShadows` entry outside the box; see the instance layout. */
|
|
9648
|
+
PrimitiveKind[PrimitiveKind["Shadow"] = 2] = "Shadow";
|
|
9649
|
+
/** A `boxShadows` entry marked `inset`. */
|
|
9650
|
+
PrimitiveKind[PrimitiveKind["InsetShadow"] = 3] = "InsetShadow";
|
|
9365
9651
|
return PrimitiveKind;
|
|
9366
9652
|
}({});
|
|
9367
9653
|
let CommandKind = /* @__PURE__ */ function(CommandKind) {
|
|
@@ -9435,7 +9721,7 @@ var FloatBuffer = class {
|
|
|
9435
9721
|
return this.data.slice(0, this.length);
|
|
9436
9722
|
}
|
|
9437
9723
|
};
|
|
9438
|
-
const instanceScratch = new FloatBuffer(
|
|
9724
|
+
const instanceScratch = new FloatBuffer(12288);
|
|
9439
9725
|
const texturedScratch = new FloatBuffer(32768);
|
|
9440
9726
|
const clipScratch = new FloatBuffer(1024);
|
|
9441
9727
|
const gradientScratch = new FloatBuffer(768);
|
|
@@ -9488,7 +9774,7 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
|
|
|
9488
9774
|
/** The nodes asking for `lift`, met on the walk and drawn after it. */
|
|
9489
9775
|
const liftedPass = [];
|
|
9490
9776
|
function closePrimitives() {
|
|
9491
|
-
const end = instanceData.length /
|
|
9777
|
+
const end = instanceData.length / 24;
|
|
9492
9778
|
if (end > openStart) commands.push({
|
|
9493
9779
|
kind: 0,
|
|
9494
9780
|
start: openStart,
|
|
@@ -9498,7 +9784,7 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
|
|
|
9498
9784
|
openStart = end;
|
|
9499
9785
|
}
|
|
9500
9786
|
function beginPrimitives(scissor) {
|
|
9501
|
-
if (openStart === instanceData.length /
|
|
9787
|
+
if (openStart === instanceData.length / 24) {
|
|
9502
9788
|
openScissor = scissor;
|
|
9503
9789
|
return;
|
|
9504
9790
|
}
|
|
@@ -9612,7 +9898,7 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
|
|
|
9612
9898
|
return;
|
|
9613
9899
|
}
|
|
9614
9900
|
const sticky = rec.stickyOffsetX !== 0 || rec.stickyOffsetY !== 0;
|
|
9615
|
-
if (state.cull !== null && !intersectsCull(state.cull, rec.
|
|
9901
|
+
if (state.cull !== null && !intersectsCull(state.cull, rec.extentMinX + rec.stickyOffsetX, rec.extentMinY + rec.stickyOffsetY, rec.extentMaxX - rec.extentMinX, rec.extentMaxY - rec.extentMinY)) return;
|
|
9616
9902
|
const paint = resolvePaintState(node, paintScratch);
|
|
9617
9903
|
const effectiveOpacity = state.opacity * paint.opacity;
|
|
9618
9904
|
const baseCtm = sticky ? translateTransform(state.ctm, rec.stickyOffsetX, rec.stickyOffsetY) : state.ctm;
|
|
@@ -9637,6 +9923,10 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
|
|
|
9637
9923
|
}
|
|
9638
9924
|
const contentScissor = nextClip;
|
|
9639
9925
|
const contentRounded = nextRounded;
|
|
9926
|
+
if (paint.boxShadows.length > 0) {
|
|
9927
|
+
beginPrimitives(ownScissor);
|
|
9928
|
+
pushShadows(instanceData, rec, paint, effectiveOpacity, nodeCtm, ownRounded, false);
|
|
9929
|
+
}
|
|
9640
9930
|
if (paint.backgroundColor !== void 0) {
|
|
9641
9931
|
const color = parseColor$1(paint.backgroundColor);
|
|
9642
9932
|
if (color !== void 0) {
|
|
@@ -9652,6 +9942,10 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
|
|
|
9652
9942
|
pushInstance(instanceData, rec.x, rec.y, rec.width, rec.height, first, uniformBorderRadius(paint.borderRadius), effectiveOpacity, 0, 0, nodeCtm, ownRounded, index);
|
|
9653
9943
|
}
|
|
9654
9944
|
}
|
|
9945
|
+
if (paint.boxShadows.length > 0) {
|
|
9946
|
+
beginPrimitives(ownScissor);
|
|
9947
|
+
pushShadows(instanceData, rec, paint, effectiveOpacity, nodeCtm, ownRounded, true);
|
|
9948
|
+
}
|
|
9655
9949
|
const textureSource = paint.video !== void 0 && paint.video.frame !== null ? paint.video : paint.image;
|
|
9656
9950
|
if (textureSource !== void 0) {
|
|
9657
9951
|
const sourceSize = paint.video !== void 0 && paint.video.frame !== null ? videoFrameSize(paint.video) : {
|
|
@@ -9766,7 +10060,7 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
|
|
|
9766
10060
|
state.rounded = nextRounded;
|
|
9767
10061
|
if (rec.clips && state.cull !== null) state.cull = pushCull(state.cull, rec);
|
|
9768
10062
|
if (paint.hasTransform || sticky) state.cull = null;
|
|
9769
|
-
if (rec.scrollable) state.ctm = translateTransform(state.ctm, -rec.scrollX, -rec.scrollY);
|
|
10063
|
+
if (rec.scrollable) state.ctm = translateTransform(state.ctm, -snapScroll(rec.scrollX, dpr), -snapScroll(rec.scrollY, dpr));
|
|
9770
10064
|
liftedFrom = liftedPass.length;
|
|
9771
10065
|
visitChildren(node, rec.paintOrder);
|
|
9772
10066
|
state.opacity = saved.opacity;
|
|
@@ -9821,9 +10115,10 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
|
|
|
9821
10115
|
const model = text.editor;
|
|
9822
10116
|
const editable = new EditableLayout(model, contentBox, text, measurer);
|
|
9823
10117
|
pushTextRects(textRunBackgrounds(editable.lines, text));
|
|
9824
|
-
|
|
10118
|
+
const spanned = text.textSelection;
|
|
10119
|
+
if (spanned !== void 0 || model.focused && !model.collapsed) {
|
|
9825
10120
|
const selection = parseColor$1(text.selectionColor);
|
|
9826
|
-
if (selection !== void 0) for (const box of editable.selectionBoxes()) pushContentRect(box, selection);
|
|
10121
|
+
if (selection !== void 0) for (const box of editable.selectionBoxes(spanned)) pushContentRect(box, selection);
|
|
9827
10122
|
}
|
|
9828
10123
|
if (editable.placeholderLines.length > 0) pushTextRun(editable.placeholderLines, colorToCss(text.placeholderColor));
|
|
9829
10124
|
else {
|
|
@@ -9842,7 +10137,7 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
|
|
|
9842
10137
|
}, underline);
|
|
9843
10138
|
}
|
|
9844
10139
|
}
|
|
9845
|
-
if (model.focused && model.collapsed && caretVisibleAt(model, now)) {
|
|
10140
|
+
if (spanned === void 0 && model.focused && model.collapsed && caretVisibleAt(model, now)) {
|
|
9846
10141
|
const caretColor = parseColor$1(text.caretColor);
|
|
9847
10142
|
if (caretColor !== void 0) {
|
|
9848
10143
|
const caret = editable.caretRect();
|
|
@@ -9976,7 +10271,7 @@ function buildRenderList(root, layout, measurer, logicalWidth, logicalHeight, dp
|
|
|
9976
10271
|
closePrimitives();
|
|
9977
10272
|
return {
|
|
9978
10273
|
instanceData: instanceData.take(),
|
|
9979
|
-
instanceCount: instanceData.length /
|
|
10274
|
+
instanceCount: instanceData.length / 24,
|
|
9980
10275
|
texturedData: texturedData.take(),
|
|
9981
10276
|
texturedCount: texturedData.length / 16,
|
|
9982
10277
|
clipData: clipData.take(),
|
|
@@ -10024,8 +10319,8 @@ function pushScrollbars(out, rec, opacity, transform, rounded, now) {
|
|
|
10024
10319
|
pushInstance(out, x, y, width, height, color, 3, opacity, 0, 0, transform, rounded);
|
|
10025
10320
|
}
|
|
10026
10321
|
}
|
|
10027
|
-
function pushInstance(out, x, y, width, height, color, radius, opacity, borderWidth, kind, transform, clip, gradient = -1) {
|
|
10028
|
-
out.ensure(
|
|
10322
|
+
function pushInstance(out, x, y, width, height, color, radius, opacity, borderWidth, kind, transform, clip, gradient = -1, shadowX = 0, shadowY = 0, shadowSpread = 0, shadowRadius = 0) {
|
|
10323
|
+
out.ensure(24);
|
|
10029
10324
|
const data = out.data;
|
|
10030
10325
|
const at = out.length;
|
|
10031
10326
|
data[at] = x;
|
|
@@ -10048,7 +10343,38 @@ function pushInstance(out, x, y, width, height, color, radius, opacity, borderWi
|
|
|
10048
10343
|
data[at + 17] = transform[5];
|
|
10049
10344
|
data[at + 18] = clip;
|
|
10050
10345
|
data[at + 19] = gradient;
|
|
10051
|
-
|
|
10346
|
+
data[at + 20] = shadowX;
|
|
10347
|
+
data[at + 21] = shadowY;
|
|
10348
|
+
data[at + 22] = shadowSpread;
|
|
10349
|
+
data[at + 23] = shadowRadius;
|
|
10350
|
+
out.length = at + 24;
|
|
10351
|
+
}
|
|
10352
|
+
/**
|
|
10353
|
+
* One instance per outer shadow, or per inset one, in the order
|
|
10354
|
+
* Canvas2D draws them: the last declared first, since CSS paints the
|
|
10355
|
+
* first shadow on top. The shader evaluates the blurred shape exactly
|
|
10356
|
+
* rather than sampling a blurred texture, so a shadow costs a quad.
|
|
10357
|
+
*/
|
|
10358
|
+
function pushShadows(out, rec, paint, opacity, transform, clip, inset) {
|
|
10359
|
+
const shadows = paint.boxShadows;
|
|
10360
|
+
const radius = borderRadiusIsZero(paint.borderRadius) ? 0 : uniformBorderRadius(paint.borderRadius);
|
|
10361
|
+
for (let i = shadows.length - 1; i >= 0; i--) {
|
|
10362
|
+
const shadow = shadows[i];
|
|
10363
|
+
if (shadow.inset === true !== inset || shadow.color.a <= 0) continue;
|
|
10364
|
+
const color = parseColor$1(shadow.color);
|
|
10365
|
+
if (color === void 0) continue;
|
|
10366
|
+
const blur = Math.max(0, shadow.blurRadius);
|
|
10367
|
+
const spread = shadow.spreadRadius;
|
|
10368
|
+
if (inset) {
|
|
10369
|
+
pushInstance(out, rec.x, rec.y, rec.width, rec.height, color, radius, opacity, blur, 3, transform, clip, -1, shadow.offsetX, shadow.offsetY, spread, boxShadowRadius(radius, spread, true));
|
|
10370
|
+
continue;
|
|
10371
|
+
}
|
|
10372
|
+
const width = rec.width + spread * 2;
|
|
10373
|
+
const height = rec.height + spread * 2;
|
|
10374
|
+
if (width <= 0 || height <= 0) continue;
|
|
10375
|
+
const reach = blur * BOX_SHADOW_BLUR_REACH;
|
|
10376
|
+
pushInstance(out, rec.x + shadow.offsetX - spread - reach, rec.y + shadow.offsetY - spread - reach, width + reach * 2, height + reach * 2, color, boxShadowRadius(radius, spread, false), opacity, blur, 2, transform, clip, -1, shadow.offsetX, shadow.offsetY, spread, radius);
|
|
10377
|
+
}
|
|
10052
10378
|
}
|
|
10053
10379
|
/**
|
|
10054
10380
|
* Writes one gradient record for a rectangle of the given size and
|
|
@@ -10503,7 +10829,7 @@ function quadVertexLayout() {
|
|
|
10503
10829
|
/** Mirrors the float layout documented on INSTANCE_STRIDE_FLOATS. */
|
|
10504
10830
|
function primitiveInstanceLayout() {
|
|
10505
10831
|
return {
|
|
10506
|
-
arrayStride:
|
|
10832
|
+
arrayStride: 96,
|
|
10507
10833
|
stepMode: "instance",
|
|
10508
10834
|
attributes: [
|
|
10509
10835
|
{
|
|
@@ -10529,7 +10855,7 @@ function primitiveInstanceLayout() {
|
|
|
10529
10855
|
{
|
|
10530
10856
|
shaderLocation: 5,
|
|
10531
10857
|
offset: 44,
|
|
10532
|
-
format: "
|
|
10858
|
+
format: "float32"
|
|
10533
10859
|
},
|
|
10534
10860
|
{
|
|
10535
10861
|
shaderLocation: 6,
|
|
@@ -10555,6 +10881,11 @@ function primitiveInstanceLayout() {
|
|
|
10555
10881
|
shaderLocation: 10,
|
|
10556
10882
|
offset: 76,
|
|
10557
10883
|
format: "float32"
|
|
10884
|
+
},
|
|
10885
|
+
{
|
|
10886
|
+
shaderLocation: 11,
|
|
10887
|
+
offset: 80,
|
|
10888
|
+
format: "float32x4"
|
|
10558
10889
|
}
|
|
10559
10890
|
]
|
|
10560
10891
|
};
|
|
@@ -11022,7 +11353,7 @@ var WebGPURenderer = class {
|
|
|
11022
11353
|
glyphPages.flush();
|
|
11023
11354
|
const uploadStart = this.hooks.onUploadStart !== void 0 || this.hooks.onUploadEnd !== void 0 ? performance.now() : 0;
|
|
11024
11355
|
if (list.instanceCount > 0) {
|
|
11025
|
-
const buffer = this.ensureBuffer(this.instanceBuffer, list.instanceData.byteLength,
|
|
11356
|
+
const buffer = this.ensureBuffer(this.instanceBuffer, list.instanceData.byteLength, 96);
|
|
11026
11357
|
if (buffer !== this.instanceBuffer) {
|
|
11027
11358
|
this.instanceBuffer = buffer;
|
|
11028
11359
|
this.cachedInstanceData = null;
|
|
@@ -13470,7 +13801,7 @@ function markNow() {
|
|
|
13470
13801
|
* frame is collected, so a node dirtied again while the frame
|
|
13471
13802
|
* is being processed belongs to the next frame.
|
|
13472
13803
|
*/
|
|
13473
|
-
var UiFrame = class {
|
|
13804
|
+
var UiFrame = class UiFrame {
|
|
13474
13805
|
id;
|
|
13475
13806
|
time;
|
|
13476
13807
|
dirty;
|
|
@@ -13516,6 +13847,21 @@ var UiFrame = class {
|
|
|
13516
13847
|
for (const value of this.dirty.values()) if ((value & flags) !== 0) return true;
|
|
13517
13848
|
return false;
|
|
13518
13849
|
}
|
|
13850
|
+
/**
|
|
13851
|
+
* This frame and `later` as one: every node in either, with the
|
|
13852
|
+
* flags it carried in both.
|
|
13853
|
+
*
|
|
13854
|
+
* What the phases after layout read when layout ran more than once
|
|
13855
|
+
* in a frame (see `UiScheduler.recollect`): a node dirtied by a
|
|
13856
|
+
* layout listener has to be re-meant and redrawn like any other
|
|
13857
|
+
* node the frame changed.
|
|
13858
|
+
*/
|
|
13859
|
+
merged(later) {
|
|
13860
|
+
if (later.isEmpty()) return this;
|
|
13861
|
+
const dirty = new Map(this.dirty);
|
|
13862
|
+
for (const [node, flags] of later.entries()) dirty.set(node, (dirty.get(node) ?? 0) | flags);
|
|
13863
|
+
return new UiFrame(this.id, this.time, dirty);
|
|
13864
|
+
}
|
|
13519
13865
|
get size() {
|
|
13520
13866
|
return this.dirty.size;
|
|
13521
13867
|
}
|
|
@@ -13652,6 +13998,32 @@ var UiScheduler = class {
|
|
|
13652
13998
|
this.handleFrame(time);
|
|
13653
13999
|
}
|
|
13654
14000
|
/**
|
|
14001
|
+
* Takes what was dirtied since `frame` was collected into that same
|
|
14002
|
+
* frame, rather than leaving it for the next one.
|
|
14003
|
+
*
|
|
14004
|
+
* For a phase that has to finish inside the frame what the frame
|
|
14005
|
+
* started. A layout listener (a `breakpoint`, a `sizeContainer`)
|
|
14006
|
+
* that writes padding after the boxes are final has made those boxes
|
|
14007
|
+
* stale, and painting them would show the stale layout for one frame
|
|
14008
|
+
* before the next corrects it. The runtime lays the writes out again
|
|
14009
|
+
* from what this returns, before anything paints.
|
|
14010
|
+
*
|
|
14011
|
+
* The result holds only the newly dirtied nodes, with `frame`'s id
|
|
14012
|
+
* and time: it is more of the same frame, not a new one, so the
|
|
14013
|
+
* frame count does not move. Anything armed by those writes finds
|
|
14014
|
+
* nothing left to do.
|
|
14015
|
+
*/
|
|
14016
|
+
recollect(frame) {
|
|
14017
|
+
const count = this.dirty.drainInto(this.drained);
|
|
14018
|
+
const dirty = /* @__PURE__ */ new Map();
|
|
14019
|
+
for (let i = 0; i < count; i++) {
|
|
14020
|
+
const node = this.drained[i];
|
|
14021
|
+
dirty.set(node, node.dirtyFlags);
|
|
14022
|
+
node.dirtyFlags = 0;
|
|
14023
|
+
}
|
|
14024
|
+
return new UiFrame(frame.id, frame.time, dirty);
|
|
14025
|
+
}
|
|
14026
|
+
/**
|
|
13655
14027
|
* Runs one frame, and names its three parts for the browser's
|
|
13656
14028
|
* profiler when anything is recording (`PerformanceMarks`).
|
|
13657
14029
|
*
|
|
@@ -14565,8 +14937,14 @@ const PRESENTATIONAL_CHILDREN = /* @__PURE__ */ new Set([
|
|
|
14565
14937
|
* is, carrying `disabled` — unavailable is a thing to announce,
|
|
14566
14938
|
* hidden is not.
|
|
14567
14939
|
*/
|
|
14568
|
-
function buildSemanticsTree(root) {
|
|
14569
|
-
return walk(root, null, false);
|
|
14940
|
+
function buildSemanticsTree(root, memory) {
|
|
14941
|
+
return walk(root, null, false, memory);
|
|
14942
|
+
}
|
|
14943
|
+
function semanticsMemory() {
|
|
14944
|
+
return {
|
|
14945
|
+
described: /* @__PURE__ */ new WeakSet(),
|
|
14946
|
+
spans: /* @__PURE__ */ new WeakMap()
|
|
14947
|
+
};
|
|
14570
14948
|
}
|
|
14571
14949
|
/**
|
|
14572
14950
|
* The records one subtree contributes, as if walked in place.
|
|
@@ -14588,8 +14966,8 @@ function buildSemanticsTree(root) {
|
|
|
14588
14966
|
* `inert` is whether an ancestor above this subtree is disabled, which
|
|
14589
14967
|
* only the caller can know.
|
|
14590
14968
|
*/
|
|
14591
|
-
function buildSemanticsSubtree(node, parent, index, inert) {
|
|
14592
|
-
const records = walk(node, parent, inert);
|
|
14969
|
+
function buildSemanticsSubtree(node, parent, index, inert, memory) {
|
|
14970
|
+
const records = walk(node, parent, inert, memory);
|
|
14593
14971
|
const own = records.get(node.id);
|
|
14594
14972
|
if (own === void 0) return null;
|
|
14595
14973
|
records.set(node.id, {
|
|
@@ -14598,26 +14976,129 @@ function buildSemanticsSubtree(node, parent, index, inert) {
|
|
|
14598
14976
|
});
|
|
14599
14977
|
return records;
|
|
14600
14978
|
}
|
|
14601
|
-
|
|
14602
|
-
|
|
14979
|
+
/**
|
|
14980
|
+
* Walks a subtree again after the shape of the tree changed inside it,
|
|
14981
|
+
* describing only what changed.
|
|
14982
|
+
*
|
|
14983
|
+
* A full walk asks every node what it means, and moves every record
|
|
14984
|
+
* whose siblings moved. After a block is inserted in a long document
|
|
14985
|
+
* nearly every node means what it did. So a record `reuse.unchanged`
|
|
14986
|
+
* vouches for is taken back as it was, and an untouched transparent
|
|
14987
|
+
* subtree (one with no record of its own, like a block of the document)
|
|
14988
|
+
* is taken back as the run of its parent's children it contributed last
|
|
14989
|
+
* time, without being walked into. Nothing taken back is renumbered:
|
|
14990
|
+
* the caller learns where everything went from `children` and `placed`.
|
|
14991
|
+
*
|
|
14992
|
+
* `node` has to carry a record, as for `buildSemanticsSubtree`; null
|
|
14993
|
+
* otherwise.
|
|
14994
|
+
*/
|
|
14995
|
+
function rewalkSemantics(node, parent, index, inert, reuse) {
|
|
14996
|
+
const result = {
|
|
14997
|
+
records: /* @__PURE__ */ new Map(),
|
|
14998
|
+
children: /* @__PURE__ */ new Map(),
|
|
14999
|
+
kept: /* @__PURE__ */ new Set(),
|
|
15000
|
+
placed: []
|
|
15001
|
+
};
|
|
15002
|
+
walk(node, parent, inert, reuse.memory, reuse, result);
|
|
15003
|
+
const own = result.records.get(node.id);
|
|
15004
|
+
if (own === void 0) return null;
|
|
15005
|
+
result.records.set(node.id, {
|
|
15006
|
+
...own,
|
|
15007
|
+
index
|
|
15008
|
+
});
|
|
15009
|
+
result.placed[0] = {
|
|
15010
|
+
id: node.id,
|
|
15011
|
+
parent,
|
|
15012
|
+
index
|
|
15013
|
+
};
|
|
15014
|
+
return result;
|
|
15015
|
+
}
|
|
15016
|
+
function walk(root, rootParent, rootInert, memory, reuse, rewalk) {
|
|
15017
|
+
const records = rewalk?.records ?? /* @__PURE__ */ new Map();
|
|
14603
15018
|
const childCounts = /* @__PURE__ */ new Map();
|
|
15019
|
+
/** Each parent's children so far, in order: for spans, and for a rewalk's result. */
|
|
15020
|
+
const given = rewalk?.children ?? /* @__PURE__ */ new Map();
|
|
15021
|
+
const placed = rewalk?.placed;
|
|
15022
|
+
const tracking = memory !== void 0 || rewalk !== void 0;
|
|
14604
15023
|
const nextIndex = (parent) => {
|
|
14605
15024
|
const index = childCounts.get(parent) ?? 0;
|
|
14606
15025
|
childCounts.set(parent, index + 1);
|
|
14607
15026
|
return index;
|
|
14608
15027
|
};
|
|
15028
|
+
const note = (parent, id, index) => {
|
|
15029
|
+
if (!tracking) return;
|
|
15030
|
+
let list = given.get(parent);
|
|
15031
|
+
if (list === void 0) given.set(parent, list = []);
|
|
15032
|
+
list.push(id);
|
|
15033
|
+
placed?.push({
|
|
15034
|
+
id,
|
|
15035
|
+
parent,
|
|
15036
|
+
index
|
|
15037
|
+
});
|
|
15038
|
+
};
|
|
15039
|
+
/** Takes back a record nothing changed, subtree and all. */
|
|
15040
|
+
const keep = (id, parent) => {
|
|
15041
|
+
note(parent, id, nextIndex(parent));
|
|
15042
|
+
rewalk.kept.add(id);
|
|
15043
|
+
};
|
|
15044
|
+
/**
|
|
15045
|
+
* Takes back everything an untouched transparent node contributed, as
|
|
15046
|
+
* a run of its parent's old children, without walking into it. False
|
|
15047
|
+
* when its span can't be trusted, and it is walked.
|
|
15048
|
+
*/
|
|
15049
|
+
const keepSpan = (node, parent) => {
|
|
15050
|
+
const span = memory.spans.get(node);
|
|
15051
|
+
if (span === void 0 || span.parent !== parent) return false;
|
|
15052
|
+
if (span.count === 0) return true;
|
|
15053
|
+
const at = span.first === null ? -1 : reuse.positionOf(parent, span.first);
|
|
15054
|
+
if (at < 0) return false;
|
|
15055
|
+
const ids = reuse.childrenOf(parent).slice(at, at + span.count);
|
|
15056
|
+
if (ids.length !== span.count) return false;
|
|
15057
|
+
for (const id of ids) keep(id, parent);
|
|
15058
|
+
return true;
|
|
15059
|
+
};
|
|
14609
15060
|
const visit = (node, parent, inert) => {
|
|
14610
15061
|
if (node.properties.get("visible") === false) return;
|
|
14611
15062
|
const disabled = inert || node.properties.get("disabled") === true;
|
|
15063
|
+
if (reuse !== void 0 && node !== root && reuse.unchanged(node)) {
|
|
15064
|
+
if (memory.described.has(node) && reuse.previous.has(node.id)) {
|
|
15065
|
+
keep(node.id, parent);
|
|
15066
|
+
return;
|
|
15067
|
+
}
|
|
15068
|
+
if (keepSpan(node, parent)) return;
|
|
15069
|
+
}
|
|
14612
15070
|
const record = describe(node, parent, disabled, nextIndex);
|
|
14613
15071
|
if (record === null) {
|
|
15072
|
+
const start = childCounts.get(parent) ?? 0;
|
|
14614
15073
|
for (let child = node.firstChild; child !== null; child = child.nextSibling) visit(child, parent, disabled);
|
|
15074
|
+
if (memory !== void 0) {
|
|
15075
|
+
const count = (childCounts.get(parent) ?? 0) - start;
|
|
15076
|
+
memory.spans.set(node, {
|
|
15077
|
+
parent,
|
|
15078
|
+
first: count === 0 ? null : given.get(parent)[start],
|
|
15079
|
+
count
|
|
15080
|
+
});
|
|
15081
|
+
}
|
|
14615
15082
|
return;
|
|
14616
15083
|
}
|
|
15084
|
+
memory?.described.add(node);
|
|
15085
|
+
if (node !== root) note(parent, record.id, record.index);
|
|
15086
|
+
else placed?.push({
|
|
15087
|
+
id: record.id,
|
|
15088
|
+
parent,
|
|
15089
|
+
index: record.index
|
|
15090
|
+
});
|
|
15091
|
+
if (rewalk !== void 0 && !given.has(record.id)) given.set(record.id, []);
|
|
14617
15092
|
const runs = linkRunsOf(node);
|
|
14618
15093
|
if (runs.length > 0) {
|
|
14619
15094
|
records.set(record.id, paragraphOf(record));
|
|
14620
15095
|
appendTextRuns(node, record.id, runs, records);
|
|
15096
|
+
if (tracking) for (let run = 0;; run++) {
|
|
15097
|
+
const id = `${record.id}${TEXT_RUN_ID_SEPARATOR}${run}`;
|
|
15098
|
+
const added = records.get(id);
|
|
15099
|
+
if (added === void 0) break;
|
|
15100
|
+
note(record.id, id, added.index);
|
|
15101
|
+
}
|
|
14621
15102
|
} else records.set(record.id, record);
|
|
14622
15103
|
for (let child = node.firstChild; child !== null; child = child.nextSibling) {
|
|
14623
15104
|
if (claimedByName(node, child)) continue;
|
|
@@ -14664,7 +15145,8 @@ function describe(node, parent, disabled, nextIndex) {
|
|
|
14664
15145
|
valueText: valueTextOf(node),
|
|
14665
15146
|
posInSet: node.properties.get("posInSet"),
|
|
14666
15147
|
setSize: node.properties.get("setSize"),
|
|
14667
|
-
level: node.properties.get("level")
|
|
15148
|
+
level: node.properties.get("level"),
|
|
15149
|
+
activeDescendant: node.properties.get("activeDescendant")?.id
|
|
14668
15150
|
});
|
|
14669
15151
|
}
|
|
14670
15152
|
/**
|
|
@@ -14828,6 +15310,46 @@ function diffSemantics(previous, next) {
|
|
|
14828
15310
|
}
|
|
14829
15311
|
return patches;
|
|
14830
15312
|
}
|
|
15313
|
+
/**
|
|
15314
|
+
* Drops the updates that only renumber a record whose siblings kept
|
|
15315
|
+
* their order.
|
|
15316
|
+
*
|
|
15317
|
+
* A record carries its index among its siblings, so inserting one near
|
|
15318
|
+
* the top of a list changes the index of every record after it, and
|
|
15319
|
+
* each of those used to go out as an update: 4,266 patches for one
|
|
15320
|
+
* paragraph inserted in a 5,000-line document, every one of them
|
|
15321
|
+
* crossing to the main thread and rewriting a mirror element. They say
|
|
15322
|
+
* nothing a mirror needs. It applies removals, then adds in document
|
|
15323
|
+
* order at their indices, so the elements that stayed are already in
|
|
15324
|
+
* the right order around the ones that came and went. Only when the
|
|
15325
|
+
* siblings that stayed changed their order among themselves (a move)
|
|
15326
|
+
* do the new indices matter, and then every update is kept.
|
|
15327
|
+
*
|
|
15328
|
+
* The records keep their new indices; this only thins the patches.
|
|
15329
|
+
*/
|
|
15330
|
+
function dropIndexShifts(previous, next, patches) {
|
|
15331
|
+
const parents = /* @__PURE__ */ new Set();
|
|
15332
|
+
for (const patch of patches) if (patch.op === "update" && onlyIndexMoved(previous.get(patch.node.id), patch.node)) parents.add(patch.node.parent);
|
|
15333
|
+
if (parents.size === 0) return [...patches];
|
|
15334
|
+
const lastOld = /* @__PURE__ */ new Map();
|
|
15335
|
+
const reordered = /* @__PURE__ */ new Set();
|
|
15336
|
+
for (const record of next.values()) {
|
|
15337
|
+
if (!parents.has(record.parent) || reordered.has(record.parent)) continue;
|
|
15338
|
+
const before = previous.get(record.id);
|
|
15339
|
+
if (before === void 0 || before.parent !== record.parent) continue;
|
|
15340
|
+
if (before.index < (lastOld.get(record.parent) ?? -1)) reordered.add(record.parent);
|
|
15341
|
+
lastOld.set(record.parent, before.index);
|
|
15342
|
+
}
|
|
15343
|
+
return patches.filter((patch) => patch.op !== "update" || reordered.has(patch.node.parent) || !onlyIndexMoved(previous.get(patch.node.id), patch.node));
|
|
15344
|
+
}
|
|
15345
|
+
/** Whether two records differ in their index and in nothing else. */
|
|
15346
|
+
function onlyIndexMoved(before, after) {
|
|
15347
|
+
if (before === void 0 || before.parent !== after.parent || before.index === after.index) return false;
|
|
15348
|
+
return recordsEqual({
|
|
15349
|
+
...before,
|
|
15350
|
+
index: after.index
|
|
15351
|
+
}, after);
|
|
15352
|
+
}
|
|
14831
15353
|
/** Structural equality over the record's flat, pruned members. */
|
|
14832
15354
|
function recordsEqual(a, b) {
|
|
14833
15355
|
const aKeys = Object.keys(a);
|
|
@@ -14847,6 +15369,6 @@ function recordsEqual(a, b) {
|
|
|
14847
15369
|
return true;
|
|
14848
15370
|
}
|
|
14849
15371
|
//#endregion
|
|
14850
|
-
export { AlignContent, AnimationDriver, BUTTON_INTERACTION, Box, Button, CARET_BLINK_MS, CARET_WIDTH, CLIP_STRIDE_BYTES, CLIP_STRIDE_FLOATS, Canvas2DRenderer, CanvasPlatformSurface, CanvasSurface, CanvasTextMeasurer, CharacterCountTextMeasurer, Column, CommandKind, Constraints, CrossAxisAlignment, DEFAULT_BLOCK_SIZE, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_FONT_WEIGHT, DEFAULT_LINE_HEIGHT_FACTOR, DEFAULT_TEXT_COLOR, DefaultImageResolver, DefaultVideoResolver, DirtyFlags, DirtyNodeSet, EDITOR_PROP, ELLIPSIS, EMPTY_RECORDING, EXTERNAL_FILES, EditableLayout, EditableText, EditableTextModel, EnvironmentNotifier, FlexDirection, FocusNotifier, GLYPH_SUBPIXEL_PHASES, GlyphShaper, Grid, INSPECTOR_HEAT_MS, INSTANCE_STRIDE_BYTES, INSTANCE_STRIDE_FLOATS, IconRasterizer, LABEL_PADDING_X, LayoutEngine, LayoutInspector, LayoutNotifier, LayoutRecord, LazyColumn, LazyGrid, LazyRow, LazySheet, MARK_PREFIX, MAX_GRADIENT_STOPS, MAX_MEASURES_PER_CHILD, MOTION_CHANNELS, MOTION_REST, MOUSE_POINTER, MainAxisAlignment, Mp3Frames, NO_CLIP_INDEX, NodeTransitions, Paint, PaintPictureCache, PaintRecorder, PaintTarget, ParagraphTextMeasurer, PrimitiveKind, Responsive, Row, SCROLLBAR_FADE_MS, SCROLLBAR_HOVER_ZONE, SCROLLBAR_INSET, SCROLLBAR_LINGER_MS, SCROLLBAR_MIN_THUMB, SCROLLBAR_THICKNESS, ScrollView, Stack, TEXTURED_STRIDE_BYTES, TEXTURED_STRIDE_FLOATS, TEXT_MATCHES_PROP, TEXT_RUN_ID_SEPARATOR, TEXT_SELECTION_PROP, Text, UI_ROLES, UI_SEMANTIC_STATES, UI_SUBGRID_AXES, UiAnimation, UiAnimationFrameClock, UiBasicColors, UiBeforeInputEvent, UiBinding, UiBorderRadiuses, UiChildrenBinding, UiContainerSizeSource, UiDragSession, UiEditingController, UiEnvironment, UiEnvironmentKeys, UiEventBinding, UiEventType, UiFindController, UiFocusEvent, UiFocusManager, UiFrame, UiGestureEvent, UiGestureRecognizer, UiGraph, UiGraphBuilder, UiHitTester, UiHostFrameClock, UiInputDispatcher, UiInputEvent, UiInsetRegistry, UiKeyboardController, UiKeyboardEvent, UiManualFrameClock, UiModifierSet, UiNode, UiNodeType, UiPasteEvent, UiPinchEvent, UiPinchRecognizer, UiPlatformAdapter, UiPointerController, UiPointerEvent, UiProperties, UiScheduler, UiSelectionChangeEvent, UiSelectionController, UiSharedElements, UiShortcutRegistry, UiSpring, UiTextChangeEvent, UiTimerFrameClock, UiTouchScroller, UiTransforms, UiTween, UiUnknownModifierPropertyError, UiVirtualSheet, UiVirtualWindow, UiVisualState, UiWheelController, UiWheelDeltaMode, UiWheelEvent, VIRTUAL_INDEX_PROP, VIRTUAL_LEAD_PROP, VIRTUAL_SHEET_PROP, VIRTUAL_WINDOW_PROP, WebGPUError, WebGPUGlyphAtlas, WebGPUGlyphPages, WebGPURenderer, WebGPUSurface, WebGPUTextureCache, accumulatedOffsetTo, animateLayout, applyCanvasTextStyle, assertModifierList, assertTransitionMap, auto, autoFocus, bandOf, borderRadius, borderRadiusCorners, borderRadiusEqual, borderRadiusIsZero, borderRadiusValuesEqual, borderShapes, borders, boxShadow, boxShadowArraysEqual, boxShadowsEqual, breakpoint, bufferSource, buildFontString, buildRenderList, buildSemanticsSubtree, buildSemanticsTree, bumpFontStack, bundle, canDecodeVideo, capturePointer, caretRectFor, caretVisibleAt, clampSize, clearFontStacks, clearLinkHover, clearMatchRanges, clearOverrideProperty, clearSelectionRange, clickOutside, closestPropertyName, colorToCss, colorToHex, colorToRgba, colorValuesEqual, colorsEqual, colorsEqualPalette, commandForKey, computeObjectFitRect, constraintsEqual, containerBands, contentOffset, contextMenu, contrastRatio, createCanvasSurface, createCanvasTextStyle, createElement, createEnvironmentKey, createPaintState, createTextCache, createTween, createWebGPUSurface, cubicBezier, cueAt, darkColors, darkTheme, decorated, decorationColor, decorationRect, defaultMotion, defaultShadows, defaultShapes, defaultSpacing, defaultTextStyle, defaultTypography, defaultVisualState, defineModifier, defineProperty, defineThemeExtension, demuxMp4Audio, demuxMp4Video, densityFactors, describeLength, describeOverrides, detectEditingPlatform, diffSemantics, dragSessionFor, dragSource, draggable, drawOverlayShapes, drawText, dropTarget, easings, editableSpansOf, editorFor, editorOf, fade, fillTextRects, findEnvironmentKey, findMatchesIn, findPropertyDefinition, flattenTextSpans, focusRing, fontStackFor, formatConstraints, formatExplanation, formatShortcut, fr, getPropertyNames, glyphCount, gradientPaint, gradientsEqual, graphemeBoundaries, hasDecorationPhase, hasDrawnText, hasTextLinks, hasThemeExtension, hasVisualState, highContrastColors, hoverable, iconKey, iconSource, imageSource, inheritedPropertyFlags, inheritedPropertyNames, initializeWebGPU, inputsEqual, insetPadding, insetsEqual, interactive, interpolateColor, interpolateNumber, interpolateTransform, interpolatorFor, isAutoLength, isComponentLikeElement, isEditableNode, isFrLength, isLayoutProtocol, isMinMaxTrack, isMotionRest, isMultiline, isNodeFocusable, isNodeHitTestable, isNodeInert, isNodeSelectable, isNodeTabStop, isObservable, isPaintVisible, isPercentLength, isPrintable, isReadOnly, isScrollContainer, isShapeName, isTypographyRole, isUiChild, isUiElement, isUiModifier, isUiRole, isUiSemanticState, isVideoSurface, isWebGPUAvailable, labelNode, labelOrigin, layoutParagraph, layoutTextLines, lazySource, lightColors, lightTheme, lineEndAt, lineIndexAtY, lineIndexForOffset, lineLimit, lineStartAt, linear, linearGradient, linkHoverOf, linkOf, linkRunAtPointIn, markInstant, markNow, matchRangesOf, measure, measureSpan, minmax, motion, nextCaretToggle, nextGraphemeEnd, nextWordEnd, noInsets, noKeyModifiers, noModifiers, noThemeExtensions, normalizeBorderRadius, normalizeColor, normalizeStates, normalizeTextAlign, normalizeTransition, normalizeVerticalAlign, observeViewportInsets, offsetAtPoint, offsetAtPointIn, offsetAtX, offsetForVerticalMove, overrideSources, paintPictures, paintValuesEqual, paintsAfterChildren, paragraphGeometry, paragraphGeometryFrom, parseAlignContent, parseColor, parseCrossAxisAlignment, parseFlexDirection, parseMainAxisAlignment, parseShortcut, parseTransform, parseWebVtt, pathValuesEqual, percent, performanceMarksEnabled, pinchable, placeGridItems, pointerDeviceOf, pop, prepareInputSurface, pressable, previousGraphemeStart, previousWordStart, propertyEffects, propertyIsInherited, propertyValuesEqual, propertyValuesEqualByName, proportionalFontMetrics, provideEnvironment, publishInset, radialGradient, raiseContrast, rangeSource, readMp3Header, recordsEqual, registerFontStack, relativeLuminance, reorderable, repeat, replayPaint, resetOverrideWarnings, resetTransitionWarnings, resolveBoolean, resolveCursor, resolveLength, resolveMotionState, resolveNumber, resolvePaintState, resolveProperty, resolvePropertyByName, resolveString, resolvedSpansOf, rgb8, rgba, rotateFrom, runCanvasStyleInto, runFontString, sameArgs, scaleFrom, scaleSpacing, scrollLeaderOf, scrollPosition, scrollRange, scrollbarThumb, scrollbarThumbs, scrollbarZoneAt, selectableTextNodes, selectableTextOf, selectionRangeOf, selectionRects, selectionRectsIn, semanticsInertAbove, setLinkHover, setMatchRanges, setPerformanceMarks, setSelectionRange, shadowsEqual, shapesEqual, sharedElement, sheetSource, shortcut, shortcuts, sizeContainer, sizeGridTracks, slideDown, slideFrom, slideUp, spacingEqual, spacingSteps, spanAtOffset, spannedRunsFor, spannedTextOf, splitMp3Frames, spring, statesEqual, steps, syncEditorValue, textContentOf, textRunBackgrounds, textRunDecorations, textRunOfRecordId, textRuns, textSpansEqual, textStylesEqual, themeExtension, themeExtensionsEqual, themeTokens, themesEqual, tightenConstraints, touchActionFor, tracePathData, traceRoundedRect, transform, transformIsIdentity, transformsEqual, tween, typographyEqual, uniformBorderRadius, unknownContainerSize, validateGradient, validateRole, validateStates, validateSubgrid, videoFrameSize, videoSource, visualState, visualStatesEqual, wheelDeltaYOf, withContrast, withDensity, withOverrideSource, withThemeExtension, wordRangeAt, wordRangeIn, writeDeclaredProperty, writeOverrideProperty };
|
|
15372
|
+
export { AlignContent, AnimationDriver, BOX_SHADOW_BLUR_REACH, BUTTON_INTERACTION, Box, Button, CARET_BLINK_MS, CARET_WIDTH, CLIP_STRIDE_BYTES, CLIP_STRIDE_FLOATS, Canvas2DRenderer, CanvasPlatformSurface, CanvasSurface, CanvasTextMeasurer, CharacterCountTextMeasurer, Column, CommandKind, Constraints, CrossAxisAlignment, DEFAULT_BLOCK_SIZE, DEFAULT_FONT_FAMILY, DEFAULT_FONT_SIZE, DEFAULT_FONT_WEIGHT, DEFAULT_LINE_HEIGHT_FACTOR, DEFAULT_TEXT_COLOR, DefaultImageResolver, DefaultVideoResolver, DirtyFlags, DirtyNodeSet, EDITOR_PROP, ELLIPSIS, EMPTY_RECORDING, EXTERNAL_FILES, EditableLayout, EditableText, EditableTextModel, EnvironmentNotifier, FlexDirection, FocusNotifier, GLYPH_SUBPIXEL_PHASES, GlyphShaper, Grid, INSPECTOR_HEAT_MS, INSTANCE_STRIDE_BYTES, INSTANCE_STRIDE_FLOATS, IconRasterizer, LABEL_PADDING_X, LayoutEngine, LayoutInspector, LayoutNotifier, LayoutRecord, LazyColumn, LazyGrid, LazyRow, LazySheet, MARK_PREFIX, MAX_GRADIENT_STOPS, MAX_MEASURES_PER_CHILD, MOTION_CHANNELS, MOTION_REST, MOUSE_POINTER, MainAxisAlignment, Mp3Frames, NO_CLIP_INDEX, NodeTransitions, Paint, PaintPictureCache, PaintRecorder, PaintTarget, ParagraphTextMeasurer, PrimitiveKind, Responsive, Row, SCROLLBAR_FADE_MS, SCROLLBAR_HOVER_ZONE, SCROLLBAR_INSET, SCROLLBAR_LINGER_MS, SCROLLBAR_MIN_THUMB, SCROLLBAR_THICKNESS, ScrollView, Stack, TEXTURED_STRIDE_BYTES, TEXTURED_STRIDE_FLOATS, TEXT_MATCHES_PROP, TEXT_RUN_ID_SEPARATOR, TEXT_SELECTION_PROP, Text, UI_ROLES, UI_SEMANTIC_STATES, UI_SUBGRID_AXES, UiAnimation, UiAnimationFrameClock, UiBasicColors, UiBeforeInputEvent, UiBinding, UiBorderRadiuses, UiChildrenBinding, UiContainerSizeSource, UiDragSession, UiEditingController, UiEnvironment, UiEnvironmentKeys, UiEventBinding, UiEventType, UiFindController, UiFocusEvent, UiFocusManager, UiFrame, UiGestureEvent, UiGestureRecognizer, UiGraph, UiGraphBuilder, UiHitTester, UiHostFrameClock, UiInputDispatcher, UiInputEvent, UiInsetRegistry, UiKeyboardController, UiKeyboardEvent, UiManualFrameClock, UiModifierSet, UiNode, UiNodeType, UiPasteEvent, UiPinchEvent, UiPinchRecognizer, UiPlatformAdapter, UiPointerController, UiPointerEvent, UiProperties, UiScheduler, UiSelectionChangeEvent, UiSelectionController, UiSharedElements, UiShortcutRegistry, UiSpring, UiTextChangeEvent, UiTimerFrameClock, UiTouchScroller, UiTransforms, UiTween, UiUnknownModifierPropertyError, UiVirtualSheet, UiVirtualWindow, UiVisualState, UiWheelController, UiWheelDeltaMode, UiWheelEvent, VIRTUAL_INDEX_PROP, VIRTUAL_LEAD_PROP, VIRTUAL_SHEET_PROP, VIRTUAL_WINDOW_PROP, WebGPUError, WebGPUGlyphAtlas, WebGPUGlyphPages, WebGPURenderer, WebGPUSurface, WebGPUTextureCache, accumulatedOffsetTo, adjacentField, animateLayout, applyCanvasTextStyle, assertModifierList, assertTransitionMap, auto, autoFocus, bandOf, borderRadius, borderRadiusCorners, borderRadiusEqual, borderRadiusIsZero, borderRadiusValuesEqual, borderShapes, borders, boxShadow, boxShadowArraysEqual, boxShadowRadius, boxShadowReach, boxShadowsEqual, breakpoint, bufferSource, buildFontString, buildRenderList, buildSemanticsSubtree, buildSemanticsTree, bumpFontStack, bundle, canDecodeVideo, capturePointer, caretRectFor, caretVisibleAt, clampSize, clearFontStacks, clearLinkHover, clearMatchRanges, clearOverrideProperty, clearSelectionRange, clickOutside, closestPropertyName, colorToCss, colorToHex, colorToRgba, colorValuesEqual, colorsEqual, colorsEqualPalette, commandForKey, comparePositions, computeObjectFitRect, constraintsEqual, containerBands, contentOffset, contextMenu, contrastRatio, createCanvasSurface, createCanvasTextStyle, createElement, createEnvironmentKey, createPaintState, createTextCache, createTween, createWebGPUSurface, cubicBezier, cueAt, darkColors, darkTheme, decorated, decorationColor, decorationRect, defaultMotion, defaultShadows, defaultShapes, defaultSpacing, defaultTextStyle, defaultTypography, defaultVisualState, defineModifier, defineProperty, defineThemeExtension, demuxMp4Audio, demuxMp4Video, densityFactors, describeLength, describeOverrides, detectEditingPlatform, diffSemantics, dragSessionFor, dragSource, draggable, drawOverlayShapes, drawText, dropIndexShifts, dropTarget, easings, edgeField, editableSpansOf, editingGroupOf, editorFor, editorOf, fade, fillTextRects, findEnvironmentKey, findMatchesIn, findPropertyDefinition, flattenTextSpans, focusRing, fontStackFor, formatConstraints, formatExplanation, formatShortcut, fr, getPropertyNames, glyphCount, gradientPaint, gradientsEqual, graphemeBoundaries, hasDecorationPhase, hasDrawnText, hasTextLinks, hasThemeExtension, hasVisualState, hiddenRangesOf, highContrastColors, hoverable, iconKey, iconSource, imageSource, inheritedPropertyFlags, inheritedPropertyNames, initializeWebGPU, inputsEqual, insetPadding, insetsEqual, interactive, interpolateColor, interpolateNumber, interpolateTransform, interpolatorFor, isAutoLength, isComponentLikeElement, isEditableNode, isFrLength, isLayoutProtocol, isMinMaxTrack, isMotionRest, isMultiline, isNodeFocusable, isNodeHitTestable, isNodeInert, isNodeSelectable, isNodeTabStop, isObservable, isPaintVisible, isPercentLength, isPrintable, isReadOnly, isScrollContainer, isShapeName, isTypographyRole, isUiChild, isUiElement, isUiModifier, isUiRole, isUiSemanticState, isVideoSurface, isWebGPUAvailable, labelNode, labelOrigin, layoutParagraph, layoutTextLines, lazySource, lightColors, lightTheme, lineEndAt, lineIndexAtY, lineIndexForOffset, lineLimit, lineStartAt, linear, linearGradient, linkHoverOf, linkOf, linkRunAtPointIn, markInstant, markNow, matchRangesOf, measure, measureSpan, minmax, motion, nextCaretToggle, nextGraphemeEnd, nextWordEnd, noInsets, noKeyModifiers, noModifiers, noThemeExtensions, normalizeBorderRadius, normalizeColor, normalizeStates, normalizeTextAlign, normalizeTransition, normalizeVerticalAlign, observeViewportInsets, offsetAtPoint, offsetAtPointIn, offsetAtX, offsetForVerticalMove, overrideSources, paintPictures, paintValuesEqual, paintsAfterChildren, paragraphGeometry, paragraphGeometryFrom, parseAlignContent, parseColor, parseCrossAxisAlignment, parseFlexDirection, parseMainAxisAlignment, parseShortcut, parseTransform, parseWebVtt, pathValuesEqual, percent, performanceMarksEnabled, pinchable, placeGridItems, pointerDeviceOf, pop, prepareInputSurface, pressable, previousGraphemeStart, previousWordStart, propertyEffects, propertyIsInherited, propertyValuesEqual, propertyValuesEqualByName, proportionalFontMetrics, provideEnvironment, publishInset, radialGradient, raiseContrast, rangeSource, readMp3Header, recordsEqual, registerFontStack, relativeLuminance, reorderable, repeat, replayPaint, resetOverrideWarnings, resetTransitionWarnings, resolveBoolean, resolveCursor, resolveLength, resolveMotionState, resolveNumber, resolvePaintState, resolveProperty, resolvePropertyByName, resolveString, resolvedSpansOf, rewalkSemantics, rgb8, rgba, rotateFrom, runCanvasStyleInto, runFontString, sameArgs, scaleFrom, scaleSpacing, scrollLeaderOf, scrollPosition, scrollRange, scrollbarThumb, scrollbarThumbs, scrollbarZoneAt, selectableTextNodes, selectableTextOf, selectionRangeOf, selectionRects, selectionRectsIn, semanticsInertAbove, semanticsMemory, setLinkHover, setMatchRanges, setPerformanceMarks, setSelectionRange, shadowsEqual, shapesEqual, sharedElement, sheetSource, shortcut, shortcuts, sizeContainer, sizeGridTracks, slideDown, slideFrom, slideUp, spacingEqual, spacingSteps, spanAtOffset, spannedRunsFor, spannedTextOf, splitMp3Frames, spring, statesEqual, steps, syncEditorValue, textContentOf, textRunBackgrounds, textRunDecorations, textRunOfRecordId, textRuns, textSpansEqual, textStylesEqual, themeExtension, themeExtensionsEqual, themeTokens, themesEqual, tightenConstraints, touchActionFor, tracePathData, traceRoundedRect, transform, transformIsIdentity, transformsEqual, tween, typographyEqual, uniformBorderRadius, unknownContainerSize, validateGradient, validateRole, validateStates, validateSubgrid, videoFrameSize, videoSource, visualState, visualStatesEqual, wheelDeltaYOf, withContrast, withDensity, withOverrideSource, withThemeExtension, wordRangeAt, wordRangeIn, writeDeclaredProperty, writeOverrideProperty };
|
|
14851
15373
|
|
|
14852
15374
|
//# sourceMappingURL=index.js.map
|