markswift 0.0.0-stage → 2.0.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 +234 -0
- package/LICENSE +21 -0
- package/README.md +592 -2
- package/dist/cli-jdrbzqfa.js +2975 -0
- package/dist/cli-qchh0m4d.js +14041 -0
- package/dist/cli.js +637 -0
- package/dist/compiler/index.js +20 -0
- package/dist/index.js +22 -0
- package/dist/types/analysis/alignment.d.ts +12 -0
- package/dist/types/analysis/bands.d.ts +53 -0
- package/dist/types/analysis/breakpoints.d.ts +22 -0
- package/dist/types/analysis/class-hints.d.ts +21 -0
- package/dist/types/analysis/context.d.ts +49 -0
- package/dist/types/analysis/controls.d.ts +97 -0
- package/dist/types/analysis/flex-row.d.ts +14 -0
- package/dist/types/analysis/flex-sizing.d.ts +5 -0
- package/dist/types/analysis/flow-layout.d.ts +18 -0
- package/dist/types/analysis/generated.d.ts +16 -0
- package/dist/types/analysis/geometry.d.ts +50 -0
- package/dist/types/analysis/grid-tracks.d.ts +44 -0
- package/dist/types/analysis/grid.d.ts +5 -0
- package/dist/types/analysis/infer.d.ts +18 -0
- package/dist/types/analysis/invisible.d.ts +6 -0
- package/dist/types/analysis/layers.d.ts +15 -0
- package/dist/types/analysis/measured-layout.d.ts +6 -0
- package/dist/types/analysis/motion.d.ts +29 -0
- package/dist/types/analysis/naming.d.ts +6 -0
- package/dist/types/analysis/node-base.d.ts +13 -0
- package/dist/types/analysis/size-constraints.d.ts +5 -0
- package/dist/types/analysis/sizing.d.ts +24 -0
- package/dist/types/analysis/style-background.d.ts +24 -0
- package/dist/types/analysis/style-border.d.ts +7 -0
- package/dist/types/analysis/style-effects.d.ts +4 -0
- package/dist/types/analysis/style.d.ts +9 -0
- package/dist/types/analysis/svg/attributes.d.ts +10 -0
- package/dist/types/analysis/svg/build.d.ts +6 -0
- package/dist/types/analysis/svg/context.d.ts +31 -0
- package/dist/types/analysis/svg/geometry.d.ts +11 -0
- package/dist/types/analysis/svg/gradients.d.ts +6 -0
- package/dist/types/analysis/svg/markup.d.ts +23 -0
- package/dist/types/analysis/svg/text.d.ts +7 -0
- package/dist/types/analysis/svg/transforms.d.ts +19 -0
- package/dist/types/analysis/svg/traversal.d.ts +4 -0
- package/dist/types/analysis/table-borders.d.ts +19 -0
- package/dist/types/analysis/table.d.ts +36 -0
- package/dist/types/analysis/text-layout.d.ts +65 -0
- package/dist/types/analysis/text-runs.d.ts +30 -0
- package/dist/types/analysis/text.d.ts +9 -0
- package/dist/types/analysis/tooltips.d.ts +16 -0
- package/dist/types/analysis/typography.d.ts +21 -0
- package/dist/types/analysis/wrapping.d.ts +5 -0
- package/dist/types/api/bands.d.ts +58 -0
- package/dist/types/api/build.d.ts +51 -0
- package/dist/types/api/convert.d.ts +13 -0
- package/dist/types/api/types.d.ts +69 -0
- package/dist/types/browser/capture.d.ts +89 -0
- package/dist/types/browser/conditions.d.ts +25 -0
- package/dist/types/browser/fonts.d.ts +34 -0
- package/dist/types/browser/images.d.ts +3 -0
- package/dist/types/browser/layers.d.ts +132 -0
- package/dist/types/browser/motion.d.ts +44 -0
- package/dist/types/browser/settle.d.ts +27 -0
- package/dist/types/browser/sizing.d.ts +10 -0
- package/dist/types/browser/snapshot.d.ts +155 -0
- package/dist/types/browser/states.d.ts +36 -0
- package/dist/types/cli/args.d.ts +31 -0
- package/dist/types/cli/config.d.ts +78 -0
- package/dist/types/cli/css.d.ts +9 -0
- package/dist/types/cli/manifest.d.ts +20 -0
- package/dist/types/cli/output.d.ts +27 -0
- package/dist/types/cli/run.d.ts +4 -0
- package/dist/types/cli.d.ts +2 -0
- package/dist/types/compiler/index.d.ts +91 -0
- package/dist/types/compiler/naming.d.ts +1 -0
- package/dist/types/css/background.d.ts +16 -0
- package/dist/types/css/blend.d.ts +9 -0
- package/dist/types/css/color.d.ts +14 -0
- package/dist/types/css/counter.d.ts +10 -0
- package/dist/types/css/easing.d.ts +4 -0
- package/dist/types/css/effects.d.ts +18 -0
- package/dist/types/css/grid.d.ts +29 -0
- package/dist/types/css/index.d.ts +15 -0
- package/dist/types/css/media.d.ts +16 -0
- package/dist/types/css/paint.d.ts +33 -0
- package/dist/types/css/radius.d.ts +5 -0
- package/dist/types/css/raster.d.ts +10 -0
- package/dist/types/css/shadows.d.ts +3 -0
- package/dist/types/css/syntax.d.ts +12 -0
- package/dist/types/css/transforms.d.ts +45 -0
- package/dist/types/css/typography.d.ts +8 -0
- package/dist/types/fonts/converter.d.ts +16 -0
- package/dist/types/fonts/metadata.d.ts +6 -0
- package/dist/types/fonts/package.d.ts +12 -0
- package/dist/types/fonts/registration.d.ts +13 -0
- package/dist/types/fonts/source.d.ts +14 -0
- package/dist/types/fonts/types.d.ts +28 -0
- package/dist/types/html/elements.d.ts +8 -0
- package/dist/types/html/index.d.ts +4 -0
- package/dist/types/html/inputs.d.ts +4 -0
- package/dist/types/html/policy.d.ts +3 -0
- package/dist/types/html/types.d.ts +12 -0
- package/dist/types/index.d.ts +8 -0
- package/dist/types/input/identity.d.ts +3 -0
- package/dist/types/input/mime.d.ts +1 -0
- package/dist/types/input/root.d.ts +1 -0
- package/dist/types/input/server.d.ts +11 -0
- package/dist/types/input/source.d.ts +9 -0
- package/dist/types/input/types.d.ts +54 -0
- package/dist/types/model/fonts.d.ts +26 -0
- package/dist/types/model/interactive.d.ts +10 -0
- package/dist/types/model/layout.d.ts +528 -0
- package/dist/types/model/semantic.d.ts +984 -0
- package/dist/types/model/values.d.ts +125 -0
- package/dist/types/model/version.d.ts +4 -0
- package/dist/types/swift/borders.d.ts +13 -0
- package/dist/types/swift/components.d.ts +115 -0
- package/dist/types/swift/context.d.ts +184 -0
- package/dist/types/swift/control-state.d.ts +19 -0
- package/dist/types/swift/controls.d.ts +62 -0
- package/dist/types/swift/diagnostics.d.ts +3 -0
- package/dist/types/swift/effects.d.ts +23 -0
- package/dist/types/swift/emit.d.ts +6 -0
- package/dist/types/swift/format.d.ts +91 -0
- package/dist/types/swift/frames.d.ts +17 -0
- package/dist/types/swift/images.d.ts +25 -0
- package/dist/types/swift/layout.d.ts +5 -0
- package/dist/types/swift/measured-layout.d.ts +4 -0
- package/dist/types/swift/modifiers.d.ts +30 -0
- package/dist/types/swift/motion.d.ts +20 -0
- package/dist/types/swift/nodes.d.ts +4 -0
- package/dist/types/swift/paint.d.ts +22 -0
- package/dist/types/swift/runtime.d.ts +6 -0
- package/dist/types/swift/shadows.d.ts +7 -0
- package/dist/types/swift/states.d.ts +3 -0
- package/dist/types/swift/svg.d.ts +14 -0
- package/dist/types/swift/text-box.d.ts +12 -0
- package/dist/types/swift/text.d.ts +3 -0
- package/dist/types/swift/tokens/emit.d.ts +26 -0
- package/dist/types/swift/tokens/extract.d.ts +21 -0
- package/dist/types/swift/tokens/naming.d.ts +22 -0
- package/dist/types/swift/tokens/slots.d.ts +18 -0
- package/dist/types/swift/tokens/types.d.ts +77 -0
- package/dist/types/swift/tokens.d.ts +6 -0
- package/dist/types/swift/traversal.d.ts +2 -0
- package/dist/types/swift/wrapping.d.ts +4 -0
- package/package.json +66 -4
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { LayoutCondition } from "../model/layout.ts";
|
|
2
|
+
import type { BandEdge } from "../model/semantic.ts";
|
|
3
|
+
/** Narrowest width a band covers: thresholds at or below it never switch a phone layout. */
|
|
4
|
+
export declare const BAND_MIN = 320;
|
|
5
|
+
/** Most captures one conversion makes. */
|
|
6
|
+
export declare const BAND_CAP = 6;
|
|
7
|
+
export declare const DEFAULT_BAND_DEVICES: ReadonlyArray<{
|
|
8
|
+
width: number;
|
|
9
|
+
height: number;
|
|
10
|
+
}>;
|
|
11
|
+
export interface BandPlan {
|
|
12
|
+
/** CSS viewport edges, ascending; `edges.length === captures.length - 1`. */
|
|
13
|
+
edges: BandEdge[];
|
|
14
|
+
/** One per band, ascending; the band's lowest capture, which represents it. */
|
|
15
|
+
captures: Array<{
|
|
16
|
+
width: number;
|
|
17
|
+
height: number;
|
|
18
|
+
}>;
|
|
19
|
+
/** Container queries: one more capture per band at its upper bound (the band capture's height), lowest bands first;
|
|
20
|
+
* then, lowest bands first, a band other than band 0 and `first`'s is captured at its lower bound instead and its
|
|
21
|
+
* device capture moves here; while captures + extra stay ≤ BAND_CAP. `[]` without container queries. */
|
|
22
|
+
extra: Array<{
|
|
23
|
+
width: number;
|
|
24
|
+
height: number;
|
|
25
|
+
}>;
|
|
26
|
+
/** Probe width per band (used only when the band's capture needs a probe). */
|
|
27
|
+
probes: Array<number | undefined>;
|
|
28
|
+
/** Thresholds not reconstructed, as warning messages. */
|
|
29
|
+
notes: string[];
|
|
30
|
+
}
|
|
31
|
+
/** Tailwind's default breakpoints by `min-width` px. */
|
|
32
|
+
export declare const TAILWIND_BANDS: Record<number, string>;
|
|
33
|
+
/** Tailwind's container scale (`@md`, …) by `min-width` px. */
|
|
34
|
+
export declare const TAILWIND_CONTAINER_BANDS: Record<number, string>;
|
|
35
|
+
/** One name per band: band 0 `""`, band `k` its lower CSS edge — a Tailwind default name, else `w<capture width>`.
|
|
36
|
+
* `prefix` (`cq_`): container bands, named from Tailwind's container scale. */
|
|
37
|
+
export declare function bandNames(cssEdges: BandEdge[], prefix?: string): string[];
|
|
38
|
+
/** A width `@container` query attributed to a host node: the conversion reconstructs it at that host. */
|
|
39
|
+
export declare function isContainerQuery(c: LayoutCondition): boolean;
|
|
40
|
+
/** Edges ascending by capture width, `min-width` first on ties; one edge per capture width. */
|
|
41
|
+
export declare function uniqueEdges(all: BandEdge[]): BandEdge[];
|
|
42
|
+
/** Band edges from the `media` width conditions, one capture and probe width per band (+ `extra`, container queries). */
|
|
43
|
+
export declare function planBands(conditions: LayoutCondition[], options: {
|
|
44
|
+
first: {
|
|
45
|
+
width: number;
|
|
46
|
+
height: number;
|
|
47
|
+
};
|
|
48
|
+
devices: ReadonlyArray<{
|
|
49
|
+
width: number;
|
|
50
|
+
height: number;
|
|
51
|
+
}>;
|
|
52
|
+
max: number;
|
|
53
|
+
}): BandPlan;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { LayoutDoc } from "../model/layout.ts";
|
|
2
|
+
import { type BandEdge, type ConversionWarning, type SemNode, type Screen } from "../model/semantic.ts";
|
|
3
|
+
/** Root-proposal edges of a set of band captures (and each capture's band), or the reason the root does not follow
|
|
4
|
+
* the viewport. Every band holds a capture, ascending by width; more than one only on pages with container queries
|
|
5
|
+
* (the planner's `extra`). */
|
|
6
|
+
export declare function bandEdges(docs: LayoutDoc[]): {
|
|
7
|
+
edges: BandEdge[];
|
|
8
|
+
cssEdges: BandEdge[];
|
|
9
|
+
bands: number[];
|
|
10
|
+
} | {
|
|
11
|
+
warning: string;
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Compose per-capture screens into one root with holders and query containers; undefined when no element differs
|
|
15
|
+
* between captures and nothing is reported (the root is band 0's when only warnings are). `bands`: each capture's
|
|
16
|
+
* viewport band (ascending; default one capture per band). A band's lowest
|
|
17
|
+
* capture represents it; the others are container-query captures, seen only by the query containers inside.
|
|
18
|
+
*/
|
|
19
|
+
export declare function mergeBands(docs: LayoutDoc[], screens: Screen[], bands?: number[]): {
|
|
20
|
+
root: SemNode;
|
|
21
|
+
warnings: ConversionWarning[];
|
|
22
|
+
} | undefined;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Colour names a design put in a class list — the utility-framework counterpart of
|
|
3
|
+
* `var(--token)` in an inline style. Pure and input-agnostic: a page with no colour
|
|
4
|
+
* utilities yields nothing, so the inference pass can always ask.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Token-hint channel for the emit pass: the *semantic* part of a node's colour utilities, in
|
|
8
|
+
* the same `Style.tokens` list that carries CSS custom-property names, qualified by the utility
|
|
9
|
+
* that painted it (`bg-card` → `bg:card`, `text-muted-foreground` → `text:muted-foreground`,
|
|
10
|
+
* `from-sky-500` → `from:sky-500`). The qualifier is what lets the token pass match a name to
|
|
11
|
+
* the slot its utility paints — one node's `bg-white text-black` are two names for two slots,
|
|
12
|
+
* not two candidates for either — and `tokens.ts` camelizes the name (`Palette.sky500`).
|
|
13
|
+
* A custom-property name never contains `:`, so the two kinds cannot collide.
|
|
14
|
+
*
|
|
15
|
+
* Every variant (`dark:`, `hover:`, `md:`, `focus:`) is dropped. `hover:`/`md:` name states the
|
|
16
|
+
* static capture never sees; a `dark:` utility names the *dark* value of the slot, and one hint
|
|
17
|
+
* list per node cannot say which theme a hint belongs to, so using it would name the light colour
|
|
18
|
+
* after its dark counterpart (`text-slate-500 dark:text-slate-400` → `slate400`). Arbitrary
|
|
19
|
+
* values (`bg-[#0f172a]`) carry no name and are dropped.
|
|
20
|
+
*/
|
|
21
|
+
export declare function classColorHints(attrs: Record<string, string>): string[];
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/** Shared inference data contracts. No runtime dependencies. */
|
|
2
|
+
import { type LayoutNode, type Rect } from "../model/layout.ts";
|
|
3
|
+
import { type LabelIndex } from "./controls.ts";
|
|
4
|
+
import { type SemNode, type Axis, type CrossAlign, type TextRun } from "../model/semantic.ts";
|
|
5
|
+
import { type BundledFamilies } from "../model/fonts.ts";
|
|
6
|
+
import { type TableSlots } from "./table.ts";
|
|
7
|
+
/** A text run: one text node and the element whose computed style it inherits. */
|
|
8
|
+
export interface SourceTextRun {
|
|
9
|
+
node: LayoutNode;
|
|
10
|
+
styleOf: LayoutNode;
|
|
11
|
+
}
|
|
12
|
+
export interface AnalyzedChild {
|
|
13
|
+
node: LayoutNode;
|
|
14
|
+
sem: SemNode;
|
|
15
|
+
}
|
|
16
|
+
export interface InferOptions {
|
|
17
|
+
/** Fonts packaged for this conversion; omitted families use system fallback. */
|
|
18
|
+
bundledFamilies?: BundledFamilies;
|
|
19
|
+
}
|
|
20
|
+
export interface InferenceContext {
|
|
21
|
+
bundledFamilies: BundledFamilies;
|
|
22
|
+
/** Capture root; lets SVG `<use>` resolve sprites elsewhere in the document. */
|
|
23
|
+
root: LayoutNode;
|
|
24
|
+
/** `position: fixed` descendants collected for hoisting onto the screen root. */
|
|
25
|
+
fixed: LayoutNode[];
|
|
26
|
+
parent?: LayoutNode;
|
|
27
|
+
parentAxis?: Axis;
|
|
28
|
+
parentDisplay?: string;
|
|
29
|
+
parentAlign?: CrossAlign;
|
|
30
|
+
/** Nearest ancestor with `background-clip: text`: its gradient is the glyph fill of block descendants' text. */
|
|
31
|
+
textClip?: LayoutNode;
|
|
32
|
+
/** Capture viewport in root coordinates (see LayoutDoc.viewport). */
|
|
33
|
+
viewport?: Rect;
|
|
34
|
+
/** `<label>` ↔ control pairs of the capture; absent in hand-built contexts. */
|
|
35
|
+
labels?: LabelIndex;
|
|
36
|
+
/** The rows box `captionOutside` split off an admitted table, and its slots: `build` lays it out as the table. */
|
|
37
|
+
table?: {
|
|
38
|
+
rows: LayoutNode;
|
|
39
|
+
slots: TableSlots;
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/** A run under construction: the emitted run plus, per character, its index in the raw text node. */
|
|
43
|
+
export interface MeasuredTextRun {
|
|
44
|
+
run: TextRun;
|
|
45
|
+
node: LayoutNode;
|
|
46
|
+
/** The element whose computed style the run inherits — `host` itself for its own text nodes. */
|
|
47
|
+
styleOf: LayoutNode;
|
|
48
|
+
src: number[];
|
|
49
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* HTML controls → `ControlNode`. Tag plus attributes decide *what* the element is; the measured
|
|
3
|
+
* box, padding and paint still come from the generic inference pass, so a control looks exactly
|
|
4
|
+
* like the box it replaced and only gains its interactive core.
|
|
5
|
+
*
|
|
6
|
+
* Nothing here reads geometry: `input[type=range]` is a slider however the design paints it.
|
|
7
|
+
*/
|
|
8
|
+
import type { LayoutNode } from "../model/layout.ts";
|
|
9
|
+
import type { Color } from "../model/values.ts";
|
|
10
|
+
import { type Action, type ControlKind, type ControlNode, type Diagnostic, type FontSpec, type PickerOption, type SemBase, type SemNode } from "../model/semantic.ts";
|
|
11
|
+
/** An element's own action: its `onclick`, else the submit handler of its form, else a member of its own. */
|
|
12
|
+
export declare function elementAction(n: LayoutNode, caption: string, form?: LayoutNode): Action;
|
|
13
|
+
/** `<form onsubmit>`: what its submit buttons and Return in its fields run. */
|
|
14
|
+
export declare function submitAction(form: LayoutNode): Action | undefined;
|
|
15
|
+
/** An `<a href>` the app must resolve itself (fragment, relative path); undefined for an absolute URL. */
|
|
16
|
+
export declare function linkAction(a: LayoutNode): Action | undefined;
|
|
17
|
+
/**
|
|
18
|
+
* The action of an element the design makes activatable without being a control (`<div role=button
|
|
19
|
+
* onclick>`, `<li onclick>`). It stays the view it is — same layout — and the emitter wraps it in a
|
|
20
|
+
* Button; one that contains another control gets a tap gesture instead.
|
|
21
|
+
*/
|
|
22
|
+
export declare function activatableAction(n: LayoutNode): Action | undefined;
|
|
23
|
+
/** `controlOf`'s answer: which control an element is, with the attribute state the design shows. */
|
|
24
|
+
export interface ControlSpec {
|
|
25
|
+
control: ControlKind;
|
|
26
|
+
value?: string;
|
|
27
|
+
swatch?: Color;
|
|
28
|
+
placeholder?: string;
|
|
29
|
+
promptColor?: Color;
|
|
30
|
+
inputType?: ControlNode["inputType"];
|
|
31
|
+
autofill?: string;
|
|
32
|
+
inputMode?: string;
|
|
33
|
+
enterKey?: string;
|
|
34
|
+
checked?: boolean;
|
|
35
|
+
group?: string;
|
|
36
|
+
form?: string;
|
|
37
|
+
disabled?: boolean;
|
|
38
|
+
range?: {
|
|
39
|
+
min: number;
|
|
40
|
+
max: number;
|
|
41
|
+
step?: number;
|
|
42
|
+
};
|
|
43
|
+
level?: ControlNode["level"];
|
|
44
|
+
options?: PickerOption[];
|
|
45
|
+
href?: string;
|
|
46
|
+
action?: Action;
|
|
47
|
+
expanded?: boolean;
|
|
48
|
+
files?: ControlNode["files"];
|
|
49
|
+
dateKind?: ControlNode["dateKind"];
|
|
50
|
+
/** Losses to record on the node (a link with no runtime destination, an unsupported input type). */
|
|
51
|
+
diagnostics: Diagnostic[];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The control this element is, or `undefined` when it is an ordinary box. Attribute-only: the
|
|
55
|
+
* caller supplies the measured base and the built children; `labels` adds what the element's
|
|
56
|
+
* surroundings decide (its form owner, a `<fieldset disabled>` around it).
|
|
57
|
+
*/
|
|
58
|
+
export declare function controlOf(n: LayoutNode, labels?: LabelIndex): ControlSpec | undefined;
|
|
59
|
+
/** A control's laid-out surroundings, as the generic container path produced them. */
|
|
60
|
+
export interface ControlParts {
|
|
61
|
+
/** The box the generic path would have painted: frame, padding, style, diagnostics. */
|
|
62
|
+
base: SemBase;
|
|
63
|
+
/** Element children, in document order, already built. */
|
|
64
|
+
children: Array<{
|
|
65
|
+
node: LayoutNode;
|
|
66
|
+
sem: SemNode;
|
|
67
|
+
}>;
|
|
68
|
+
/** The element's own text, one node per run group. */
|
|
69
|
+
texts: SemNode[];
|
|
70
|
+
/** Font and colour of the element's own text, for the value the control draws itself. */
|
|
71
|
+
font?: FontSpec;
|
|
72
|
+
color?: Color;
|
|
73
|
+
/** Computed `appearance` and `accent-color` of the element. */
|
|
74
|
+
appearance?: string;
|
|
75
|
+
accent?: Color;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* The control node: `spec`'s attribute state on `parts.base`'s measured box. Children become
|
|
79
|
+
* `content` in measured order (a `<summary>` becomes the disclosure's `label` instead).
|
|
80
|
+
*/
|
|
81
|
+
export declare function buildControl(spec: ControlSpec, parts: ControlParts): ControlNode;
|
|
82
|
+
/** `<label>` ↔ control (HTML: `for` names an element id; otherwise the first control inside). */
|
|
83
|
+
export interface LabelIndex {
|
|
84
|
+
/** Control element → its label's text (the label's text content without the control's own). */
|
|
85
|
+
text: Map<LayoutNode, string>;
|
|
86
|
+
/** Label element → the enabled toggle/radio (native, or an ARIA toggle role) a tap on the label changes, or text field it focuses. */
|
|
87
|
+
activates: Map<LayoutNode, LayoutNode>;
|
|
88
|
+
/** `<input>`/`<button>` → its form owner (HTML: the `<form>` its `@form` names, else its nearest ancestor `<form>`). */
|
|
89
|
+
forms: Map<LayoutNode, LayoutNode>;
|
|
90
|
+
/** Form controls a `<fieldset disabled>` disables (everything in it but its first `<legend>`). */
|
|
91
|
+
disabled: Set<LayoutNode>;
|
|
92
|
+
/** First element per DOM `id`. */
|
|
93
|
+
byId: Map<string, LayoutNode>;
|
|
94
|
+
/** `role=radio` element → the id of its nearest `role=radiogroup` ancestor. */
|
|
95
|
+
radioGroups: Map<LayoutNode, string>;
|
|
96
|
+
}
|
|
97
|
+
export declare function labelIndex(root: LayoutNode): LabelIndex;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Authored flex rows the runtime `MarkswiftFlexRow` reproduces, admitted only when they reproduce the capture. */
|
|
2
|
+
import type { LayoutNode } from "../model/layout.ts";
|
|
3
|
+
import type { FlexItem, FlexRow } from "../model/semantic.ts";
|
|
4
|
+
/**
|
|
5
|
+
* Item widths for a content width, mirroring MarkswiftFlexRow.widths (runtime/flex-row.swift): CSS's flex freeze
|
|
6
|
+
* loop (css-flexbox §9.7) with min/max clamps, shrink weighted by the inner basis and factor sums below 1.
|
|
7
|
+
* `bases`: each item's px basis (the px part for a percentage basis, resolved here against `width`).
|
|
8
|
+
*/
|
|
9
|
+
export declare function solveFlexRow(items: FlexItem[], bases: number[], width: number, gap: number): number[];
|
|
10
|
+
/**
|
|
11
|
+
* The admitted row, or undefined. Pure on the captured LayoutNode, memoised. `atProbe` skips the candidate gate
|
|
12
|
+
* (step 5): a probe capture verifies the solver, and at another width the native HStack may suffice (unshrunk items).
|
|
13
|
+
*/
|
|
14
|
+
export declare function admitFlexRow(n: LayoutNode, atProbe?: boolean): FlexRow | undefined;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { LayoutNode } from "../model/layout.ts";
|
|
2
|
+
import { type Axis, type Size, type Diagnostic } from "../model/semantic.ts";
|
|
3
|
+
import type { InferenceContext } from "./context.ts";
|
|
4
|
+
/** Native stacks can share equal leftover space, but cannot reproduce arbitrary CSS allocation. */
|
|
5
|
+
export declare function flexGrowthSize(n: LayoutNode, axis: Axis, ctx: InferenceContext, diagnostics: Diagnostic[]): Size | undefined;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Flow, float, stack and grid layout inference. */
|
|
2
|
+
import { type SemBase, type CrossAlign, type Distribution, type StackNode, type Axis } from "../model/semantic.ts";
|
|
3
|
+
import { type AnalyzedChild } from "./context.ts";
|
|
4
|
+
/**
|
|
5
|
+
* Stack geometry from measured child frames: spacing per adjacent pair (uniform when equal),
|
|
6
|
+
* and the leading offset the base's padding does not explain. A float's neighbour overlaps its
|
|
7
|
+
* box (the browser shortens line boxes instead of the block), so the gap is the float's margin;
|
|
8
|
+
* a negative `margin-top` really does overlap, and negative spacing reproduces it.
|
|
9
|
+
*/
|
|
10
|
+
export declare function stackOf(base: SemBase, axis: Axis, all: AnalyzedChild[], align: CrossAlign, distribution: Distribution, flex?: boolean): StackNode;
|
|
11
|
+
/**
|
|
12
|
+
* Measured lines: items overlapping vertically (by more than half the shorter box) and clear of
|
|
13
|
+
* each other horizontally share a line. Boxes that overlap on both axes are not a line but a
|
|
14
|
+
* negative margin — except around a float, whose neighbour's box overlaps it while its ink does
|
|
15
|
+
* not (the browser shortens the line boxes, not the block). Lines run top→bottom, items in a
|
|
16
|
+
* line left→right.
|
|
17
|
+
*/
|
|
18
|
+
export declare function linesOf(all: AnalyzedChild[]): AnalyzedChild[][];
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/** Generated content (`::before`/`::after`/`::marker`): inline images, counters, alt text, undrawn images. */
|
|
2
|
+
import { type LayoutNode } from "../model/layout.ts";
|
|
3
|
+
import { type TextRun } from "../model/semantic.ts";
|
|
4
|
+
/** Content-bearing pseudo-elements (not `::backdrop` and other boxes without `content`). */
|
|
5
|
+
export declare const PSEUDO: Readonly<Record<string, true>>;
|
|
6
|
+
/** An `img` child of a pseudo whose bytes were captured (`data:`): it rides in the pseudo's text as an image run. */
|
|
7
|
+
export declare function inlineImage(parent: LayoutNode, k: LayoutNode): boolean;
|
|
8
|
+
/** The alt text of a pseudo's generated image: `content: url(…) / "alt"`, else `""` (decorative); undefined off a pseudo. */
|
|
9
|
+
export declare function generatedAlt(p: LayoutNode | undefined): string | undefined;
|
|
10
|
+
/** A pseudo that names more `url()` images than the browser laid out: the diagnostic reporting the loss. */
|
|
11
|
+
export declare function undrawnImages(p: LayoutNode): {
|
|
12
|
+
feature: "content" | "list-style-image";
|
|
13
|
+
message: string;
|
|
14
|
+
} | undefined;
|
|
15
|
+
/** The counter a pseudo printed as `text` (a counter `list-style-type` marker, `content: counter()`), if regenerable. */
|
|
16
|
+
export declare function counterOf(el: LayoutNode, text: string): TextRun["counter"];
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/** Measured box geometry and reusable inset calculations. */
|
|
2
|
+
import { type LayoutNode, type Rect } from "../model/layout.ts";
|
|
3
|
+
import { type SemNode, type Axis } from "../model/semantic.ts";
|
|
4
|
+
/** Rendered at all: a `display: none` box is collapsed away by the browser, so we drop it too. */
|
|
5
|
+
export declare function renders(n: LayoutNode): boolean;
|
|
6
|
+
/**
|
|
7
|
+
* Does this box lie entirely left of the content box that starts at `x`? A
|
|
8
|
+
* `list-style-position: outside` marker does: it hangs in the parent's padding and takes no
|
|
9
|
+
* part in the flow, so the text column keeps its own width and wrapped lines stay aligned
|
|
10
|
+
* under the first one. `stackOf` drops such a child; `buildOverlays` draws it where it was.
|
|
11
|
+
*/
|
|
12
|
+
export declare function hangsLeading(box: Rect, x: number): boolean;
|
|
13
|
+
/** Any descendant that fills its width — such a subtree stays greedy inside a hugging container. */
|
|
14
|
+
export declare function fillsWidthInside(n: SemNode): boolean;
|
|
15
|
+
/** Taken out of normal flow to one side, with the line boxes beside it shortened. */
|
|
16
|
+
export declare function floating(n: LayoutNode): boolean;
|
|
17
|
+
/** Positioned out of normal flow (`absolute`/`fixed`): placed as an overlay, never laid out by its parent. */
|
|
18
|
+
export declare function outOfFlow(n: LayoutNode): boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Used offset of a `position: relative` box from its Typed-OM insets (046; the snapshot's computed `top` reports a `%`
|
|
21
|
+
* against an auto-height block as px Chrome never applies). `top` beats `bottom`; `left` beats `right` unless the
|
|
22
|
+
* containing block (`cb`, the DOM parent) is rtl. `%` resolves against `cb`'s content box; a `%` top/bottom against an
|
|
23
|
+
* indefinite height is `auto`, so the other side applies (`top:10%; bottom:5px` → −5, as Chrome). `[0, 0]` for every
|
|
24
|
+
* other box. `losses` are diagnostic messages.
|
|
25
|
+
*/
|
|
26
|
+
export declare function relativeOffset(n: LayoutNode, cb: LayoutNode | undefined): {
|
|
27
|
+
offset: [number, number];
|
|
28
|
+
losses: string[];
|
|
29
|
+
};
|
|
30
|
+
/** A computed `display` that lays out its children as a flex container (`flex`, `inline-flex`). */
|
|
31
|
+
export declare function isFlex(display: string | undefined): boolean;
|
|
32
|
+
/** The axis `n` stacks its children on: horizontal only for a row-direction flex container. */
|
|
33
|
+
export declare function mainAxis(n: LayoutNode): Axis;
|
|
34
|
+
/**
|
|
35
|
+
* Tops of the measured line boxes under `el`. DOMSnapshot reports inline *fragments* — Blink
|
|
36
|
+
* splits one at every collapsed source newline — so fragments that share a top edge are one
|
|
37
|
+
* line; the same grouping `markLineBreaks` uses to place the forced breaks.
|
|
38
|
+
*/
|
|
39
|
+
export declare function lineTops(el: LayoutNode): number[];
|
|
40
|
+
export declare const EDGES: readonly ["top", "right", "bottom", "left"];
|
|
41
|
+
export type EdgeName = (typeof EDGES)[number];
|
|
42
|
+
/** Border width of one edge; 0 when its style paints nothing. */
|
|
43
|
+
export declare function edgeWidth(s: Record<string, string>, edge: EdgeName): number;
|
|
44
|
+
/**
|
|
45
|
+
* Padding + border per edge (top, right, bottom, left): the distance from the box edge to its content.
|
|
46
|
+
* Rows and row groups have none: CSS ignores their padding, a collapsed border lies inside the cells' boxes
|
|
47
|
+
* and a separated one is not drawn.
|
|
48
|
+
*/
|
|
49
|
+
export declare function insetsOf(s: Record<string, string>): [number, number, number, number];
|
|
50
|
+
export declare function unionRect(a: Rect, b: Rect): Rect;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/** Authored grid tracks the runtime `MarkswiftTracks` reproduces, admitted only when they reproduce the capture. */
|
|
2
|
+
import type { LayoutNode } from "../model/layout.ts";
|
|
3
|
+
import type { GridPlacement, GridRowTrack, GridTemplate } from "../model/semantic.ts";
|
|
4
|
+
/**
|
|
5
|
+
* Column widths for a content width, mirroring MarkswiftTracks.columns (runtime/tracks.swift). fr tracks follow CSS's
|
|
6
|
+
* "find the size of an fr": an fr sum below 1 leaves space unused, and a track whose `minmax(<px>, fr)` floor exceeds
|
|
7
|
+
* its share freezes at the floor while the rest share again.
|
|
8
|
+
*/
|
|
9
|
+
export declare function solveTracks(t: GridTemplate, width: number, gap: number, count: number, autoWidths: number[]): number[];
|
|
10
|
+
/**
|
|
11
|
+
* Row heights, mirroring MarkswiftTracks.rowHeights (runtime/tracks.swift). CSS grid §12.5 for heights (an item's min-
|
|
12
|
+
* and max-content heights are equal): a spanning item's missing height goes equally to its spanned auto rows that no
|
|
13
|
+
* item has sized yet, else equally to all its spanned auto rows; same-span items take the max per row, smaller first.
|
|
14
|
+
*/
|
|
15
|
+
export declare function solveRows(rows: GridRowTrack[], autoRow: GridRowTrack, gap: number, items: Array<{
|
|
16
|
+
row: number;
|
|
17
|
+
span: number;
|
|
18
|
+
height: number;
|
|
19
|
+
}>): number[];
|
|
20
|
+
type Span = {
|
|
21
|
+
start?: number;
|
|
22
|
+
span: number;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* CSS grid §8.5 auto-placement, `grid-auto-flow: row` (sparse), in a grid of `k` explicit columns: items with both
|
|
26
|
+
* lines first, then items locked to a row, then the rest behind a cursor. Each item's 1-based [column, row] start, or
|
|
27
|
+
* undefined when an item needs an implicit column or two items with both lines overlap.
|
|
28
|
+
*/
|
|
29
|
+
export declare function placeItems(k: number, items: Array<{
|
|
30
|
+
col: Span;
|
|
31
|
+
row: Span;
|
|
32
|
+
}>): Array<[number, number]> | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* The authored template, rows and every item's placement when the solvers reproduce every captured cell within 1px;
|
|
35
|
+
* else undefined.
|
|
36
|
+
*/
|
|
37
|
+
export declare function admitTracks(n: LayoutNode): {
|
|
38
|
+
template: GridTemplate;
|
|
39
|
+
stretch: boolean;
|
|
40
|
+
rows?: GridRowTrack[];
|
|
41
|
+
autoRow?: GridRowTrack;
|
|
42
|
+
placements: GridPlacement[];
|
|
43
|
+
} | undefined;
|
|
44
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Native-grid admission is proven from resolved tracks and captured cell geometry. */
|
|
2
|
+
import type { LayoutNode } from "../model/layout.ts";
|
|
3
|
+
import { type GridNode, type SemBase } from "../model/semantic.ts";
|
|
4
|
+
import type { AnalyzedChild } from "./context.ts";
|
|
5
|
+
export declare function buildGrid(n: LayoutNode, base: SemBase, all: AnalyzedChild[]): GridNode;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Layout tree traversal and semantic node dispatch. */
|
|
2
|
+
import { type LayoutDoc, type LayoutNode } from "../model/layout.ts";
|
|
3
|
+
import { type Screen, type SemNode, type Overlay } from "../model/semantic.ts";
|
|
4
|
+
import { type InferOptions } from "./context.ts";
|
|
5
|
+
export declare function inferScreen(doc: LayoutDoc, name: string, options?: InferOptions): Screen;
|
|
6
|
+
/**
|
|
7
|
+
* A node outside the captured tree (an in-flow layer's content, `layers.ts`) built as a child of `parent`. Fixed
|
|
8
|
+
* descendants are not hoisted: `fixed` counts the ones left out.
|
|
9
|
+
*/
|
|
10
|
+
export declare function buildDetached(node: LayoutNode, parent: LayoutNode, doc: LayoutDoc, options?: InferOptions): {
|
|
11
|
+
sem: SemNode;
|
|
12
|
+
fixed: number;
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* A presented layer's roots (`layers.ts`) as root overlays, built like the screen's own fixed nodes (fixed
|
|
16
|
+
* descendants drained into further roots); every one is `fixed`.
|
|
17
|
+
*/
|
|
18
|
+
export declare function layerOverlays(doc: LayoutDoc, nodes: LayoutNode[], options?: InferOptions): Overlay[];
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Paint that is invisible at rest and can never become visible is wasted render work: drop it from the IR. */
|
|
2
|
+
import { type SemNode } from "../model/semantic.ts";
|
|
3
|
+
/** Removes invisible overlays; an invisible in-flow node keeps its space but draws nothing. Never touches `n` itself. */
|
|
4
|
+
export declare function dropInvisible(n: SemNode): void;
|
|
5
|
+
/** Keeps `hitTesting: false` where it changes a tap: on overlays (they paint over siblings), outermost only. */
|
|
6
|
+
export declare function pruneHitTesting(n: SemNode, overlay?: boolean, inside?: boolean): void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* App mode: closed in-flow layers (`<details>`, collapsibles, accordion items) become content behind the screen's state;
|
|
3
|
+
* dialogs, sheets, popovers and hover cards become drawn presentations (plan 060, D-PRESENT); menus and listboxes
|
|
4
|
+
* become the trigger's native `Menu` (plan 061, D-MENUS).
|
|
5
|
+
*/
|
|
6
|
+
import { type LayoutDoc } from "../model/layout.ts";
|
|
7
|
+
import { type Screen } from "../model/semantic.ts";
|
|
8
|
+
import { type InferOptions } from "./context.ts";
|
|
9
|
+
/**
|
|
10
|
+
* Each `inflow` layer of `doc`: a `<details>` gets the content and `opens`; anything else inserts the content into its
|
|
11
|
+
* plain parent stack after its rest predecessor (`shownBy`), and the trigger Button `opens` it. A menu or listbox layer
|
|
12
|
+
* becomes its trigger's native menu (`menu`); each other layer that is not a tooltip (062) becomes a drawn presentation
|
|
13
|
+
* on the root (`present`). Skips are reported.
|
|
14
|
+
*/
|
|
15
|
+
export declare function applyLayers(screen: Screen, doc: LayoutDoc, options?: InferOptions): void;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** A shared coordinate contract for captured grid and wrapping fallbacks. */
|
|
2
|
+
import type { MeasuredLayout, SemBase, SemNode } from "../model/semantic.ts";
|
|
3
|
+
import type { AnalyzedChild } from "./context.ts";
|
|
4
|
+
/** Captured fallbacks stack their children in global paint order (z-index), not DOM order. */
|
|
5
|
+
export declare function paintOrder(items: AnalyzedChild[]): AnalyzedChild[];
|
|
6
|
+
export declare function measuredLayoutOf(base: SemBase, children: SemNode[]): MeasuredLayout;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/** CSS `@keyframes` animations captured by `browser/motion.ts` → IR `Motion` (D-MOTION), with per-node diagnostics. */
|
|
2
|
+
import type { Anim, LayoutNode } from "../model/layout.ts";
|
|
3
|
+
import { type Diagnostic, type Motion, type SemBase, type SemNode, type Style } from "../model/semantic.ts";
|
|
4
|
+
/**
|
|
5
|
+
* Captured pressed/focused transitions → per paint field timing, only for fields the node's look changes. `reduced`
|
|
6
|
+
* is the author's reduce lists, else D-MOTION's fallback: movement (`transform`) jumps, fades keep their timing.
|
|
7
|
+
*/
|
|
8
|
+
export declare function transitionsOf(n: LayoutNode, states: SemBase["states"], diagnostics: Diagnostic[]): Motion["transitions"];
|
|
9
|
+
/** LayoutNode.motion → IR motion + per-node diagnostics. Undefined when nothing is mapped. Inference is mode-independent. */
|
|
10
|
+
export declare function motionOf(n: LayoutNode, style: Style, diagnostics: Diagnostic[]): Motion | undefined;
|
|
11
|
+
/**
|
|
12
|
+
* In-flow layer content (066): `height` keyframes from 0 to the node's own height (or `auto`) open it, the reverse
|
|
13
|
+
* closes it; their timing becomes `reveal`, and the lists come back without `height`. Other shapes are reported.
|
|
14
|
+
*/
|
|
15
|
+
export declare function revealOf(n: LayoutNode, diagnostics: Diagnostic[]): {
|
|
16
|
+
reveal?: NonNullable<Motion["reveal"]>;
|
|
17
|
+
enter: Anim[];
|
|
18
|
+
exit: Anim[];
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* A layer root's captured enter and exit (066), after its placement is decided (`analysis/layers.ts`): the enter joins
|
|
22
|
+
* `animations` (the root is inserted when its layer opens, so it plays on appear) with D-MOTION's fallback under Reduce
|
|
23
|
+
* Motion (movement removed, opacity kept); the first exit becomes `exit`, exact for two keyframes starting at the
|
|
24
|
+
* settled look, else played first → last (reported).
|
|
25
|
+
*/
|
|
26
|
+
export declare function layerMotionOf(n: LayoutNode, sem: SemNode, lists: {
|
|
27
|
+
enter: Anim[];
|
|
28
|
+
exit: Anim[];
|
|
29
|
+
}): void;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Name hints from an element's own markup: what generated Swift names (components, fields) may use. */
|
|
2
|
+
import type { SemBase } from "../model/semantic.ts";
|
|
3
|
+
/** First of `data-markswift-component`, `id`, `data-slot`, `aria-label`, first non-utility class, tag noun. */
|
|
4
|
+
export declare function nameHintOf(tag: string, attrs: Record<string, string>): SemBase["nameHint"];
|
|
5
|
+
/** Trimmed `data-markswift-field`; undefined when absent or empty. */
|
|
6
|
+
export declare function fieldOf(attrs: Record<string, string>): string | undefined;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Semantic node base construction and confidence classification. */
|
|
2
|
+
import { type SemNode, type SemBase } from "../model/semantic.ts";
|
|
3
|
+
import { type LayoutNode } from "../model/layout.ts";
|
|
4
|
+
import { type InferenceContext } from "./context.ts";
|
|
5
|
+
export declare function finish<T extends SemNode>(node: T): T;
|
|
6
|
+
export declare function withBase<T extends Partial<SemNode>>(n: LayoutNode, ctx: InferenceContext, extra: T): SemNode;
|
|
7
|
+
/**
|
|
8
|
+
* The element and every rendered element below it compute `pointer-events: none` (an `auto` descendant stays
|
|
9
|
+
* hittable in CSS). `pointer-events` inherits: a child with no key and no children (046's synthetic pseudo `img`,
|
|
10
|
+
* `styles: {}`) passes under a `none` parent.
|
|
11
|
+
*/
|
|
12
|
+
export declare function passesTaps(n: LayoutNode): boolean;
|
|
13
|
+
export declare function makeBase(n: LayoutNode, ctx: InferenceContext, declared: Record<string, string>): SemBase;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Normalize browser-computed CSS constraints to the semantic border-box contract. */
|
|
2
|
+
import type { LayoutNode } from "../model/layout.ts";
|
|
3
|
+
import { type SizeConstraints, type Diagnostic } from "../model/semantic.ts";
|
|
4
|
+
import type { InferenceContext } from "./context.ts";
|
|
5
|
+
export declare function constraintsOf(n: LayoutNode, declared: Record<string, string>, ctx: InferenceContext, diagnostics: Diagnostic[]): SizeConstraints;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Intrinsic versus fixed sizing inferred from measured content. */
|
|
2
|
+
import { type LayoutNode } from "../model/layout.ts";
|
|
3
|
+
import { type Size, type SizeConstraints, type Diagnostic } from "../model/semantic.ts";
|
|
4
|
+
import { type InferenceContext } from "./context.ts";
|
|
5
|
+
/**
|
|
6
|
+
* The box's bottom inset as the browser left it: its own padding, plus the last in-flow child's
|
|
7
|
+
* bottom margin when a padded box keeps it from collapsing through. A hugging box has nowhere
|
|
8
|
+
* else to put that gap — a stack's spacing only lives between children — so it becomes inset.
|
|
9
|
+
* Only for boxes whose children are all elements: text-node boxes are glyph areas, and their
|
|
10
|
+
* line-box slack would masquerade as a margin. Capped at padding + that margin: any further
|
|
11
|
+
* slack is placement (min-height, flex alignment), never padding.
|
|
12
|
+
*/
|
|
13
|
+
export declare function trailingInset(n: LayoutNode, height: Size, padBottom: number): number;
|
|
14
|
+
/**
|
|
15
|
+
* Cascaded preferred width/height retain fixed-size intent; older captures use inline styles.
|
|
16
|
+
* Otherwise geometry tells: parent content box → fill, own content → hug, other sizes →
|
|
17
|
+
* measured pixels. Flex allocation and constraints share the same border-box contract.
|
|
18
|
+
*/
|
|
19
|
+
export declare function sizeOf(n: LayoutNode, d: Record<string, string>, ctx: InferenceContext, diagnostics: Diagnostic[]): SizeConstraints & {
|
|
20
|
+
width: Size;
|
|
21
|
+
height: Size;
|
|
22
|
+
selfAlign?: "start" | "center" | "end";
|
|
23
|
+
selfAlignV?: "start" | "center" | "end";
|
|
24
|
+
};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** Computed background paint and text-clipped gradients. */
|
|
2
|
+
import type { LayoutNode, Rect } from "../model/layout.ts";
|
|
3
|
+
import { type Diagnostic } from "../model/semantic.ts";
|
|
4
|
+
import type { Paint } from "../model/values.ts";
|
|
5
|
+
/** `background-clip: text`: the element's gradient paints the glyphs of every text run below it. */
|
|
6
|
+
export declare function clipsText(el: LayoutNode): boolean;
|
|
7
|
+
/**
|
|
8
|
+
* `background-clip: text` — the box's first gradient layer becomes the glyph fill of `run`
|
|
9
|
+
* (a text-node box inside `el`), re-expressed over that box since native text fills span the
|
|
10
|
+
* glyph run while the browser painted across the whole element. Text builders attach it to
|
|
11
|
+
* the run; `styleOf` drops the box fills in return.
|
|
12
|
+
*/
|
|
13
|
+
export declare function textPaintOf(el: LayoutNode, run: Rect): Paint | undefined;
|
|
14
|
+
/**
|
|
15
|
+
* `url()` layer `i` of `background-*` / `mask-*` → image paint with its size, top-left
|
|
16
|
+
* position and repeat resolved in px. The position needs the drawn size: explicit
|
|
17
|
+
* `background-size`, the natural size (a data: svg's width/height, an embedded raster's
|
|
18
|
+
* header; a viewBox-only svg has just a ratio and fits the positioning area, per CSS), or the
|
|
19
|
+
* cover/contain scaling of that; unknown (remote files) → only a `0% 0%` position is certain.
|
|
20
|
+
* A data: svg is parsed here into the paint's `vector`; one that cannot be drawn is reported
|
|
21
|
+
* to `diagnostics`.
|
|
22
|
+
*/
|
|
23
|
+
export declare function imagePaint(url: string, s: Record<string, string>, prop: "background" | "mask", i: number, w: number, h: number, diagnostics: Diagnostic[]): Paint;
|
|
24
|
+
export declare function backgroundFills(s: Record<string, string>, w: number, h: number, diagnostics: Diagnostic[]): Paint[];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** CSS border geometry and Chrome's 3D edge shading. */
|
|
2
|
+
import { type Style, type Diagnostic } from "../model/semantic.ts";
|
|
3
|
+
/** The 1px themed edge Chrome paints instead of `s`'s computed border, when it draws its theme. */
|
|
4
|
+
export declare function themedBorder(tag: string, s: Record<string, string>): Partial<Style> | undefined;
|
|
5
|
+
/** The fill and edge Chrome's theme paints while the button is pressed. */
|
|
6
|
+
export declare function themedPressed(tag: string, s: Record<string, string>): Partial<Style> | undefined;
|
|
7
|
+
export declare function borderStyle(s: Record<string, string>, w: number, h: number, diagnostics: Diagnostic[]): Partial<Style>;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
/** Visual effects, clipping, visibility and design-token hints. */
|
|
2
|
+
import type { LayoutNode } from "../model/layout.ts";
|
|
3
|
+
import { type Style, type Diagnostic } from "../model/semantic.ts";
|
|
4
|
+
export declare function applyEffects(n: LayoutNode, style: Style, diagnostics: Diagnostic[]): void;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Computed visual styles and paint inference. */
|
|
2
|
+
import { type LayoutNode } from "../model/layout.ts";
|
|
3
|
+
import { type Style, type Diagnostic, type SemBase } from "../model/semantic.ts";
|
|
4
|
+
export declare function styleOf(n: LayoutNode, diagnostics: Diagnostic[]): Style;
|
|
5
|
+
/**
|
|
6
|
+
* `n.states` → paint deltas against the resting `rest`, by running `styleOf` on the state's computed
|
|
7
|
+
* values. A theme-painted button is pressed in Chrome's pressed theme, which no computed style shows.
|
|
8
|
+
*/
|
|
9
|
+
export declare function stateStylesOf(n: LayoutNode, rest: Style): SemBase["states"];
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** SVG presentation attributes, inherited values and references. */
|
|
2
|
+
import { type LayoutNode } from "../../model/layout.ts";
|
|
3
|
+
import { type SvgScope, type SvgContext } from "./context.ts";
|
|
4
|
+
export declare function inherit(parent: Record<string, string>, own: Record<string, string>): Record<string, string>;
|
|
5
|
+
/** Presentation value: computed style first, attribute fallback; inside a `<use>` instance `currentColor` follows the use element. */
|
|
6
|
+
export declare function styleProp(c: LayoutNode, attrs: Record<string, string>, k: string, scope: SvgScope): string | undefined;
|
|
7
|
+
/** `url(#id)` target from an attribute or the inline `style` (non-whitelisted properties such as `clip-path`/`mask`). */
|
|
8
|
+
export declare function reference(c: LayoutNode, attrs: Record<string, string>, k: string, ctx: SvgContext): LayoutNode | undefined;
|
|
9
|
+
export declare function parseDash(s: string | undefined): number[];
|
|
10
|
+
export declare function num(s: string | undefined, def?: number): number;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
/** Build semantic SVG nodes from measured layout trees. */
|
|
2
|
+
import { type LayoutNode } from "../../model/layout.ts";
|
|
3
|
+
import { type SemBase, type SvgNode } from "../../model/semantic.ts";
|
|
4
|
+
import { type BundledFamilies } from "../../model/fonts.ts";
|
|
5
|
+
/** Build the SvgNode for `n` on top of an already-measured `base` (frame, style, padding). `doc` is the document root used to resolve `#id` references. */
|
|
6
|
+
export declare function buildSvg(n: LayoutNode, base: SemBase, doc?: LayoutNode, bundledFamilies?: BundledFamilies): SvgNode;
|