@docx-editor.dev/core 0.0.1-placeholder → 2.0.1
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/LICENSE +201 -0
- package/README.md +92 -2
- package/THIRD_PARTY_NOTICES.md +18 -0
- package/dist/automation.cjs +1 -0
- package/dist/automation.d.cts +74 -0
- package/dist/automation.d.ts +74 -0
- package/dist/automation.js +1 -0
- package/dist/binding.cjs +1 -0
- package/dist/binding.d.cts +82 -0
- package/dist/binding.d.ts +82 -0
- package/dist/binding.js +1 -0
- package/dist/chunk-5KSCB2OZ.js +2 -0
- package/dist/chunk-BSC44TIT.js +5 -0
- package/dist/chunk-DLPL5DAG.js +12 -0
- package/dist/chunk-DOEIARE2.js +2 -0
- package/dist/chunk-G7YCQBZE.cjs +5 -0
- package/dist/chunk-HBL3NNH5.cjs +1 -0
- package/dist/chunk-HR7K3W6A.js +1 -0
- package/dist/chunk-HVAV2JSN.js +11 -0
- package/dist/chunk-MYH2HCUJ.cjs +2 -0
- package/dist/chunk-NSM75TN6.cjs +1 -0
- package/dist/chunk-PHDVKUWZ.js +1 -0
- package/dist/chunk-QADYGK5L.cjs +12 -0
- package/dist/chunk-REZUWYB7.js +1 -0
- package/dist/chunk-RNBHTPW7.js +10 -0
- package/dist/chunk-UD2ZXLFI.cjs +2 -0
- package/dist/chunk-VYAVK2AH.cjs +1 -0
- package/dist/chunk-YUK46A2N.cjs +11 -0
- package/dist/chunk-ZMIX42J7.cjs +10 -0
- package/dist/chunk-ZT55Q52J.cjs +2 -0
- package/dist/chunk-ZUALAR4M.js +2 -0
- package/dist/content-control-walk-CbTqHq6O.d.cts +56 -0
- package/dist/content-control-walk-D06GijR0.d.ts +56 -0
- package/dist/contracts/document.cjs +1 -0
- package/dist/contracts/document.d.cts +246 -0
- package/dist/contracts/document.d.ts +246 -0
- package/dist/contracts/document.js +0 -0
- package/dist/contracts/editor.cjs +1 -0
- package/dist/contracts/editor.d.cts +11 -0
- package/dist/contracts/editor.d.ts +11 -0
- package/dist/contracts/editor.js +1 -0
- package/dist/contracts/interaction.cjs +1 -0
- package/dist/contracts/interaction.d.cts +11 -0
- package/dist/contracts/interaction.d.ts +11 -0
- package/dist/contracts/interaction.js +0 -0
- package/dist/contracts/modules.cjs +1 -0
- package/dist/contracts/modules.d.cts +90 -0
- package/dist/contracts/modules.d.ts +90 -0
- package/dist/contracts/modules.js +1 -0
- package/dist/contracts/types.cjs +1 -0
- package/dist/contracts/types.d.cts +452 -0
- package/dist/contracts/types.d.ts +452 -0
- package/dist/contracts/types.js +0 -0
- package/dist/editor-C1QRi1v4.d.ts +1671 -0
- package/dist/editor-D0UDock4.d.cts +1671 -0
- package/dist/editor.cjs +1 -0
- package/dist/editor.css +6017 -0
- package/dist/editor.d.cts +271 -0
- package/dist/editor.d.ts +271 -0
- package/dist/editor.js +1 -0
- package/dist/hf-references-BdjsQNE_.d.ts +71 -0
- package/dist/hf-references-CgEOSw3i.d.cts +71 -0
- package/dist/image-resources-BJnTpG66.d.ts +195 -0
- package/dist/image-resources-BpIydXtU.d.cts +195 -0
- package/dist/index-CrW-IxXt.d.cts +2515 -0
- package/dist/index-ZqBEOrTV.d.ts +2515 -0
- package/dist/index.cjs +1 -0
- package/dist/index.d.cts +22 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.js +1 -0
- package/dist/layout.cjs +1 -0
- package/dist/layout.d.cts +2316 -0
- package/dist/layout.d.ts +2316 -0
- package/dist/layout.js +1 -0
- package/dist/note-nodes-BPSTVDMr.d.ts +108 -0
- package/dist/note-nodes-C6DLxlvj.d.cts +108 -0
- package/dist/note-properties-CnmCoory.d.cts +68 -0
- package/dist/note-properties-m75hmP70.d.ts +68 -0
- package/dist/ooxml-package-CR5us6ad.d.cts +354 -0
- package/dist/ooxml-package-D_CtywTW.d.ts +354 -0
- package/dist/ooxml-tree-BU0e3DVi.d.cts +871 -0
- package/dist/ooxml-tree-BU0e3DVi.d.ts +871 -0
- package/dist/output.cjs +1 -0
- package/dist/output.d.cts +158 -0
- package/dist/output.d.ts +158 -0
- package/dist/output.js +1 -0
- package/dist/protocol-CAkOBBGE.d.cts +1201 -0
- package/dist/protocol-oxHaWmt4.d.ts +1201 -0
- package/dist/review-support-DS8DYX2a.d.cts +326 -0
- package/dist/review-support-Fy3vdIea.d.ts +326 -0
- package/dist/revision-projection-72ZApe-g.d.cts +84 -0
- package/dist/revision-projection-DHAkcD_L.d.ts +84 -0
- package/dist/semantic-cell-selection-CZjBSmMv.d.cts +427 -0
- package/dist/semantic-cell-selection-DsmHmLJ5.d.ts +427 -0
- package/dist/semantic-interaction-D-Dszxrn.d.cts +187 -0
- package/dist/semantic-interaction-Dy-dCUFF.d.ts +187 -0
- package/dist/semantic-paint-drawings-BA3z9jl8.d.ts +21 -0
- package/dist/semantic-paint-drawings-D7qbB0E2.d.cts +21 -0
- package/dist/semantic-records-CJR3BvHs.d.cts +1432 -0
- package/dist/semantic-records-CWodBJsz.d.ts +1432 -0
- package/dist/shaped-measurer-B-TAtcQU.d.ts +613 -0
- package/dist/shaped-measurer-CNIT_svZ.d.cts +613 -0
- package/dist/store.cjs +1 -0
- package/dist/store.d.cts +2247 -0
- package/dist/store.d.ts +2247 -0
- package/dist/store.js +1 -0
- package/dist/tree-op-types-CwOeiaQ8.d.ts +1431 -0
- package/dist/tree-op-types-DMiW6nIH.d.cts +1431 -0
- package/dist/tree-package-store-D5S7VKs5.d.ts +708 -0
- package/dist/tree-package-store-DOKMtCnh.d.cts +708 -0
- package/dist/tree-session-CiUel5Kz.d.ts +542 -0
- package/dist/tree-session-D47_imvR.d.cts +542 -0
- package/dist/tree-store-CxifqwIv.d.cts +273 -0
- package/dist/tree-store-hLtjeyWE.d.ts +273 -0
- package/package.json +105 -15
- package/index.js +0 -1
|
@@ -0,0 +1,427 @@
|
|
|
1
|
+
import { e as OoxmlPart, a as OoxmlElement, O as OoxmlNode } from './ooxml-tree-BU0e3DVi.js';
|
|
2
|
+
import { P as PageGeometry, I as InlineDrawingRecord, A as AnchoredDrawingRecord, T as TextMeasurer, L as LineRecord, S as SemanticLayout, C as ContentControlBoundaryRecord, a as StyleSpanRecord, b as TableRowFragmentRecord, c as TableCellFragmentRecord } from './semantic-records-CWodBJsz.js';
|
|
3
|
+
import { R as RevisionDisplayMode } from './revision-projection-DHAkcD_L.js';
|
|
4
|
+
import { S as SemanticPosition, C as CaretGeometry, a as SemanticSelection } from './semantic-interaction-Dy-dCUFF.js';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Hard ceiling on sections enumerated from a document (matches write-path
|
|
8
|
+
* `MAX_SECTIONS` in note/hf lifecycle). Hostile packages with unbounded `w:sectPr`
|
|
9
|
+
* marks fail closed here rather than amplifying layout props arrays.
|
|
10
|
+
*/
|
|
11
|
+
declare const MAX_DOCUMENT_SECTIONS = 4096;
|
|
12
|
+
/** A section's margins in twips, including the header and footer reserve bands. */
|
|
13
|
+
interface SectionMargins {
|
|
14
|
+
readonly topTwips: number;
|
|
15
|
+
readonly rightTwips: number;
|
|
16
|
+
readonly bottomTwips: number;
|
|
17
|
+
readonly leftTwips: number;
|
|
18
|
+
readonly headerTwips: number;
|
|
19
|
+
readonly footerTwips: number;
|
|
20
|
+
readonly gutterTwips: number;
|
|
21
|
+
}
|
|
22
|
+
/** One explicit `w:col`: its width and the gap after it. */
|
|
23
|
+
interface SectionColumnDefinition {
|
|
24
|
+
readonly widthTwips: number;
|
|
25
|
+
/** Space after this column; zero on the final column. */
|
|
26
|
+
readonly gapTwips: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* A section's column layout.
|
|
30
|
+
*
|
|
31
|
+
* Equal-width and explicit-width columns are one type because a file may declare `w:num` with no
|
|
32
|
+
* `w:col` children at all, and layout must handle both without branching at every use site.
|
|
33
|
+
*/
|
|
34
|
+
interface SectionColumns {
|
|
35
|
+
readonly count: number;
|
|
36
|
+
/** Shared gap for equal-width columns and fallback gap for incomplete explicit definitions. */
|
|
37
|
+
readonly gapTwips: number;
|
|
38
|
+
readonly equalWidth?: boolean;
|
|
39
|
+
readonly separator?: boolean;
|
|
40
|
+
/** Authored `w:col` geometry when `equalWidth` is false. */
|
|
41
|
+
readonly definitions?: readonly SectionColumnDefinition[];
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* How this section is placed relative to the previous one (ECMA-376 17.6.22,
|
|
45
|
+
* `ST_SectionMark`).
|
|
46
|
+
*
|
|
47
|
+
* All five schema values are read. `nextColumn` paginates like `nextPage` for now: in a
|
|
48
|
+
* single-column section that IS Word's behaviour, and multi-column flow is not modelled,
|
|
49
|
+
* so collapsing it at the parse boundary would only hide the authored value from a
|
|
50
|
+
* consumer that asks.
|
|
51
|
+
*/
|
|
52
|
+
type SectionBreakType = 'nextPage' | 'continuous' | 'evenPage' | 'oddPage' | 'nextColumn';
|
|
53
|
+
/**
|
|
54
|
+
* Authored `w:pgNumType` (ECMA-376 CT_PageNumber).
|
|
55
|
+
*
|
|
56
|
+
* Distinguishes three states via {@link SectionProperties.pageNumbering}:
|
|
57
|
+
* - element absent → `undefined` (Word defaults; no empty element to re-emit)
|
|
58
|
+
* - empty `<w:pgNumType/>` → `{}` (present, no authored attrs; must round-trip empty)
|
|
59
|
+
* - attributes set → only those keys appear (never invent schema defaults like `fmt=decimal`)
|
|
60
|
+
*
|
|
61
|
+
* `chapStyle` / `chapSep` are preserved for consumers; PAGE projection does not yet compose
|
|
62
|
+
* chapter numbers (heading outline resolution is out of this slice).
|
|
63
|
+
*/
|
|
64
|
+
interface SectionPageNumbering {
|
|
65
|
+
/** Authored `@w:start` when present and in range; otherwise omitted. */
|
|
66
|
+
readonly start?: number;
|
|
67
|
+
/** Authored `@w:fmt` (ST_NumberFormat) when present; otherwise omitted. */
|
|
68
|
+
readonly fmt?: string;
|
|
69
|
+
/** Authored `@w:chapStyle` outline level when present and in range. */
|
|
70
|
+
readonly chapStyle?: number;
|
|
71
|
+
/** Authored `@w:chapSep` when present (hyphen / period / colon / emDash / enDash). */
|
|
72
|
+
readonly chapSep?: string;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* One section's resolved `w:sectPr`, as layout needs it.
|
|
76
|
+
*
|
|
77
|
+
* Resolved, not raw: defaults the file omitted are filled in here (an absent `w:type` is
|
|
78
|
+
* `nextPage`), so layout never has to know which attributes were authored and which were
|
|
79
|
+
* inherited.
|
|
80
|
+
*/
|
|
81
|
+
interface SectionProperties {
|
|
82
|
+
readonly pageSize: {
|
|
83
|
+
readonly widthTwips: number;
|
|
84
|
+
readonly heightTwips: number;
|
|
85
|
+
};
|
|
86
|
+
readonly margins: SectionMargins;
|
|
87
|
+
readonly columns: SectionColumns;
|
|
88
|
+
readonly landscape: boolean;
|
|
89
|
+
readonly titlePage: boolean;
|
|
90
|
+
/** Absent `w:type` defaults to `nextPage`. */
|
|
91
|
+
readonly breakType: SectionBreakType;
|
|
92
|
+
/**
|
|
93
|
+
* Authored page-number type. Absent when `w:pgNumType` is missing; empty object when the
|
|
94
|
+
* element is present with no attributes (comprehensive-fixture shape).
|
|
95
|
+
*/
|
|
96
|
+
readonly pageNumbering?: SectionPageNumbering;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* One section of the body story: contiguous top-level blocks plus the properties that end it.
|
|
100
|
+
*
|
|
101
|
+
* `blockStart` / `blockEndExclusive` index into `storyBlocks(part)`.
|
|
102
|
+
*/
|
|
103
|
+
interface DocumentSection {
|
|
104
|
+
readonly index: number;
|
|
105
|
+
readonly properties: SectionProperties;
|
|
106
|
+
readonly blockStart: number;
|
|
107
|
+
readonly blockEndExclusive: number;
|
|
108
|
+
}
|
|
109
|
+
/** US Letter, portrait, one-inch margins: Word's own default when a section says nothing. */
|
|
110
|
+
declare const DEFAULT_SECTION_PROPERTIES: SectionProperties;
|
|
111
|
+
/**
|
|
112
|
+
* Parse authored `w:pgNumType` without inventing schema defaults.
|
|
113
|
+
*
|
|
114
|
+
* Returns `undefined` when the element is absent. An empty element yields `{}` so callers
|
|
115
|
+
* can tell "present but unauthored" from "missing" and serialization can re-emit empty.
|
|
116
|
+
* Hostile / out-of-range attribute values are dropped rather than clamped into meaning.
|
|
117
|
+
*/
|
|
118
|
+
declare function parsePageNumbering(sectPr: OoxmlNode): SectionPageNumbering | undefined;
|
|
119
|
+
/** Parse one `w:sectPr` into geometry/break properties (null reads as Word's defaults). */
|
|
120
|
+
declare function parseSectionProperties(sectPr: OoxmlNode | null | undefined): SectionProperties;
|
|
121
|
+
/** `w:sectPr` nested under a paragraph's `w:pPr`, if present. */
|
|
122
|
+
declare function paragraphSectionNode(paragraph: OoxmlElement): OoxmlElement | undefined;
|
|
123
|
+
/**
|
|
124
|
+
* The section properties a part declares, or Word's defaults where it says nothing.
|
|
125
|
+
*
|
|
126
|
+
* Returns the FINAL section (body-level `w:sectPr`, else the last paragraph-level one).
|
|
127
|
+
* Multi-section geometry belongs to `enumerateDocumentSections`; chrome that needs "the
|
|
128
|
+
* document's page" still reads the last section, which is what Word's body-level sectPr is.
|
|
129
|
+
*/
|
|
130
|
+
declare function readSectionProperties(part: OoxmlPart): SectionProperties;
|
|
131
|
+
/**
|
|
132
|
+
* Split the body story into sections.
|
|
133
|
+
*
|
|
134
|
+
* A paragraph carrying `w:pPr/w:sectPr` ends the current section (that paragraph is IN the
|
|
135
|
+
* section being ended). The body-level `w:sectPr` ends the final section. A document with
|
|
136
|
+
* neither yields one section of Word defaults covering every block.
|
|
137
|
+
*
|
|
138
|
+
* Enumeration is capped at {@link MAX_DOCUMENT_SECTIONS}. Further paragraph-level section
|
|
139
|
+
* breaks are ignored and remaining blocks fold into the last accepted section (fail closed).
|
|
140
|
+
*
|
|
141
|
+
* `displayMode` MUST match the one the caller passes to `storyBlocks`. `blockStart` /
|
|
142
|
+
* `blockEndExclusive` are indices into that list, and the list changes shape with the mode:
|
|
143
|
+
* the proposed view drops a paragraph whose mark and content a revision both removed. Slicing
|
|
144
|
+
* a filtered list with indices counted over an unfiltered one puts body text under another
|
|
145
|
+
* section's page geometry — the wrong paper size, the wrong margins, the wrong header.
|
|
146
|
+
*/
|
|
147
|
+
declare function enumerateDocumentSections(part: OoxmlPart, displayMode?: RevisionDisplayMode): DocumentSection[];
|
|
148
|
+
/**
|
|
149
|
+
* Every section in a document, with a flag saying whether the list was cut short.
|
|
150
|
+
*
|
|
151
|
+
* `truncated` is reported rather than silent: section count comes from a file, so a crafted
|
|
152
|
+
* document declaring thousands of paragraph-level `w:sectPr` marks is bounded, and a reader
|
|
153
|
+
* should be able to tell that happened.
|
|
154
|
+
*/
|
|
155
|
+
interface DocumentSectionsEnumeration {
|
|
156
|
+
readonly sections: DocumentSection[];
|
|
157
|
+
/** True when paragraph-level sectPr marks beyond {@link MAX_DOCUMENT_SECTIONS} were dropped. */
|
|
158
|
+
readonly truncated: boolean;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Like {@link enumerateDocumentSections}, but reports whether the section bound clipped
|
|
162
|
+
* hostile input. Prefer the plain enumerator for normal layout; use this when a caller
|
|
163
|
+
* needs a named fail-closed diagnostic.
|
|
164
|
+
*/
|
|
165
|
+
declare function enumerateDocumentSectionsBounded(part: OoxmlPart, displayMode?: RevisionDisplayMode): DocumentSectionsEnumeration;
|
|
166
|
+
/**
|
|
167
|
+
* Section properties as the geometry layout paginates against.
|
|
168
|
+
*
|
|
169
|
+
* The gutter is added to the LEFT margin: it is binding allowance, extra space on the inner
|
|
170
|
+
* edge, and folding it into the content width instead would silently narrow every line.
|
|
171
|
+
*/
|
|
172
|
+
declare function geometryOfSection(section: SectionProperties): PageGeometry;
|
|
173
|
+
|
|
174
|
+
/** A point in the coordinate space named by the function taking it. */
|
|
175
|
+
interface HitPoint {
|
|
176
|
+
readonly x: number;
|
|
177
|
+
readonly y: number;
|
|
178
|
+
}
|
|
179
|
+
/** The innermost table cell a point resolved through. */
|
|
180
|
+
interface TableCellAddress {
|
|
181
|
+
/** Canonical node id of the `w:tbl`. */
|
|
182
|
+
readonly tableId: string;
|
|
183
|
+
/** Canonical node id of the `w:tr`. */
|
|
184
|
+
readonly rowId: string;
|
|
185
|
+
/** Canonical node id of the `w:tc`. */
|
|
186
|
+
readonly cellId: string;
|
|
187
|
+
/** Ordinal in the WHOLE table, stable across fragments and header repeats. */
|
|
188
|
+
readonly rowIndex: number;
|
|
189
|
+
readonly gridColumn: number;
|
|
190
|
+
readonly gridSpan: number;
|
|
191
|
+
}
|
|
192
|
+
/** Stable inline drawing identity when a hit resolves to a drawing atom. */
|
|
193
|
+
interface SemanticHitDrawing {
|
|
194
|
+
readonly drawingNodeId: string;
|
|
195
|
+
readonly paragraphId: string;
|
|
196
|
+
readonly start: number;
|
|
197
|
+
}
|
|
198
|
+
/** What a point landed on: a semantic position, its caret geometry, and where it sits. */
|
|
199
|
+
interface SemanticHit {
|
|
200
|
+
readonly position: SemanticPosition;
|
|
201
|
+
readonly caret: CaretGeometry;
|
|
202
|
+
readonly pageIndex: number;
|
|
203
|
+
readonly lineId: string;
|
|
204
|
+
/** Null outside a table; the innermost cell when tables nest. */
|
|
205
|
+
readonly cell: TableCellAddress | null;
|
|
206
|
+
/**
|
|
207
|
+
* True when the point was inside the resolved line's box AND inside one of its spans.
|
|
208
|
+
*
|
|
209
|
+
* A caller distinguishing a click ON text from a click BESIDE it — to decide whether to
|
|
210
|
+
* claim the gesture at all — needs this, and cannot recover it from the position.
|
|
211
|
+
*/
|
|
212
|
+
readonly onGlyphs: boolean;
|
|
213
|
+
/**
|
|
214
|
+
* Innermost content-control boundary covering the hit point, or null outside every control.
|
|
215
|
+
*
|
|
216
|
+
* Resolved from layout-published boundary geometry (not DOM). Nested controls prefer the
|
|
217
|
+
* deepest {@link ContentControlBoundaryRecord.nestingDepth}.
|
|
218
|
+
*/
|
|
219
|
+
readonly contentControlId: string | null;
|
|
220
|
+
/** Non-null when the hit resolved to an inline drawing atom. */
|
|
221
|
+
readonly drawing: SemanticHitDrawing | null;
|
|
222
|
+
}
|
|
223
|
+
/**
|
|
224
|
+
* How precisely a hit resolves within a run.
|
|
225
|
+
*
|
|
226
|
+
* Without a measurer the offset is INTERPOLATED across the span's advance, which is exact only
|
|
227
|
+
* for monospaced text — supply one for proportional fonts, or a click lands a character or two
|
|
228
|
+
* away from the glyph under the pointer.
|
|
229
|
+
*/
|
|
230
|
+
interface HitTestOptions {
|
|
231
|
+
/**
|
|
232
|
+
* Exact resolution of the character within a run.
|
|
233
|
+
*
|
|
234
|
+
* Absent, the offset is interpolated across the span's own advance, which is exact only for
|
|
235
|
+
* a uniform advance. Pass the measurer layout was produced with, or the answer can disagree
|
|
236
|
+
* with what was painted.
|
|
237
|
+
*/
|
|
238
|
+
readonly measurer?: TextMeasurer;
|
|
239
|
+
/** Vertical weight for the nearest-block rule. */
|
|
240
|
+
readonly verticalWeight?: number;
|
|
241
|
+
}
|
|
242
|
+
/**
|
|
243
|
+
* How much more a point of vertical distance counts than a point of horizontal distance.
|
|
244
|
+
*
|
|
245
|
+
* Without it, clicking far out in the right margin beside a two-word line picks whichever
|
|
246
|
+
* block happens to be directly below, because that block is horizontally nearer. Weighting
|
|
247
|
+
* the vertical axis makes "the line I am level with" win, which is what the pointer meant.
|
|
248
|
+
*/
|
|
249
|
+
declare const DEFAULT_VERTICAL_WEIGHT = 8;
|
|
250
|
+
/**
|
|
251
|
+
* The page a sheet-space y belongs to.
|
|
252
|
+
*
|
|
253
|
+
* The gutter between page *i* and page *i+1* resolves to page *i*, because the nearest text
|
|
254
|
+
* to a point in that gap is the last line of the page above it. That falls out of searching
|
|
255
|
+
* for the last page whose top is at or above the point, with no special case: the gutter is
|
|
256
|
+
* inside `[top(i), top(i+1))` by construction. A point above the first page clamps to it, and
|
|
257
|
+
* a point past the last page clamps to that.
|
|
258
|
+
*/
|
|
259
|
+
declare function pageAtY(layout: SemanticLayout, sheetY: number): number;
|
|
260
|
+
/** True when a sheet-space point falls inside a page's header or footer box. */
|
|
261
|
+
declare function isFurniturePoint(layout: SemanticLayout, point: HitPoint): boolean;
|
|
262
|
+
/** Hit test a point given in PAGE-CONTENT coordinates, the space the fragment boxes use. */
|
|
263
|
+
declare function hitTestPage(layout: SemanticLayout, pageIndex: number, point: HitPoint, options?: HitTestOptions): SemanticHit | null;
|
|
264
|
+
/**
|
|
265
|
+
* Hit test a point given in SHEET coordinates — the space `page.box` lives in, and the space
|
|
266
|
+
* a surface's own pixel offsets convert into.
|
|
267
|
+
*/
|
|
268
|
+
declare function hitTestSheet(layout: SemanticLayout, point: HitPoint, options?: HitTestOptions): SemanticHit | null;
|
|
269
|
+
/**
|
|
270
|
+
* Innermost content control whose published boundary geometry contains `point` on `pageIndex`.
|
|
271
|
+
*
|
|
272
|
+
* Nested controls that share the same content box resolve to the deepest nesting depth.
|
|
273
|
+
*/
|
|
274
|
+
declare function contentControlAtPoint(layout: SemanticLayout, pageIndex: number, point: HitPoint): ContentControlBoundaryRecord | null;
|
|
275
|
+
/**
|
|
276
|
+
* The end position of a line, as Word places it.
|
|
277
|
+
*
|
|
278
|
+
* On a SOFT-WRAPPED line the space that caused the break is painted at the end of the line
|
|
279
|
+
* but the caret belongs before it — otherwise clicking in the right margin puts the caret
|
|
280
|
+
* visually at the start of the NEXT line, which reads as the click having missed. The last
|
|
281
|
+
* line of a paragraph has no such space to discount.
|
|
282
|
+
*
|
|
283
|
+
* A HARD BREAK is the same story with a character that is always there: the position after
|
|
284
|
+
* it belongs to the line the break opened (`caretAt` places it there), so a click in the
|
|
285
|
+
* right margin of the line the break ENDED has to stop in front of it or the caret appears
|
|
286
|
+
* a row below the click.
|
|
287
|
+
*
|
|
288
|
+
* A PAGE break is discounted even on the paragraph's LAST line, which is the one case the
|
|
289
|
+
* last-line shortcut got wrong. The position after such a break is on the next page — and
|
|
290
|
+
* when the remainder is empty it has no line anywhere, because Word Online starts the
|
|
291
|
+
* following block flush at the top of that page. So the caret for it stays behind on the
|
|
292
|
+
* line the break ended, and a click in the wide blank space beside the mark resolved to a
|
|
293
|
+
* position a page away from where it landed: the caret appeared under the pointer and the
|
|
294
|
+
* typing came out on the next page. `<w:p><w:r><w:br w:type="page"/></w:r></w:p>` is the
|
|
295
|
+
* commonest way to end a page, so that blank space is most of a page wide.
|
|
296
|
+
*/
|
|
297
|
+
declare function lineEndOffset(layout: SemanticLayout, line: LineRecord): number;
|
|
298
|
+
/**
|
|
299
|
+
* The x of a model offset inside a span — the inverse of {@link offsetWithinSpan}.
|
|
300
|
+
*
|
|
301
|
+
* Shares the measurement, and the cache, with the hit test. Interpolating across the span's
|
|
302
|
+
* advance instead is exact only for a uniform one: in a proportional face the caret for
|
|
303
|
+
* offset 4 of an 8-character span is drawn at half its width, which lands in the middle of a
|
|
304
|
+
* glyph rather than between two.
|
|
305
|
+
*/
|
|
306
|
+
declare function spanOffsetX(span: StyleSpanRecord, offset: number, measurer: TextMeasurer | undefined): number;
|
|
307
|
+
/**
|
|
308
|
+
* Where a caret sits on a line: its x, and the box it should be drawn at.
|
|
309
|
+
*
|
|
310
|
+
* The height comes from the RUN at the insertion point, not from the line. A line is as tall
|
|
311
|
+
* as its largest run, so a caret in 11pt text on a line that also carries 36pt text was drawn
|
|
312
|
+
* three times the height of the text it sits in. Word sizes the insertion point to the run it
|
|
313
|
+
* would type into, which is also how the painter already draws the selection band: every run
|
|
314
|
+
* is its own inline box, and the band steps with the text.
|
|
315
|
+
*
|
|
316
|
+
* Affinity at a shared model boundary:
|
|
317
|
+
* - after a layout-sized atom (tab / projected field), prefer the DOWNSTREAM span so the
|
|
318
|
+
* caret sits at the aligned destination (e.g. before CONFIDENTIAL after a right tab),
|
|
319
|
+
* matching hit-testing and caretStops;
|
|
320
|
+
* - otherwise the run BEFORE the offset wins — the run a keystroke would continue —
|
|
321
|
+
* except at the start of the line, where there is nothing before it.
|
|
322
|
+
*/
|
|
323
|
+
declare function caretBoxOnLine(line: LineRecord, offset: number, measurer: TextMeasurer | undefined): {
|
|
324
|
+
x: number;
|
|
325
|
+
y: number;
|
|
326
|
+
height: number;
|
|
327
|
+
};
|
|
328
|
+
/** Page-content overlay rectangle for a drawing's painted extent. */
|
|
329
|
+
interface DrawingOverlayFrame {
|
|
330
|
+
readonly pageIndex: number;
|
|
331
|
+
/** Relative to {@link PageRecord.contentBox}. */
|
|
332
|
+
readonly x: number;
|
|
333
|
+
readonly y: number;
|
|
334
|
+
readonly width: number;
|
|
335
|
+
readonly height: number;
|
|
336
|
+
readonly record: InlineDrawingRecord | AnchoredDrawingRecord;
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* Locate a drawing's painted extent on the published layout.
|
|
340
|
+
*
|
|
341
|
+
* Coordinates are page-content relative — the same space {@link hitTestPage} uses — so an
|
|
342
|
+
* overlay can position from records without reading painted DOM geometry.
|
|
343
|
+
*/
|
|
344
|
+
declare function findDrawingOverlayFrameInLayout(layout: SemanticLayout, drawingNodeId: string): DrawingOverlayFrame | null;
|
|
345
|
+
|
|
346
|
+
/** A rectangle of table cells. */
|
|
347
|
+
interface CellSelection {
|
|
348
|
+
readonly kind: 'cells';
|
|
349
|
+
/** Canonical node id of the `w:tbl`. */
|
|
350
|
+
readonly tableId: string;
|
|
351
|
+
/** Every selected `w:tc`, in document order, with merges resolved. */
|
|
352
|
+
readonly cellIds: readonly string[];
|
|
353
|
+
/** Inclusive row ordinals within the table. */
|
|
354
|
+
readonly rows: {
|
|
355
|
+
readonly from: number;
|
|
356
|
+
readonly to: number;
|
|
357
|
+
};
|
|
358
|
+
/** Inclusive grid columns. */
|
|
359
|
+
readonly columns: {
|
|
360
|
+
readonly from: number;
|
|
361
|
+
readonly to: number;
|
|
362
|
+
};
|
|
363
|
+
/**
|
|
364
|
+
* The equivalent text range.
|
|
365
|
+
*
|
|
366
|
+
* Every existing reader of a selection — deletion, the clipboard, the DOM mirror, viewport
|
|
367
|
+
* pinning — takes this and needs no knowledge that a rectangle produced it.
|
|
368
|
+
*/
|
|
369
|
+
readonly text: SemanticSelection;
|
|
370
|
+
}
|
|
371
|
+
/** One painted occurrence of a cell, and where it sits. */
|
|
372
|
+
interface PlacedCell {
|
|
373
|
+
readonly pageIndex: number;
|
|
374
|
+
readonly tableId: string;
|
|
375
|
+
readonly row: TableRowFragmentRecord;
|
|
376
|
+
readonly cell: TableCellFragmentRecord;
|
|
377
|
+
/** Ordinal within the whole table, shared by a header row and every repeat of it. */
|
|
378
|
+
readonly rowIndex: number;
|
|
379
|
+
readonly isHeaderRepeat: boolean;
|
|
380
|
+
}
|
|
381
|
+
/**
|
|
382
|
+
* The rectangle two cells define.
|
|
383
|
+
*
|
|
384
|
+
* Grown to a fixpoint rather than taken literally: a cell that spans two columns cannot be
|
|
385
|
+
* half selected, and a vertically merged run cannot be selected in the middle. Word grows the
|
|
386
|
+
* rectangle until every cell it touches is wholly inside it, so dragging into a merged cell
|
|
387
|
+
* pulls the selection out to that cell's full extent.
|
|
388
|
+
*/
|
|
389
|
+
declare function cellSelectionBetween(layout: SemanticLayout, anchor: TableCellAddress, head: TableCellAddress): CellSelection | null;
|
|
390
|
+
/** Paragraph ids inside a set of cells, in document order, each once. */
|
|
391
|
+
declare function paragraphsInCells(layout: SemanticLayout, cellIds: readonly string[]): readonly string[];
|
|
392
|
+
/** The style spans a cell selection covers, for reporting active formatting. */
|
|
393
|
+
declare function spansInCells(layout: SemanticLayout, cellIds: readonly string[]): readonly StyleSpanRecord[];
|
|
394
|
+
/** One rectangle per painted occurrence of a selected cell, in page-content coordinates. */
|
|
395
|
+
declare function cellSelectionRects(layout: SemanticLayout, cellIds: readonly string[]): readonly {
|
|
396
|
+
pageIndex: number;
|
|
397
|
+
x: number;
|
|
398
|
+
y: number;
|
|
399
|
+
width: number;
|
|
400
|
+
height: number;
|
|
401
|
+
}[];
|
|
402
|
+
/**
|
|
403
|
+
* A cell selection as plain text: tabs between cells, newlines between rows.
|
|
404
|
+
*
|
|
405
|
+
* What a spreadsheet and every other word processor put on the clipboard for a rectangle, and
|
|
406
|
+
* the only shape that survives the trip: the text range a rectangle stands in for would paste
|
|
407
|
+
* back as one run of characters with the grid gone.
|
|
408
|
+
*/
|
|
409
|
+
declare function cellSelectionText(layout: SemanticLayout, selection: CellSelection): string;
|
|
410
|
+
/** Where a paragraph sits in a table, if it sits in one. */
|
|
411
|
+
interface TableCellContext {
|
|
412
|
+
readonly tableId: string;
|
|
413
|
+
readonly rows: number;
|
|
414
|
+
readonly columns: number;
|
|
415
|
+
readonly rowIndex: number;
|
|
416
|
+
readonly columnIndex: number;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* The table context of one paragraph — what a toolbar reflects when the caret is in a cell.
|
|
420
|
+
*
|
|
421
|
+
* Answers for a plain caret, not only for a cell selection, because "am I in a table" is a
|
|
422
|
+
* question about where the caret is and a toolbar that only knew during a rectangle drag
|
|
423
|
+
* would show its table controls disabled while the user was typing in a cell.
|
|
424
|
+
*/
|
|
425
|
+
declare function tableContextAt(layout: SemanticLayout, paragraphId: string): TableCellContext | null;
|
|
426
|
+
|
|
427
|
+
export { pageAtY as A, paragraphSectionNode as B, type CellSelection as C, DEFAULT_SECTION_PROPERTIES as D, paragraphsInCells as E, parsePageNumbering as F, parseSectionProperties as G, type HitPoint as H, readSectionProperties as I, spanOffsetX as J, spansInCells as K, tableContextAt as L, MAX_DOCUMENT_SECTIONS as M, type PlacedCell as P, type SectionProperties as S, type TableCellAddress as T, type SectionColumns as a, DEFAULT_VERTICAL_WEIGHT as b, type DocumentSection as c, type DocumentSectionsEnumeration as d, type DrawingOverlayFrame as e, type HitTestOptions as f, type SectionBreakType as g, type SectionColumnDefinition as h, type SectionMargins as i, type SectionPageNumbering as j, type SemanticHit as k, type SemanticHitDrawing as l, type TableCellContext as m, caretBoxOnLine as n, cellSelectionBetween as o, cellSelectionRects as p, cellSelectionText as q, contentControlAtPoint as r, enumerateDocumentSections as s, enumerateDocumentSectionsBounded as t, findDrawingOverlayFrameInLayout as u, geometryOfSection as v, hitTestPage as w, hitTestSheet as x, isFurniturePoint as y, lineEndOffset as z };
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { T as TextMeasurer, S as SemanticLayout, B as BlockFragmentRecord, C as ContentControlBoundaryRecord, a as StyleSpanRecord } from './semantic-records-CJR3BvHs.cjs';
|
|
2
|
+
|
|
3
|
+
/** A caret position in the model. */
|
|
4
|
+
interface SemanticPosition {
|
|
5
|
+
readonly paragraphId: string;
|
|
6
|
+
readonly offset: number;
|
|
7
|
+
}
|
|
8
|
+
/** A caret position with the geometry that renders it. */
|
|
9
|
+
interface CaretGeometry {
|
|
10
|
+
readonly position: SemanticPosition;
|
|
11
|
+
/** Page-relative, in the same coordinate space as the line boxes. */
|
|
12
|
+
readonly x: number;
|
|
13
|
+
readonly y: number;
|
|
14
|
+
readonly height: number;
|
|
15
|
+
readonly lineId: string;
|
|
16
|
+
readonly pageIndex: number;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* A selection as two semantic positions — never as DOM nodes.
|
|
20
|
+
*
|
|
21
|
+
* `anchor` is where the selection started and `head` is where it currently ends, so `head` before
|
|
22
|
+
* `anchor` is an ordinary backwards selection rather than an error. Collapsed when the two are
|
|
23
|
+
* equal, which is what a caret is.
|
|
24
|
+
*/
|
|
25
|
+
interface SemanticSelection {
|
|
26
|
+
readonly anchor: SemanticPosition;
|
|
27
|
+
readonly head: SemanticPosition;
|
|
28
|
+
}
|
|
29
|
+
/** One painted selection rectangle, in page-relative layout points. */
|
|
30
|
+
interface SelectionRect {
|
|
31
|
+
readonly pageIndex: number;
|
|
32
|
+
readonly x: number;
|
|
33
|
+
readonly y: number;
|
|
34
|
+
readonly width: number;
|
|
35
|
+
readonly height: number;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Every caret stop in the document body, in reading order.
|
|
39
|
+
*
|
|
40
|
+
* One per character boundary on every line, plus the line end. Derived rather than stored,
|
|
41
|
+
* so a stop can never survive the content it described. Ownership of a position SHARED by
|
|
42
|
+
* two lines is decided here exactly as `caretAt` decides it. Furniture stories use
|
|
43
|
+
* {@link caretStopsForBlocks} so open header/footer navigation never walks body stops.
|
|
44
|
+
*/
|
|
45
|
+
declare function caretStops(layout: SemanticLayout, measurer?: TextMeasurer): CaretGeometry[];
|
|
46
|
+
/**
|
|
47
|
+
* Caret stops for one story's block fragments (header/footer), in reading order.
|
|
48
|
+
*
|
|
49
|
+
* Coordinates stay story-relative — the same space `hitTestFragments` and furniture paint
|
|
50
|
+
* use — so arrow motion follows tab-stop geometry and projected field atoms without mixing
|
|
51
|
+
* body sheet offsets.
|
|
52
|
+
*/
|
|
53
|
+
declare function caretStopsForBlocks(layout: SemanticLayout, pageIndex: number, fragments: readonly BlockFragmentRecord[], measurer?: TextMeasurer): CaretGeometry[];
|
|
54
|
+
/**
|
|
55
|
+
* How caret geometry is resolved.
|
|
56
|
+
*
|
|
57
|
+
* `preferPage` disambiguates a paragraph that paints on SEVERAL pages — a shared header appears
|
|
58
|
+
* once per page, and without a preference the caret could be placed on any of its copies.
|
|
59
|
+
*/
|
|
60
|
+
interface CaretAtOptions {
|
|
61
|
+
readonly measurer?: TextMeasurer;
|
|
62
|
+
/**
|
|
63
|
+
* Prefer geometry from this sheet when the same paragraph paints on multiple pages
|
|
64
|
+
* (shared header/footer copies).
|
|
65
|
+
*/
|
|
66
|
+
readonly preferredPageIndex?: number;
|
|
67
|
+
}
|
|
68
|
+
/** Geometry for one model position, or null when it is not laid out. */
|
|
69
|
+
declare function caretAt(layout: SemanticLayout, position: SemanticPosition, measurerOrOptions?: TextMeasurer | CaretAtOptions): CaretGeometry | null;
|
|
70
|
+
/**
|
|
71
|
+
* The caret position nearest a point, in PAGE-CONTENT coordinates.
|
|
72
|
+
*
|
|
73
|
+
* Never returns null for a point inside the document: a click in the margin, past the end of
|
|
74
|
+
* a line, or below the last line still has an obvious intended caret, and refusing to answer
|
|
75
|
+
* would make those clicks do nothing.
|
|
76
|
+
*
|
|
77
|
+
* The rules live in `semantic-hit-test.ts`, which answers with the cell address and the
|
|
78
|
+
* on-glyphs flag a pointer controller needs too; this keeps the geometry-only shape for
|
|
79
|
+
* callers that want nothing else.
|
|
80
|
+
*/
|
|
81
|
+
declare function hitTestSemantic(layout: SemanticLayout, point: {
|
|
82
|
+
readonly x: number;
|
|
83
|
+
readonly y: number;
|
|
84
|
+
readonly pageIndex?: number;
|
|
85
|
+
}): CaretGeometry | null;
|
|
86
|
+
/**
|
|
87
|
+
* Innermost content-control boundary at a page-content point, or null outside every control.
|
|
88
|
+
*
|
|
89
|
+
* Prefers the deepest nesting depth when nested boundaries share geometry.
|
|
90
|
+
*/
|
|
91
|
+
declare function contentControlAtSemantic(layout: SemanticLayout, point: {
|
|
92
|
+
readonly x: number;
|
|
93
|
+
readonly y: number;
|
|
94
|
+
readonly pageIndex?: number;
|
|
95
|
+
}): ContentControlBoundaryRecord | null;
|
|
96
|
+
/** Layout-published content-control boundaries in document order. */
|
|
97
|
+
declare function contentControlsInLayout(layout: SemanticLayout): readonly ContentControlBoundaryRecord[];
|
|
98
|
+
/** The rectangles covering a selection, one per line it spans. */
|
|
99
|
+
declare function selectionRects(layout: SemanticLayout, selection: SemanticSelection): SelectionRect[];
|
|
100
|
+
/** A model range to highlight, and the key the caller knows it by. */
|
|
101
|
+
interface KeyedRange {
|
|
102
|
+
readonly key: string;
|
|
103
|
+
readonly from: SemanticPosition;
|
|
104
|
+
readonly to: SemanticPosition;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Rectangles for MANY ranges in ONE pass over the lines.
|
|
108
|
+
*
|
|
109
|
+
* Not `selectionRects` in a loop. That walks every page, fragment and line per range, and a
|
|
110
|
+
* contract with two hundred comments would re-walk the whole document two hundred times on
|
|
111
|
+
* every layout — the highlight would cost more than the layout it decorates. One pass tests
|
|
112
|
+
* each line against every range instead, which is the same work a single selection does.
|
|
113
|
+
*/
|
|
114
|
+
declare function keyedRangeRects(layout: SemanticLayout, ranges: readonly KeyedRange[],
|
|
115
|
+
/**
|
|
116
|
+
* Pages to measure, or every page when absent.
|
|
117
|
+
*
|
|
118
|
+
* A band that is not on screen is not painted, so measuring it is pure cost — and it is
|
|
119
|
+
* cost paid per keystroke, because an edit republishes the layout. Bounding this to the
|
|
120
|
+
* materialized pages is what keeps typing in a heavily reviewed document as fast as
|
|
121
|
+
* typing in a clean one.
|
|
122
|
+
*/
|
|
123
|
+
pages?: ReadonlySet<number>): Map<string, SelectionRect[]>;
|
|
124
|
+
/** Paragraph ids in document order, deduplicated across fragments. */
|
|
125
|
+
declare function documentOrder(layout: SemanticLayout): string[];
|
|
126
|
+
/**
|
|
127
|
+
* One caret movement, in Word's own vocabulary.
|
|
128
|
+
*
|
|
129
|
+
* Visual rather than logical where the two differ: `left` means left on screen, which in
|
|
130
|
+
* right-to-left text is forward through the string.
|
|
131
|
+
*/
|
|
132
|
+
type NavigationCommand = 'left' | 'right' | 'up' | 'down' | 'wordLeft' | 'wordRight' | 'lineStart' | 'lineEnd' | 'documentStart' | 'documentEnd' | 'pageUp' | 'pageDown';
|
|
133
|
+
/**
|
|
134
|
+
* The text of one paragraph, read back from the layout records.
|
|
135
|
+
*
|
|
136
|
+
* Word boundaries need characters, and the records carry them: every span holds the text it
|
|
137
|
+
* was laid out from, keyed by the source range it covers. Reading them back keeps word
|
|
138
|
+
* motion in the interaction lane instead of making it a second consumer of the model.
|
|
139
|
+
*/
|
|
140
|
+
declare function paragraphTextFromLayout(layout: SemanticLayout, paragraphId: string): string;
|
|
141
|
+
/**
|
|
142
|
+
* The next word boundary from `offset`, in `direction`.
|
|
143
|
+
*
|
|
144
|
+
* Word-LEFT skips any whitespace immediately behind the caret and then the word behind that,
|
|
145
|
+
* which is what every editor does and what makes repeated presses walk words rather than
|
|
146
|
+
* alternate between a word and the space before it. Word-RIGHT stops at the END of the
|
|
147
|
+
* current word, then skips the following whitespace on the next press.
|
|
148
|
+
*/
|
|
149
|
+
declare function wordBoundary(text: string, offset: number, direction: -1 | 1): number;
|
|
150
|
+
/**
|
|
151
|
+
* How a caret move resolves.
|
|
152
|
+
*
|
|
153
|
+
* Story-scoped stops are REQUIRED when navigating inside an open header or footer: the body's
|
|
154
|
+
* stops describe a different story, and moving through them would walk the caret out of the
|
|
155
|
+
* furniture the user is editing.
|
|
156
|
+
*/
|
|
157
|
+
interface MoveCaretOptions {
|
|
158
|
+
/**
|
|
159
|
+
* Precomputed stops for the active story. Open header/footer navigation MUST pass
|
|
160
|
+
* story-scoped stops from {@link caretStopsForBlocks}; body keeps the default.
|
|
161
|
+
*/
|
|
162
|
+
readonly stops?: readonly CaretGeometry[];
|
|
163
|
+
readonly measurer?: TextMeasurer;
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Move a caret.
|
|
167
|
+
*
|
|
168
|
+
* Vertical movement keeps a DESIRED X so a caret travelling through short lines returns to
|
|
169
|
+
* its original column rather than collapsing to the end of the shortest one. The caller
|
|
170
|
+
* threads that value; passing null starts a fresh vertical run from the current position.
|
|
171
|
+
*/
|
|
172
|
+
declare function moveCaret(layout: SemanticLayout, position: SemanticPosition, command: NavigationCommand, desiredX?: number | null, options?: MoveCaretOptions): {
|
|
173
|
+
position: SemanticPosition;
|
|
174
|
+
desiredX: number | null;
|
|
175
|
+
} | null;
|
|
176
|
+
/**
|
|
177
|
+
* The anchor an IME composition is attached to.
|
|
178
|
+
*
|
|
179
|
+
* Composition needs a position that survives the intermediate transactions it produces, so
|
|
180
|
+
* it is expressed in model coordinates and re-resolved against each new layout rather than
|
|
181
|
+
* cached as geometry.
|
|
182
|
+
*/
|
|
183
|
+
declare function compositionAnchor(layout: SemanticLayout, position: SemanticPosition): CaretGeometry | null;
|
|
184
|
+
/** The style spans a selection touches, for reporting active formatting. */
|
|
185
|
+
declare function spansInSelection(layout: SemanticLayout, selection: SemanticSelection): StyleSpanRecord[];
|
|
186
|
+
|
|
187
|
+
export { type CaretGeometry as C, type KeyedRange as K, type MoveCaretOptions as M, type NavigationCommand as N, type SemanticPosition as S, type SemanticSelection as a, type CaretAtOptions as b, type SelectionRect as c, caretAt as d, caretStops as e, caretStopsForBlocks as f, compositionAnchor as g, contentControlAtSemantic as h, contentControlsInLayout as i, documentOrder as j, hitTestSemantic as k, keyedRangeRects as l, moveCaret as m, spansInSelection as n, paragraphTextFromLayout as p, selectionRects as s, wordBoundary as w };
|