@stll/folio-core 0.15.12 → 0.15.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-edits/apply.js +67 -2
- package/dist/layout-bridge/convert/toFlowBlocks.js +5 -5
- package/dist/layout-bridge/dom/clickToPositionDom.d.ts +12 -2
- package/dist/layout-bridge/dom/clickToPositionDom.js +39 -14
- package/dist/layout-bridge/headerFooterLayout.js +1 -1
- package/dist/layout-painter/renderParagraph.js +4 -1
- package/dist/render-dom/RenderedDomContext.js +9 -8
- package/package.json +1 -1
package/dist/ai-edits/apply.js
CHANGED
|
@@ -42,6 +42,10 @@ const applyReplaceBlockStyleId = ({ item, tr }) => {
|
|
|
42
42
|
styleId: item.operation.styleId
|
|
43
43
|
});
|
|
44
44
|
};
|
|
45
|
+
const REPLACEMENT_BACKGROUND_CLEAR_FORMATTING = {
|
|
46
|
+
highlight: false,
|
|
47
|
+
runShading: false
|
|
48
|
+
};
|
|
45
49
|
const applyInlineFormatting = ({ tr, schema, from, to, formatting }) => {
|
|
46
50
|
for (const [name, enabled] of Object.entries(formatting)) {
|
|
47
51
|
const markType = schema.marks[name];
|
|
@@ -60,6 +64,29 @@ const formattingWouldChange = (marks, formatting) => Object.entries(formatting).
|
|
|
60
64
|
if (name === "underline") return mark?.attrs["style"] !== "single";
|
|
61
65
|
return mark === void 0;
|
|
62
66
|
});
|
|
67
|
+
const clearReplacementBackground = ({ tr, schema, from, to, mode, revisionId, author, date, initials, suggestionId = null }) => {
|
|
68
|
+
if (![schema.marks["highlight"], schema.marks["runShading"]].some((markType) => markType !== void 0 && tr.doc.rangeHasMark(from, to, markType))) return tr;
|
|
69
|
+
if (mode === "direct") return applyInlineFormatting({
|
|
70
|
+
tr,
|
|
71
|
+
schema,
|
|
72
|
+
from,
|
|
73
|
+
to,
|
|
74
|
+
formatting: REPLACEMENT_BACKGROUND_CLEAR_FORMATTING
|
|
75
|
+
});
|
|
76
|
+
return applyTrackedInlineFormatting({
|
|
77
|
+
tr,
|
|
78
|
+
schema,
|
|
79
|
+
doc: tr.doc,
|
|
80
|
+
from,
|
|
81
|
+
to,
|
|
82
|
+
formatting: REPLACEMENT_BACKGROUND_CLEAR_FORMATTING,
|
|
83
|
+
revisionId,
|
|
84
|
+
author,
|
|
85
|
+
date,
|
|
86
|
+
initials,
|
|
87
|
+
suggestionId
|
|
88
|
+
});
|
|
89
|
+
};
|
|
63
90
|
const applyTrackedInlineFormatting = ({ tr, schema, doc, from, to, formatting, revisionId, author, date, initials, suggestionId = null }) => {
|
|
64
91
|
const propertyChangeType = schema.marks["runPropertyChange"];
|
|
65
92
|
if (!propertyChangeType) return tr;
|
|
@@ -418,6 +445,21 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations, mode =
|
|
|
418
445
|
case "replaceRange": {
|
|
419
446
|
const revisionIdDelete = revisionSeed++;
|
|
420
447
|
const revisionIdInsert = revisionSeed++;
|
|
448
|
+
const revisionIdBackground = revisionSeed++;
|
|
449
|
+
const stepsBeforeBackgroundClear = tr.steps.length;
|
|
450
|
+
tr = clearReplacementBackground({
|
|
451
|
+
tr,
|
|
452
|
+
schema: view.state.schema,
|
|
453
|
+
from: item.from,
|
|
454
|
+
to: item.to,
|
|
455
|
+
mode,
|
|
456
|
+
revisionId: revisionIdBackground,
|
|
457
|
+
author,
|
|
458
|
+
date,
|
|
459
|
+
initials,
|
|
460
|
+
suggestionId
|
|
461
|
+
});
|
|
462
|
+
const clearedBackground = tr.steps.length > stepsBeforeBackgroundClear;
|
|
421
463
|
tr = applyTextReplacement({
|
|
422
464
|
tr,
|
|
423
465
|
item,
|
|
@@ -430,7 +472,11 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations, mode =
|
|
|
430
472
|
suggestionId,
|
|
431
473
|
initials
|
|
432
474
|
});
|
|
433
|
-
if (producesTrackedChanges) appliedRevisionIds = [
|
|
475
|
+
if (producesTrackedChanges) appliedRevisionIds = [
|
|
476
|
+
revisionIdDelete,
|
|
477
|
+
revisionIdInsert,
|
|
478
|
+
...clearedBackground ? [revisionIdBackground] : []
|
|
479
|
+
];
|
|
434
480
|
break;
|
|
435
481
|
}
|
|
436
482
|
case "commentOnRange":
|
|
@@ -466,6 +512,7 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations, mode =
|
|
|
466
512
|
case "replaceBlock": {
|
|
467
513
|
const revisionIdDelete = revisionSeed++;
|
|
468
514
|
const revisionIdInsert = revisionSeed++;
|
|
515
|
+
const revisionIdBackground = revisionSeed++;
|
|
469
516
|
if (item.operation.preserveFormatting === false && mode === "direct") {
|
|
470
517
|
const replacement = item.operation.text;
|
|
471
518
|
const paragraphType = view.state.schema.nodes["paragraph"];
|
|
@@ -485,6 +532,20 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations, mode =
|
|
|
485
532
|
tr = tr.replaceWith(item.blockFrom, item.blockTo, node);
|
|
486
533
|
break;
|
|
487
534
|
}
|
|
535
|
+
const stepsBeforeBackgroundClear = tr.steps.length;
|
|
536
|
+
tr = clearReplacementBackground({
|
|
537
|
+
tr,
|
|
538
|
+
schema: view.state.schema,
|
|
539
|
+
from: item.from,
|
|
540
|
+
to: item.to,
|
|
541
|
+
mode,
|
|
542
|
+
revisionId: revisionIdBackground,
|
|
543
|
+
author,
|
|
544
|
+
date,
|
|
545
|
+
initials,
|
|
546
|
+
suggestionId
|
|
547
|
+
});
|
|
548
|
+
const clearedBackground = tr.steps.length > stepsBeforeBackgroundClear;
|
|
488
549
|
tr = applyTextReplacement({
|
|
489
550
|
tr,
|
|
490
551
|
item,
|
|
@@ -501,7 +562,11 @@ const applyFolioAIEditOperationsInternal = ({ view, snapshot, operations, mode =
|
|
|
501
562
|
item,
|
|
502
563
|
tr
|
|
503
564
|
});
|
|
504
|
-
if (producesTrackedChanges) appliedRevisionIds = [
|
|
565
|
+
if (producesTrackedChanges) appliedRevisionIds = [
|
|
566
|
+
revisionIdDelete,
|
|
567
|
+
revisionIdInsert,
|
|
568
|
+
...clearedBackground ? [revisionIdBackground] : []
|
|
569
|
+
];
|
|
505
570
|
break;
|
|
506
571
|
}
|
|
507
572
|
case "insertAfterBlock":
|
|
@@ -69,7 +69,7 @@ function formatNumberedMarker(counters, level) {
|
|
|
69
69
|
const parts = [];
|
|
70
70
|
for (let i = 0; i <= level; i += 1) {
|
|
71
71
|
const value = counters[i] ?? 0;
|
|
72
|
-
if (value <= 0) break;
|
|
72
|
+
if (!Number.isFinite(value) || value <= 0) break;
|
|
73
73
|
parts.push(value);
|
|
74
74
|
}
|
|
75
75
|
if (parts.length === 0) return "1.";
|
|
@@ -156,23 +156,23 @@ function computeListMarker(pmAttrs, listCounters, abstractCounters, seenNumIds)
|
|
|
156
156
|
const abstractNumId = pmAttrs.listAbstractNumId;
|
|
157
157
|
if (level > 0) {
|
|
158
158
|
const latestAbstractCounters = abstractNumId === void 0 ? void 0 : abstractCounters.get(abstractNumId);
|
|
159
|
-
if (counters.slice(0, level).every(Number.
|
|
159
|
+
if (counters.slice(0, level).every((counter) => !Number.isFinite(counter))) for (let i = 0; i < level; i += 1) {
|
|
160
160
|
const latestCounter = latestAbstractCounters?.[i];
|
|
161
|
-
counters[i] = latestCounter !== void 0 &&
|
|
161
|
+
counters[i] = latestCounter !== void 0 && Number.isFinite(latestCounter) ? latestCounter : pmAttrs.listLevelStarts?.[i] ?? 1;
|
|
162
162
|
}
|
|
163
163
|
}
|
|
164
164
|
const seenKey = `${numId}:${level}`;
|
|
165
165
|
if (!seenNumIds.has(seenKey)) {
|
|
166
166
|
seenNumIds.add(seenKey);
|
|
167
167
|
if (pmAttrs.listStartOverride != null) counters[level] = pmAttrs.listStartOverride - 1;
|
|
168
|
-
else if (Number.isNaN(counters[level])) counters[level] = (pmAttrs.listLevelStarts?.[level] ?? 1) - 1;
|
|
169
168
|
}
|
|
169
|
+
if (!Number.isFinite(counters[level])) counters[level] = (pmAttrs.listLevelStarts?.[level] ?? 1) - 1;
|
|
170
170
|
counters[level] = (counters[level] ?? 0) + 1;
|
|
171
171
|
for (let i = level + 1; i < counters.length; i += 1) counters[i] = NaN;
|
|
172
172
|
const childAdvances = pmAttrs.listImplicitChildLevelAdvances ?? 0;
|
|
173
173
|
if (childAdvances > 0 && level + 1 < counters.length) {
|
|
174
174
|
const childCounter = counters[level + 1];
|
|
175
|
-
counters[level + 1] = (childCounter === void 0 || Number.
|
|
175
|
+
counters[level + 1] = (childCounter === void 0 || !Number.isFinite(childCounter) ? 0 : childCounter) + childAdvances;
|
|
176
176
|
}
|
|
177
177
|
listCounters.set(numId, counters);
|
|
178
178
|
if (abstractNumId !== void 0) abstractCounters.set(abstractNumId, [...counters]);
|
|
@@ -75,7 +75,17 @@ type CollapsedLineEdgeCaretGeometry = {
|
|
|
75
75
|
* below the line until visible text is typed. Anchor the caret to the nearest
|
|
76
76
|
* painted sibling instead; an all-whitespace line falls back to its line box.
|
|
77
77
|
*/
|
|
78
|
-
declare function getCollapsedLineEdgeCaretGeometry(spanEl: HTMLElement): CollapsedLineEdgeCaretGeometry | null;
|
|
78
|
+
declare function getCollapsedLineEdgeCaretGeometry(spanEl: HTMLElement, pmPos?: number): CollapsedLineEdgeCaretGeometry | null;
|
|
79
|
+
type CollapsedLineEdgeCaretTarget = {
|
|
80
|
+
span: HTMLElement;
|
|
81
|
+
geometry: CollapsedLineEdgeCaretGeometry;
|
|
82
|
+
};
|
|
83
|
+
/**
|
|
84
|
+
* Prefer a collapsed line-edge span when multiple painted spans share the PM
|
|
85
|
+
* position. Generic text runs use inclusive endpoints, so DOM order alone
|
|
86
|
+
* cannot decide which span owns a boundary.
|
|
87
|
+
*/
|
|
88
|
+
declare function findCollapsedLineEdgeCaretTarget(spans: readonly HTMLElement[], pmPos: number): CollapsedLineEdgeCaretTarget | null;
|
|
79
89
|
declare function getCaretPositionFromDom(container: HTMLElement, pmPos: number, overlayRect: DOMRect): DomCaretPosition | null;
|
|
80
90
|
//#endregion
|
|
81
|
-
export { CollapsedLineEdgeCaretGeometry, DomCaretPosition, DomSelectionRect, clickToPositionDom, findPositionInSpan, getCaretPositionFromDom, getCollapsedLineEdgeCaretGeometry, getSelectionRectsFromDom };
|
|
91
|
+
export { CollapsedLineEdgeCaretGeometry, CollapsedLineEdgeCaretTarget, DomCaretPosition, DomSelectionRect, clickToPositionDom, findCollapsedLineEdgeCaretTarget, findPositionInSpan, getCaretPositionFromDom, getCollapsedLineEdgeCaretGeometry, getSelectionRectsFromDom };
|
|
@@ -232,7 +232,7 @@ function getSelectionRectsFromDom(container, from, to, overlayRect) {
|
|
|
232
232
|
* below the line until visible text is typed. Anchor the caret to the nearest
|
|
233
233
|
* painted sibling instead; an all-whitespace line falls back to its line box.
|
|
234
234
|
*/
|
|
235
|
-
function getCollapsedLineEdgeCaretGeometry(spanEl) {
|
|
235
|
+
function getCollapsedLineEdgeCaretGeometry(spanEl, pmPos) {
|
|
236
236
|
const isLeading = spanEl.dataset["collapsedLeadingSpaces"] === "true";
|
|
237
237
|
const isTrailing = spanEl.dataset["collapsedTrailingSpaces"] === "true";
|
|
238
238
|
if (!isLeading && !isTrailing) return null;
|
|
@@ -242,14 +242,50 @@ function getCollapsedLineEdgeCaretGeometry(spanEl) {
|
|
|
242
242
|
const line = closestHtmlElement(spanEl, ".layout-line");
|
|
243
243
|
const anchorRect = sibling?.getBoundingClientRect() ?? line?.getBoundingClientRect() ?? spanRect;
|
|
244
244
|
const lineRect = line?.getBoundingClientRect();
|
|
245
|
+
const pmStart = Number(spanEl.dataset["pmStart"]);
|
|
246
|
+
const pmEnd = Number(spanEl.dataset["pmEnd"]);
|
|
247
|
+
const storedSpaceAdvance = Number(spanEl.dataset["collapsedSpaceAdvance"]);
|
|
248
|
+
const lineScale = line && line.offsetWidth > 0 && lineRect ? lineRect.width / line.offsetWidth : 1;
|
|
249
|
+
const trailingSpaceCount = isTrailing && pmPos !== void 0 && Number.isFinite(pmStart) && Number.isFinite(pmEnd) ? Math.max(0, Math.min(pmPos, pmEnd) - pmStart) : 0;
|
|
250
|
+
const inlineDirection = spanRect.left <= anchorRect.left ? -1 : 1;
|
|
251
|
+
const trailingAdvance = Number.isFinite(storedSpaceAdvance) && lineScale > 0 ? trailingSpaceCount * storedSpaceAdvance * lineScale * inlineDirection : 0;
|
|
245
252
|
return {
|
|
246
|
-
left: spanRect.left,
|
|
253
|
+
left: spanRect.left + trailingAdvance,
|
|
247
254
|
top: anchorRect.top,
|
|
248
255
|
height: anchorRect.height || lineRect?.height || 16
|
|
249
256
|
};
|
|
250
257
|
}
|
|
258
|
+
/**
|
|
259
|
+
* Prefer a collapsed line-edge span when multiple painted spans share the PM
|
|
260
|
+
* position. Generic text runs use inclusive endpoints, so DOM order alone
|
|
261
|
+
* cannot decide which span owns a boundary.
|
|
262
|
+
*/
|
|
263
|
+
function findCollapsedLineEdgeCaretTarget(spans, pmPos) {
|
|
264
|
+
for (const span of spans) {
|
|
265
|
+
const pmStart = Number(span.dataset["pmStart"]);
|
|
266
|
+
const pmEnd = Number(span.dataset["pmEnd"]);
|
|
267
|
+
if (pmPos < pmStart || pmPos > pmEnd) continue;
|
|
268
|
+
const geometry = getCollapsedLineEdgeCaretGeometry(span, pmPos);
|
|
269
|
+
if (geometry) return {
|
|
270
|
+
span,
|
|
271
|
+
geometry
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
return null;
|
|
275
|
+
}
|
|
251
276
|
function getCaretPositionFromDom(container, pmPos, overlayRect) {
|
|
252
277
|
const spans = htmlQueryAll(container, ".layout-page-content span[data-pm-start][data-pm-end]");
|
|
278
|
+
const collapsedTarget = findCollapsedLineEdgeCaretTarget(spans, pmPos);
|
|
279
|
+
if (collapsedTarget) {
|
|
280
|
+
const pageEl = closestHtmlElement(collapsedTarget.span, ".layout-page");
|
|
281
|
+
const pageIndex = pageEl ? Number(pageEl.dataset["pageNumber"] || 1) - 1 : 0;
|
|
282
|
+
return {
|
|
283
|
+
x: collapsedTarget.geometry.left - overlayRect.left,
|
|
284
|
+
y: collapsedTarget.geometry.top - overlayRect.top,
|
|
285
|
+
height: collapsedTarget.geometry.height,
|
|
286
|
+
pageIndex
|
|
287
|
+
};
|
|
288
|
+
}
|
|
253
289
|
for (const spanEl of spans) {
|
|
254
290
|
const pmStart = Number(spanEl.dataset["pmStart"]);
|
|
255
291
|
const pmEnd = Number(spanEl.dataset["pmEnd"]);
|
|
@@ -270,17 +306,6 @@ function getCaretPositionFromDom(container, pmPos, overlayRect) {
|
|
|
270
306
|
continue;
|
|
271
307
|
}
|
|
272
308
|
if (pmPos >= pmStart && pmPos <= pmEnd) {
|
|
273
|
-
const collapsedGeometry = getCollapsedLineEdgeCaretGeometry(spanEl);
|
|
274
|
-
if (collapsedGeometry) {
|
|
275
|
-
const pageEl = closestHtmlElement(spanEl, ".layout-page");
|
|
276
|
-
const pageIndex = pageEl ? Number(pageEl.dataset["pageNumber"] || 1) - 1 : 0;
|
|
277
|
-
return {
|
|
278
|
-
x: collapsedGeometry.left - overlayRect.left,
|
|
279
|
-
y: collapsedGeometry.top - overlayRect.top,
|
|
280
|
-
height: collapsedGeometry.height,
|
|
281
|
-
pageIndex
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
309
|
const textNode = spanEl.firstChild;
|
|
285
310
|
if (!textNode || textNode.nodeType !== Node.TEXT_NODE) {
|
|
286
311
|
const spanRect = spanEl.getBoundingClientRect();
|
|
@@ -335,4 +360,4 @@ function getCaretPositionFromDom(container, pmPos, overlayRect) {
|
|
|
335
360
|
return null;
|
|
336
361
|
}
|
|
337
362
|
//#endregion
|
|
338
|
-
export { clickToPositionDom, findPositionInSpan, getCaretPositionFromDom, getCollapsedLineEdgeCaretGeometry, getSelectionRectsFromDom };
|
|
363
|
+
export { clickToPositionDom, findCollapsedLineEdgeCaretTarget, findPositionInSpan, getCaretPositionFromDom, getCollapsedLineEdgeCaretGeometry, getSelectionRectsFromDom };
|
|
@@ -69,7 +69,7 @@ function computeHfCaretRectFromView(view, section, doc = globalThis.document) {
|
|
|
69
69
|
const end = Number(span.dataset["pmEnd"]);
|
|
70
70
|
if (!Number.isFinite(start) || !Number.isFinite(end)) continue;
|
|
71
71
|
if (pmPos >= start && pmPos <= end) {
|
|
72
|
-
const collapsedGeometry = getCollapsedLineEdgeCaretGeometry(span);
|
|
72
|
+
const collapsedGeometry = getCollapsedLineEdgeCaretGeometry(span, pmPos);
|
|
73
73
|
if (collapsedGeometry) return {
|
|
74
74
|
top: collapsedGeometry.top,
|
|
75
75
|
left: collapsedGeometry.left,
|
|
@@ -988,11 +988,14 @@ function renderLine(block, line, alignment, doc, options) {
|
|
|
988
988
|
const splitRuns = splitTextRunsByEastAsia(sliceRunsForLine(block, line));
|
|
989
989
|
const { runs: runsForLine, collapsedLeadingRuns: collapsedLeadingSpaceRuns, collapsedTrailingRuns: collapsedTrailingSpaceRuns } = splitCollapsibleLineEdgeSpaces(splitRuns, startsAfterSoftWrap(block, line));
|
|
990
990
|
const isCollapsedLineEdgeSpaceRun = (run) => collapsedLeadingSpaceRuns.has(run) || collapsedTrailingSpaceRuns.has(run);
|
|
991
|
+
const collapsedSpaceMeasureText = collapsedLeadingSpaceRuns.size > 0 || collapsedTrailingSpaceRuns.size > 0 ? createTextMeasurer(doc) : void 0;
|
|
991
992
|
const renderLineTextRun = (run) => {
|
|
992
993
|
const runEl = renderTextRun(run, doc);
|
|
993
994
|
if (collapsedLeadingSpaceRuns.has(run)) runEl.dataset["collapsedLeadingSpaces"] = "true";
|
|
994
995
|
if (collapsedTrailingSpaceRuns.has(run)) runEl.dataset["collapsedTrailingSpaces"] = "true";
|
|
995
996
|
if (isCollapsedLineEdgeSpaceRun(run)) {
|
|
997
|
+
const spaceAdvance = (collapsedSpaceMeasureText?.(" ", run.fontSize || 11, run.fontFamily || "Calibri", runMeasureStyle(run)) ?? 0) * ((run.horizontalScale ?? 100) / 100);
|
|
998
|
+
runEl.dataset["collapsedSpaceAdvance"] = String(spaceAdvance);
|
|
996
999
|
runEl.style.fontSize = "0";
|
|
997
1000
|
runEl.style.letterSpacing = "0";
|
|
998
1001
|
runEl.style.wordSpacing = "0";
|
|
@@ -1055,7 +1058,7 @@ function renderLine(block, line, alignment, doc, options) {
|
|
|
1055
1058
|
lineEl.style.overflow = "visible";
|
|
1056
1059
|
let tabContext;
|
|
1057
1060
|
const hasScaledTextRun = runsForLine.some((run) => (isTextRun(run) || isFieldRun(run) || isMathRun(run)) && run.horizontalScale !== void 0 && run.horizontalScale !== 100);
|
|
1058
|
-
const measureText = hasTabRuns || hasScaledTextRun ? createTextMeasurer(doc) : void 0;
|
|
1061
|
+
const measureText = collapsedSpaceMeasureText ?? (hasTabRuns || hasScaledTextRun ? createTextMeasurer(doc) : void 0);
|
|
1059
1062
|
if (hasTabRuns) {
|
|
1060
1063
|
const explicitStops = options?.tabStops?.map(convertTabStopToCalc);
|
|
1061
1064
|
const leftIndentTwips = options?.leftIndentPx ? Math.round(options.leftIndentPx * 15) : 0;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { findCollapsedLineEdgeCaretTarget } from "../layout-bridge/dom/clickToPositionDom.js";
|
|
2
2
|
import { findBodyEmptyRuns, findBodyPmSpans } from "../layout-bridge/dom/findBodyPmSpans.js";
|
|
3
3
|
import { closestHtmlElement } from "../utils/domGuards.js";
|
|
4
4
|
//#region src/render-dom/RenderedDomContext.ts
|
|
@@ -27,7 +27,14 @@ var RenderedDomContextImpl = class {
|
|
|
27
27
|
}
|
|
28
28
|
getCoordinatesForPosition(pmPos) {
|
|
29
29
|
const containerRect = this.#pagesContainer.getBoundingClientRect();
|
|
30
|
-
|
|
30
|
+
const spans = findBodyPmSpans(this.#pagesContainer);
|
|
31
|
+
const collapsedTarget = findCollapsedLineEdgeCaretTarget(spans, pmPos);
|
|
32
|
+
if (collapsedTarget) return {
|
|
33
|
+
x: (collapsedTarget.geometry.left - containerRect.left) / this.#zoom,
|
|
34
|
+
y: (collapsedTarget.geometry.top - containerRect.top) / this.#zoom,
|
|
35
|
+
height: lineHeightFor(collapsedTarget.span, this.#zoom)
|
|
36
|
+
};
|
|
37
|
+
for (const span of spans) {
|
|
31
38
|
const pmStart = Number(span.dataset["pmStart"]);
|
|
32
39
|
const pmEnd = Number(span.dataset["pmEnd"]);
|
|
33
40
|
if (!(span.classList.contains("layout-run-tab") ? pmPos >= pmStart && pmPos < pmEnd : pmPos >= pmStart && pmPos <= pmEnd)) continue;
|
|
@@ -37,12 +44,6 @@ var RenderedDomContextImpl = class {
|
|
|
37
44
|
y: (spanRect.top - containerRect.top) / this.#zoom,
|
|
38
45
|
height: lineHeightFor(span, this.#zoom)
|
|
39
46
|
};
|
|
40
|
-
const collapsedGeometry = getCollapsedLineEdgeCaretGeometry(span);
|
|
41
|
-
if (collapsedGeometry) return {
|
|
42
|
-
x: (collapsedGeometry.left - containerRect.left) / this.#zoom,
|
|
43
|
-
y: (collapsedGeometry.top - containerRect.top) / this.#zoom,
|
|
44
|
-
height: lineHeightFor(span, this.#zoom)
|
|
45
|
-
};
|
|
46
47
|
const textNode = textNodeForSpan(span);
|
|
47
48
|
if (!textNode) return {
|
|
48
49
|
x: (spanRect.left - containerRect.left) / this.#zoom,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stll/folio-core",
|
|
3
|
-
"version": "0.15.
|
|
3
|
+
"version": "0.15.13",
|
|
4
4
|
"description": "Headless, framework-neutral core of folio: the OOXML (.docx) parser, document model, ProseMirror integration, and page-layout engine. No React.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"document-model",
|