@linloir/limr 0.1.0 → 1.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/README.en.md +151 -0
- package/README.md +80 -127
- package/benchmarks/results/layout.json +2593 -0
- package/benchmarks/results/markstream-code.json +1823 -0
- package/benchmarks/results/markstream-reading-repeat.json +1152 -0
- package/benchmarks/results/markstream.json +12486 -0
- package/benchmarks/results/streaming-browser.json +77 -0
- package/benchmarks/results/streaming.json +357 -0
- package/dist/base.css +93 -10
- package/dist/{chunk-7JF5HHVF.js → chunk-BG5QUQFR.js} +340 -72
- package/dist/chunk-BG5QUQFR.js.map +1 -0
- package/dist/chunk-BVHHOVMT.js +179 -0
- package/dist/chunk-BVHHOVMT.js.map +1 -0
- package/dist/chunk-FJZCQY2S.js +155 -0
- package/dist/chunk-FJZCQY2S.js.map +1 -0
- package/dist/chunk-FSI5OTBW.js +1 -0
- package/dist/{chunk-ETHLPBKQ.js → chunk-GU2RPESF.js} +238 -131
- package/dist/chunk-GU2RPESF.js.map +1 -0
- package/dist/{chunk-65V5OZ4G.js → chunk-SUAAUGAX.js} +1350 -511
- package/dist/chunk-SUAAUGAX.js.map +1 -0
- package/dist/core/index.d.ts +6 -3
- package/dist/core/index.js +15 -5
- package/dist/extensions/index.d.ts +30 -5
- package/dist/extensions/index.js +15 -3
- package/dist/index.d.ts +4 -4
- package/dist/index.js +31 -8
- package/dist/{engine-43u8B4yt.d.ts → knuth-plass-C8mgFm7W.d.ts} +67 -1
- package/dist/knuth-plass-layout-CHQCWKB5.js +449 -0
- package/dist/knuth-plass-layout-CHQCWKB5.js.map +1 -0
- package/dist/react/index.d.ts +7 -5
- package/dist/react/index.js +7 -3
- package/dist/styles.css +93 -10
- package/dist/{translations-BliabrPd.d.ts → translations-BXzSwLBJ.d.ts} +49 -4
- package/docs/README.md +13 -0
- package/docs/api.md +5 -158
- package/docs/assets/rendered.svg +9 -0
- package/docs/assets/source.svg +9 -0
- package/docs/en/README.md +28 -0
- package/docs/en/ai-skills.md +57 -0
- package/docs/en/annotations.md +86 -0
- package/docs/en/api.md +115 -0
- package/docs/en/architecture.md +41 -0
- package/docs/en/extensions.md +208 -0
- package/docs/en/getting-started.md +69 -0
- package/docs/en/integration.md +154 -0
- package/docs/en/modules.md +84 -0
- package/docs/en/performance.md +93 -0
- package/docs/en/plugin-packages.md +68 -0
- package/docs/en/styles.md +99 -0
- package/docs/en/syntax.md +455 -0
- package/docs/extensions.md +5 -306
- package/docs/implementation.md +5 -76
- package/docs/performance.md +5 -81
- package/docs/screenshots/blocks.png +0 -0
- package/docs/screenshots/dark.png +0 -0
- package/docs/screenshots/desktop.png +0 -0
- package/docs/screenshots/plugin-mobile.png +0 -0
- package/docs/styles.md +5 -100
- package/docs/visual-upgrade.md +5 -145
- package/docs/zh-CN/README.md +28 -0
- package/docs/zh-CN/ai-skills.md +57 -0
- package/docs/zh-CN/annotations.md +86 -0
- package/docs/zh-CN/api.md +115 -0
- package/docs/zh-CN/architecture.md +41 -0
- package/docs/zh-CN/extensions.md +210 -0
- package/docs/zh-CN/getting-started.md +69 -0
- package/docs/zh-CN/integration.md +154 -0
- package/docs/zh-CN/modules.md +84 -0
- package/docs/zh-CN/performance.md +93 -0
- package/docs/zh-CN/plugin-packages.md +68 -0
- package/docs/zh-CN/styles.md +99 -0
- package/docs/zh-CN/syntax.md +457 -0
- package/examples/notes.tsx +18 -11
- package/examples/packages/paper-theme/index.css +25 -0
- package/examples/packages/paper-theme/package.json +7 -0
- package/examples/packages/reading-tools/index.d.ts +2 -0
- package/examples/packages/reading-tools/index.js +25 -0
- package/examples/packages/reading-tools/package.json +16 -0
- package/package.json +17 -5
- package/skills/limr-plugin-development/SKILL.md +22 -0
- package/skills/limr-plugin-development/agents/openai.yaml +4 -0
- package/skills/limr-plugin-development/assets/plugin-template/README.md +30 -0
- package/skills/limr-plugin-development/assets/plugin-template/package.json +36 -0
- package/skills/limr-plugin-development/assets/plugin-template/src/index.tsx +50 -0
- package/skills/limr-plugin-development/assets/plugin-template/src/styles.css +9 -0
- package/skills/limr-plugin-development/assets/plugin-template/tsconfig.json +20 -0
- package/skills/limr-plugin-development/assets/plugin-template/tsup.config.ts +8 -0
- package/skills/limr-plugin-development/references/contract.md +51 -0
- package/skills/limr-use/SKILL.md +23 -0
- package/skills/limr-use/agents/openai.yaml +4 -0
- package/skills/limr-use/references/integration.md +49 -0
- package/skills/limr-use/references/syntax.md +20 -0
- package/dist/chunk-65V5OZ4G.js.map +0 -1
- package/dist/chunk-7JF5HHVF.js.map +0 -1
- package/dist/chunk-ETHLPBKQ.js.map +0 -1
- package/dist/chunk-V2OG4Y3F.js +0 -1
- /package/dist/{chunk-V2OG4Y3F.js.map → chunk-FSI5OTBW.js.map} +0 -0
|
@@ -0,0 +1,449 @@
|
|
|
1
|
+
import {
|
|
2
|
+
measurementRange
|
|
3
|
+
} from "./chunk-BVHHOVMT.js";
|
|
4
|
+
import {
|
|
5
|
+
prepareKnuthPlass
|
|
6
|
+
} from "./chunk-FJZCQY2S.js";
|
|
7
|
+
import {
|
|
8
|
+
LruCache
|
|
9
|
+
} from "./chunk-6N6TFHEN.js";
|
|
10
|
+
|
|
11
|
+
// src/react/knuth-plass-layout.ts
|
|
12
|
+
import LineBreaker from "linebreak";
|
|
13
|
+
import Hypher from "hypher";
|
|
14
|
+
import patterns from "hyphenation.en-us";
|
|
15
|
+
var hypher = new Hypher(patterns);
|
|
16
|
+
var wordWidths = new LruCache(8192);
|
|
17
|
+
var hyphens = new LruCache(2048);
|
|
18
|
+
var plans = new LruCache(256);
|
|
19
|
+
var canvas;
|
|
20
|
+
var jobs = /* @__PURE__ */ new Map();
|
|
21
|
+
var queue = /* @__PURE__ */ new Set();
|
|
22
|
+
var frame = 0;
|
|
23
|
+
var resize;
|
|
24
|
+
var intersection;
|
|
25
|
+
var listening = false;
|
|
26
|
+
function selected(element) {
|
|
27
|
+
const selection = element.ownerDocument.getSelection();
|
|
28
|
+
return !!selection?.rangeCount && !selection.isCollapsed && selection.getRangeAt(0).intersectsNode(element);
|
|
29
|
+
}
|
|
30
|
+
function defer(job) {
|
|
31
|
+
const state = selected(job.element) ? "wrap" : "clip";
|
|
32
|
+
if (job.element.dataset.limrKpStale !== state) job.element.dataset.limrKpStale = state;
|
|
33
|
+
}
|
|
34
|
+
function enqueue(job) {
|
|
35
|
+
if (job.disposed) return;
|
|
36
|
+
job.dirty = true;
|
|
37
|
+
if (!job.visible) return;
|
|
38
|
+
queue.add(job);
|
|
39
|
+
if (!frame) frame = requestAnimationFrame(flush);
|
|
40
|
+
}
|
|
41
|
+
function observe(job) {
|
|
42
|
+
job.observer.observe(job.element, { subtree: true, childList: true, characterData: true, attributes: true, attributeFilter: ["class", "style", "hidden"] });
|
|
43
|
+
}
|
|
44
|
+
function restore(job, changed) {
|
|
45
|
+
job.observer.disconnect();
|
|
46
|
+
job.undo?.(changed);
|
|
47
|
+
job.undo = void 0;
|
|
48
|
+
job.update = void 0;
|
|
49
|
+
job.reflow = void 0;
|
|
50
|
+
job.plan = void 0;
|
|
51
|
+
}
|
|
52
|
+
function flush() {
|
|
53
|
+
frame = 0;
|
|
54
|
+
const end = performance.now() + 6, writes = [];
|
|
55
|
+
for (const job of queue) {
|
|
56
|
+
queue.delete(job);
|
|
57
|
+
if (job.disposed || !job.visible || selected(job.element)) continue;
|
|
58
|
+
const animations = job.element.getAnimations({ subtree: true }).filter((animation) => animation.playState === "running" && animation.effect?.getTiming().iterations !== Infinity);
|
|
59
|
+
if (animations.length) {
|
|
60
|
+
void Promise.allSettled(animations.map((animation) => animation.finished)).then(() => enqueue(job));
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
const apply2 = prepare(job);
|
|
64
|
+
writes.push(() => {
|
|
65
|
+
if (job.disposed) return;
|
|
66
|
+
apply2?.();
|
|
67
|
+
job.element.removeAttribute("data-limr-kp-stale");
|
|
68
|
+
job.dirty = false;
|
|
69
|
+
observe(job);
|
|
70
|
+
if (apply2) job.runtime.requestLayout();
|
|
71
|
+
});
|
|
72
|
+
if (performance.now() >= end) break;
|
|
73
|
+
}
|
|
74
|
+
for (const write of writes) write();
|
|
75
|
+
if (queue.size) frame = requestAnimationFrame(flush);
|
|
76
|
+
}
|
|
77
|
+
function initialize() {
|
|
78
|
+
if (listening) return;
|
|
79
|
+
listening = true;
|
|
80
|
+
resize = new ResizeObserver((entries) => {
|
|
81
|
+
const narrower = [];
|
|
82
|
+
for (const entry of entries) {
|
|
83
|
+
const job = jobs.get(entry.target);
|
|
84
|
+
if (job) {
|
|
85
|
+
const font = fontKey(getComputedStyle(job.element));
|
|
86
|
+
if (job.undo && entry.contentRect.width < (job.width ?? entry.contentRect.width) && (!job.visible || selected(job.element))) narrower.push(job);
|
|
87
|
+
if (job.width !== entry.contentRect.width || font !== job.font) {
|
|
88
|
+
job.width = entry.contentRect.width;
|
|
89
|
+
job.font = font;
|
|
90
|
+
enqueue(job);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
for (const job of narrower) defer(job);
|
|
95
|
+
});
|
|
96
|
+
intersection = new IntersectionObserver((entries) => {
|
|
97
|
+
for (const entry of entries) {
|
|
98
|
+
const job = jobs.get(entry.target);
|
|
99
|
+
if (!job) continue;
|
|
100
|
+
job.visible = entry.isIntersecting;
|
|
101
|
+
if (job.visible && (job.dirty || !job.undo)) enqueue(job);
|
|
102
|
+
else if (!job.visible && job.dirty && job.undo) defer(job);
|
|
103
|
+
}
|
|
104
|
+
}, { rootMargin: "600px" });
|
|
105
|
+
document.addEventListener("selectionchange", selectionChanged);
|
|
106
|
+
document.fonts.addEventListener("loadingdone", fontsChanged);
|
|
107
|
+
}
|
|
108
|
+
function selectionChanged() {
|
|
109
|
+
for (const job of jobs.values()) if ((job.dirty || !job.undo) && !selected(job.element)) enqueue(job);
|
|
110
|
+
}
|
|
111
|
+
function fontsChanged() {
|
|
112
|
+
wordWidths.clear();
|
|
113
|
+
plans.clear();
|
|
114
|
+
for (const job of jobs.values()) {
|
|
115
|
+
job.prepared = void 0;
|
|
116
|
+
enqueue(job);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
function typeset(root, runtime, options = {}) {
|
|
120
|
+
initialize();
|
|
121
|
+
const elements = [root, ...root.querySelectorAll("p,.limr-paragraph,li")].filter((element) => element.matches("p,.limr-paragraph,li") && !element.closest("pre,[data-limr-ignore]") && !element.querySelector('p,ul,ol,blockquote,aside,[data-limr-atomic="block"]'));
|
|
122
|
+
const owned = [];
|
|
123
|
+
for (const element of elements) {
|
|
124
|
+
if (jobs.has(element)) continue;
|
|
125
|
+
const job = { element, runtime, options, visible: false, dirty: true, disposed: false, observer: new MutationObserver((records) => {
|
|
126
|
+
const relevant = records.filter((record) => {
|
|
127
|
+
const target = record.target instanceof Element ? record.target : record.target.parentElement;
|
|
128
|
+
if (target?.closest(".limr-highlight-layer,.limr-paint-layer")) return false;
|
|
129
|
+
return record.type !== "childList" || ![...record.addedNodes, ...record.removedNodes].every((node) => node instanceof Element && node.matches(".limr-highlight-layer,.limr-paint-layer"));
|
|
130
|
+
});
|
|
131
|
+
if (!relevant.length) return;
|
|
132
|
+
job.prepared = void 0;
|
|
133
|
+
restore(job, new Set(relevant.filter((record) => record.type === "characterData").map((record) => record.target)));
|
|
134
|
+
observe(job);
|
|
135
|
+
enqueue(job);
|
|
136
|
+
}) };
|
|
137
|
+
owned.push(job);
|
|
138
|
+
jobs.set(element, job);
|
|
139
|
+
resize.observe(element);
|
|
140
|
+
intersection.observe(element);
|
|
141
|
+
observe(job);
|
|
142
|
+
}
|
|
143
|
+
return () => {
|
|
144
|
+
for (const job of owned) {
|
|
145
|
+
job.disposed = true;
|
|
146
|
+
queue.delete(job);
|
|
147
|
+
restore(job);
|
|
148
|
+
resize.unobserve(job.element);
|
|
149
|
+
intersection.unobserve(job.element);
|
|
150
|
+
jobs.delete(job.element);
|
|
151
|
+
}
|
|
152
|
+
if (!jobs.size) {
|
|
153
|
+
resize?.disconnect();
|
|
154
|
+
intersection?.disconnect();
|
|
155
|
+
cancelAnimationFrame(frame);
|
|
156
|
+
frame = 0;
|
|
157
|
+
document.removeEventListener("selectionchange", selectionChanged);
|
|
158
|
+
document.fonts.removeEventListener("loadingdone", fontsChanged);
|
|
159
|
+
listening = false;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
function collect(element) {
|
|
164
|
+
const segments = [];
|
|
165
|
+
let offset = 0;
|
|
166
|
+
function visit(node) {
|
|
167
|
+
if (node instanceof Text) {
|
|
168
|
+
const text = node.data;
|
|
169
|
+
if (text) {
|
|
170
|
+
segments.push({ node, start: offset, end: offset + text.length, text });
|
|
171
|
+
offset += text.length;
|
|
172
|
+
}
|
|
173
|
+
} else if (node instanceof Element) {
|
|
174
|
+
const style = getComputedStyle(node);
|
|
175
|
+
if (node.hasAttribute("hidden") || node.matches(".limr-highlight-layer,.limr-paint-layer") || style.display === "none" || style.position === "absolute" || style.position === "fixed") return;
|
|
176
|
+
if (node.tagName === "BR" || node.matches("[data-limr-atomic], [data-limr-ignore], code, img, svg, button, input")) {
|
|
177
|
+
segments.push({ node, start: offset, end: ++offset, text: node.tagName === "BR" ? "\u2028" : "\uFFFC" });
|
|
178
|
+
} else node.childNodes.forEach(visit);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
element.childNodes.forEach(visit);
|
|
182
|
+
return segments;
|
|
183
|
+
}
|
|
184
|
+
function fontKey(style) {
|
|
185
|
+
return [style.fontFamily, style.fontSize, style.fontWeight, style.fontStyle, style.fontStretch, style.fontVariantLigatures, style.fontFeatureSettings, style.fontVariationSettings, style.letterSpacing, style.wordSpacing, style.textTransform, style.fontKerning, style.getPropertyValue("text-spacing-trim")].join("|");
|
|
186
|
+
}
|
|
187
|
+
function itemize(element, options) {
|
|
188
|
+
const segments = collect(element), text = segments.map((segment) => segment.text).join("");
|
|
189
|
+
const segmentStarts = new Map(segments.map((segment) => [segment.start, segment]));
|
|
190
|
+
if (!text.trim()) return;
|
|
191
|
+
const breaks = /* @__PURE__ */ new Map();
|
|
192
|
+
const breaker = new LineBreaker(text);
|
|
193
|
+
for (let next = breaker.nextBreak(); next; next = breaker.nextBreak()) if (next.position < text.length) breaks.set(next.position, { required: next.required });
|
|
194
|
+
if (options.hyphenate !== false) for (const word of text.matchAll(/[a-zA-Z]{5,}/g)) {
|
|
195
|
+
let pieces = options.hyphenate ? options.hyphenate(word[0]) : hyphens.get(word[0]);
|
|
196
|
+
if (!pieces) {
|
|
197
|
+
pieces = hypher.hyphenate(word[0]);
|
|
198
|
+
hyphens.set(word[0], pieces);
|
|
199
|
+
}
|
|
200
|
+
if (pieces.join("") !== word[0]) continue;
|
|
201
|
+
let at = word.index;
|
|
202
|
+
for (const piece of pieces.slice(0, -1)) {
|
|
203
|
+
at += piece.length;
|
|
204
|
+
if (!breaks.has(at)) breaks.set(at, { hyphen: true, automatic: true });
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
const atomics = [];
|
|
208
|
+
const items = [], styleCache = /* @__PURE__ */ new Map();
|
|
209
|
+
const range = measurementRange(element.ownerDocument);
|
|
210
|
+
function metrics(parent) {
|
|
211
|
+
let found = styleCache.get(parent);
|
|
212
|
+
if (found) return found;
|
|
213
|
+
const style = getComputedStyle(parent), font = style.font || `${style.fontStyle} ${style.fontWeight} ${style.fontSize} ${style.fontFamily}`;
|
|
214
|
+
canvas ??= document.createElement("canvas").getContext("2d");
|
|
215
|
+
canvas.font = font;
|
|
216
|
+
const spacing = parseFloat(style.letterSpacing) || 0;
|
|
217
|
+
const wordSpacing = parseFloat(style.wordSpacing) || 0;
|
|
218
|
+
found = { key: fontKey(style), space: canvas.measureText(" ").width + spacing + wordSpacing, hyphen: canvas.measureText("-").width + spacing, em: parseFloat(style.fontSize), wordSpacing };
|
|
219
|
+
styleCache.set(parent, found);
|
|
220
|
+
return found;
|
|
221
|
+
}
|
|
222
|
+
function measure(node, from, to, key) {
|
|
223
|
+
const text2 = node.data.slice(from, to), cacheKey = `${key}\0${text2}`;
|
|
224
|
+
const cached = wordWidths.get(cacheKey);
|
|
225
|
+
if (cached !== void 0) return cached;
|
|
226
|
+
range.setStart(node, from);
|
|
227
|
+
range.setEnd(node, to);
|
|
228
|
+
const measured = [...range.getClientRects()].reduce((sum, rect) => sum + rect.width, 0);
|
|
229
|
+
wordWidths.set(cacheKey, measured);
|
|
230
|
+
return measured;
|
|
231
|
+
}
|
|
232
|
+
for (const segment of segments) {
|
|
233
|
+
const { node } = segment;
|
|
234
|
+
if (!(node instanceof Text)) {
|
|
235
|
+
if (node.tagName === "BR") items.push({ type: "glue", width: 0, stretch: 1, shrink: 0, infinite: true }, { type: "penalty", width: 0, penalty: -1e4, anchor: { node, start: 0, end: 0, existingBreak: true } });
|
|
236
|
+
else {
|
|
237
|
+
const width = node.getBoundingClientRect().width;
|
|
238
|
+
items.push({ type: "box", width });
|
|
239
|
+
atomics.push({ element: node, width });
|
|
240
|
+
}
|
|
241
|
+
continue;
|
|
242
|
+
}
|
|
243
|
+
const style = metrics(node.parentElement);
|
|
244
|
+
const points = /* @__PURE__ */ new Set([0, segment.text.length]);
|
|
245
|
+
for (const at of breaks.keys()) if (at > segment.start && at <= segment.end) points.add(at - segment.start);
|
|
246
|
+
for (const space of segment.text.matchAll(/[ \t\r\n\f]+/g)) {
|
|
247
|
+
points.add(space.index);
|
|
248
|
+
points.add(space.index + space[0].length);
|
|
249
|
+
}
|
|
250
|
+
const sorted = [...points].sort((a, b) => a - b);
|
|
251
|
+
for (let i = 1; i < sorted.length; i++) {
|
|
252
|
+
const start = sorted[i - 1], end = sorted[i], value = segment.text.slice(start, end);
|
|
253
|
+
const anchor = { node, start, end, wordSpacing: style.wordSpacing };
|
|
254
|
+
if (/^[ \t\r\n\f]+$/.test(value)) {
|
|
255
|
+
const preceding = items.at(-1);
|
|
256
|
+
const space = preceding?.type === "glue" ? 0 : style.space;
|
|
257
|
+
items.push({ type: "glue", width: space, stretch: space / 2, shrink: space / 3, anchor });
|
|
258
|
+
} else {
|
|
259
|
+
items.push({ type: "box", width: measure(node, start, end, style.key) });
|
|
260
|
+
const point = segment.start + end, opportunity = breaks.get(point);
|
|
261
|
+
const next = segmentStarts.get(point);
|
|
262
|
+
if (opportunity && !(next?.node instanceof Element && next.node.hasAttribute("data-limr-ignore"))) {
|
|
263
|
+
const at = { node, start: end, end };
|
|
264
|
+
if (opportunity.hyphen) items.push({ type: "penalty", width: style.hyphen, penalty: options.hyphenPenalty ?? 50, flagged: true, automatic: opportunity.automatic, anchor: at });
|
|
265
|
+
else if (opportunity.required) items.push({ type: "glue", width: 0, stretch: 1, shrink: 0, infinite: true }, { type: "penalty", width: 0, penalty: -1e4, anchor: at });
|
|
266
|
+
else if (!/[ \t\r\n\f]/.test(text[point] ?? "")) items.push({ type: "glue", width: 0, stretch: style.em * 0.15, shrink: 0, anchor: at });
|
|
267
|
+
}
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
}
|
|
271
|
+
items.push({ type: "penalty", width: 0, penalty: 1e4 }, { type: "glue", width: 0, stretch: 1, shrink: 0, infinite: true }, { type: "penalty", width: 0, penalty: -1e4 });
|
|
272
|
+
return { items, atomics, layout: prepareKnuthPlass(items), styles: new Map([...styleCache].map(([element2, style]) => [element2, style.key])), signature: JSON.stringify([options, items.map(({ anchor: _anchor, ...item }) => item)]) };
|
|
273
|
+
}
|
|
274
|
+
function prepare(job) {
|
|
275
|
+
const { element, options } = job, base = getComputedStyle(element);
|
|
276
|
+
const width = element.clientWidth - parseFloat(base.paddingLeft) - parseFloat(base.paddingRight);
|
|
277
|
+
if (width <= 0) return;
|
|
278
|
+
if (job.prepared && ([...job.prepared.styles].some(([element2, key]) => !element2.isConnected || fontKey(getComputedStyle(element2)) !== key) || job.prepared.atomics.some(({ element: element2, width: width2 }) => element2.getBoundingClientRect().width !== width2))) job.prepared = void 0;
|
|
279
|
+
if (!job.prepared) {
|
|
280
|
+
restore(job);
|
|
281
|
+
job.prepared = itemize(element, options);
|
|
282
|
+
}
|
|
283
|
+
const prepared = job.prepared;
|
|
284
|
+
if (!prepared) return;
|
|
285
|
+
const { items } = prepared;
|
|
286
|
+
const indent = (parseFloat(base.textIndent) || 0) * (base.textIndent.endsWith("%") ? width / 100 : 1);
|
|
287
|
+
const lengths = indent ? [width - indent, width] : width;
|
|
288
|
+
const emergencyStretch = options.emergencyStretch ?? parseFloat(base.fontSize) * 3;
|
|
289
|
+
const signature = `${width}:${indent}:${emergencyStretch}:${prepared.signature}`;
|
|
290
|
+
let plan = plans.get(signature);
|
|
291
|
+
if (!plan) {
|
|
292
|
+
plan = prepared.layout(lengths, { ...options, emergencyStretch });
|
|
293
|
+
plans.set(signature, plan);
|
|
294
|
+
}
|
|
295
|
+
if (!plan.lines.length) return;
|
|
296
|
+
if (job.plan?.lines.length === plan.lines.length && job.plan.lines.every((line, index) => line.index === plan.lines[index].index && line.ratio === plan.lines[index].ratio)) return;
|
|
297
|
+
if (job.update && job.plan?.lines.length === plan.lines.length && job.plan.lines.every((line, index) => line.index === plan.lines[index].index)) {
|
|
298
|
+
return () => {
|
|
299
|
+
job.observer.disconnect();
|
|
300
|
+
job.update(plan);
|
|
301
|
+
job.plan = plan;
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
return () => {
|
|
305
|
+
job.observer.disconnect();
|
|
306
|
+
const applied = job.reflow ? job.reflow(plan) : apply(element, items, plan);
|
|
307
|
+
job.undo = applied.undo;
|
|
308
|
+
job.update = applied.update;
|
|
309
|
+
job.reflow = applied.reflow;
|
|
310
|
+
job.plan = plan;
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
function apply(element, items, plan, previous = []) {
|
|
314
|
+
const saved = new Map(previous.map((original) => [original.node, original]));
|
|
315
|
+
const insertions = /* @__PURE__ */ new Map();
|
|
316
|
+
const patches = [];
|
|
317
|
+
const add = (anchor, insertion) => {
|
|
318
|
+
if (anchor?.node instanceof Text) insertions.set(anchor.node, [...insertions.get(anchor.node) ?? [], { start: anchor.start, end: anchor.end, ...insertion }]);
|
|
319
|
+
};
|
|
320
|
+
let line = 0;
|
|
321
|
+
for (let i = 0; i < items.length; i++) {
|
|
322
|
+
while (line < plan.lines.length - 1 && i > plan.lines[line].index) line++;
|
|
323
|
+
const current = plan.lines[line], item = items[i], last = line === plan.lines.length - 1;
|
|
324
|
+
if (item.type === "glue" && item.anchor) {
|
|
325
|
+
const boundary = i <= current.start || i === current.index;
|
|
326
|
+
const lineIndex = line;
|
|
327
|
+
const measure = (next) => {
|
|
328
|
+
const ratio = next.lines[lineIndex].ratio;
|
|
329
|
+
return boundary ? 0 : Math.max(0, item.width + ratio * (ratio < 0 ? item.shrink : item.stretch));
|
|
330
|
+
};
|
|
331
|
+
const width = measure(plan);
|
|
332
|
+
const spacing = !boundary && item.width > 0 && item.anchor.end > item.anchor.start ? (item.anchor.wordSpacing ?? 0) + width - item.width : void 0;
|
|
333
|
+
if (width || item.anchor.end !== item.anchor.start || i === current.index || item.stretch) add(item.anchor, { width, spacing, measure: spacing === void 0 ? measure : (next) => (item.anchor.wordSpacing ?? 0) + measure(next) - item.width, break: !last && i === current.index });
|
|
334
|
+
} else if (item.type === "penalty" && i === current.index && !last && !item.anchor?.existingBreak) add(item.anchor, { break: true, hyphen: !!item.width });
|
|
335
|
+
}
|
|
336
|
+
const originals = [];
|
|
337
|
+
for (const [node, changes] of insertions) {
|
|
338
|
+
const old = saved.get(node), value = old?.value ?? node.data, fragment = document.createDocumentFragment();
|
|
339
|
+
let at = 0, group = [];
|
|
340
|
+
const flush2 = (end) => {
|
|
341
|
+
const regular = group.find((change) => change.spacing !== void 0), spacing = regular?.spacing;
|
|
342
|
+
const append = (end2) => {
|
|
343
|
+
if (end2 <= at) return;
|
|
344
|
+
const text = document.createTextNode(value.slice(at, end2));
|
|
345
|
+
if (spacing !== void 0 && /\s/.test(text.data)) {
|
|
346
|
+
const run = document.createElement("span");
|
|
347
|
+
run.dataset.limrKpRun = "";
|
|
348
|
+
run.style.wordSpacing = `${spacing}px`;
|
|
349
|
+
run.append(text);
|
|
350
|
+
fragment.append(run);
|
|
351
|
+
patches.push((next) => {
|
|
352
|
+
run.style.wordSpacing = `${regular.measure(next)}px`;
|
|
353
|
+
});
|
|
354
|
+
} else fragment.append(text);
|
|
355
|
+
at = end2;
|
|
356
|
+
};
|
|
357
|
+
for (const change of group) {
|
|
358
|
+
if (change.spacing !== void 0 && change.spacing === spacing) continue;
|
|
359
|
+
append(change.start);
|
|
360
|
+
if (change.width !== void 0) {
|
|
361
|
+
const glue = document.createElement("span");
|
|
362
|
+
glue.className = "limr-kp-glue";
|
|
363
|
+
glue.style.width = `${change.width}px`;
|
|
364
|
+
glue.textContent = value.slice(change.start, change.end);
|
|
365
|
+
fragment.append(glue);
|
|
366
|
+
if (change.measure) patches.push((next) => {
|
|
367
|
+
glue.style.width = `${change.measure(next)}px`;
|
|
368
|
+
});
|
|
369
|
+
}
|
|
370
|
+
if (change.hyphen) {
|
|
371
|
+
const hyphen = document.createElement("span");
|
|
372
|
+
hyphen.className = "limr-kp-hyphen";
|
|
373
|
+
hyphen.dataset.limrIgnore = "true";
|
|
374
|
+
hyphen.setAttribute("aria-hidden", "true");
|
|
375
|
+
fragment.append(hyphen);
|
|
376
|
+
}
|
|
377
|
+
if (change.break) {
|
|
378
|
+
const br = document.createElement("br");
|
|
379
|
+
br.dataset.limrIgnore = "true";
|
|
380
|
+
fragment.append(br);
|
|
381
|
+
}
|
|
382
|
+
at = change.end;
|
|
383
|
+
}
|
|
384
|
+
append(end);
|
|
385
|
+
group = [];
|
|
386
|
+
};
|
|
387
|
+
for (const change of changes.sort((a, b) => a.start - b.start)) {
|
|
388
|
+
group.push(change);
|
|
389
|
+
if (change.break) flush2(change.end);
|
|
390
|
+
}
|
|
391
|
+
flush2(value.length);
|
|
392
|
+
const shell = old?.shell ?? document.createElement("span");
|
|
393
|
+
shell.dataset.limrKpText = "";
|
|
394
|
+
shell.replaceChildren(fragment);
|
|
395
|
+
if (!old) {
|
|
396
|
+
node.data = "";
|
|
397
|
+
node.after(shell);
|
|
398
|
+
}
|
|
399
|
+
originals.push({ node, value, shell });
|
|
400
|
+
saved.delete(node);
|
|
401
|
+
}
|
|
402
|
+
for (const { node, value, shell } of saved.values()) {
|
|
403
|
+
node.data = value;
|
|
404
|
+
shell.remove();
|
|
405
|
+
}
|
|
406
|
+
element.dataset.limrKp = plan.pass;
|
|
407
|
+
element.dataset.limrKpLines = String(plan.lines.length);
|
|
408
|
+
const undo = (changed) => {
|
|
409
|
+
const selection = element.ownerDocument.getSelection();
|
|
410
|
+
const position = (node, offset) => {
|
|
411
|
+
if (!node || !element.contains(node)) return;
|
|
412
|
+
const range = measurementRange(element.ownerDocument);
|
|
413
|
+
range.selectNodeContents(element);
|
|
414
|
+
range.setEnd(node, offset);
|
|
415
|
+
return range.toString().length;
|
|
416
|
+
};
|
|
417
|
+
const anchor = selection?.anchorNode, focus = selection?.focusNode, anchorOffset = selection?.anchorOffset ?? 0, focusOffset = selection?.focusOffset ?? 0;
|
|
418
|
+
const from = position(anchor ?? null, anchorOffset), to = position(focus ?? null, focusOffset);
|
|
419
|
+
for (const { node, value, shell } of originals) {
|
|
420
|
+
if (!changed?.has(node)) node.data = value;
|
|
421
|
+
shell.remove();
|
|
422
|
+
}
|
|
423
|
+
delete element.dataset.limrKp;
|
|
424
|
+
delete element.dataset.limrKpLines;
|
|
425
|
+
delete element.dataset.limrKpStale;
|
|
426
|
+
if (selection && (from !== void 0 || to !== void 0)) {
|
|
427
|
+
const locate = (offset) => {
|
|
428
|
+
const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT);
|
|
429
|
+
let tail;
|
|
430
|
+
for (let text = walker.nextNode(); text; text = walker.nextNode()) {
|
|
431
|
+
tail = text;
|
|
432
|
+
if (offset <= text.length) return [text, offset];
|
|
433
|
+
offset -= text.length;
|
|
434
|
+
}
|
|
435
|
+
return tail ? [tail, tail.length] : [element, 0];
|
|
436
|
+
};
|
|
437
|
+
const start = from === void 0 ? [anchor, anchorOffset] : locate(from), end = to === void 0 ? [focus, focusOffset] : locate(to);
|
|
438
|
+
if (start[0]?.isConnected && end[0]?.isConnected) selection.setBaseAndExtent(start[0], start[1], end[0], end[1]);
|
|
439
|
+
}
|
|
440
|
+
};
|
|
441
|
+
return { undo, update(next) {
|
|
442
|
+
for (const patch of patches) patch(next);
|
|
443
|
+
element.dataset.limrKp = next.pass;
|
|
444
|
+
}, reflow: (next) => apply(element, items, next, originals) };
|
|
445
|
+
}
|
|
446
|
+
export {
|
|
447
|
+
typeset
|
|
448
|
+
};
|
|
449
|
+
//# sourceMappingURL=knuth-plass-layout-CHQCWKB5.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/react/knuth-plass-layout.ts"],"sourcesContent":["/// <reference path=\"../vendor.d.ts\" />\nimport LineBreaker from 'linebreak';\nimport Hypher from 'hypher';\nimport patterns from 'hyphenation.en-us';\nimport { prepareKnuthPlass, type KnuthPlassOptions, type LineItem, type ParagraphLayout } from '../core/knuth-plass';\nimport { LruCache } from '../core/cache';\nimport type { ReaderRuntime } from './runtime';\nimport { measurementRange } from './source-geometry';\n\nconst hypher = new Hypher(patterns), wordWidths = new LruCache<string, number>(8192), hyphens = new LruCache<string, readonly string[]>(2048);\nconst plans = new LruCache<string, ParagraphLayout>(256);\nlet canvas: CanvasRenderingContext2D | null;\ninterface Segment { node: Text | Element; start: number; end: number; text: string }\ninterface Anchor { node: Text | Element; start: number; end: number; existingBreak?: boolean; wordSpacing?: number }\ntype Item = LineItem & { anchor?: Anchor };\ninterface Preparation { items: Item[]; signature: string; layout: ReturnType<typeof prepareKnuthPlass>; styles: Map<Element, string>; atomics: { element: Element; width: number }[] }\ninterface Job { prepared?: Preparation; plan?: ParagraphLayout; update?: (plan: ParagraphLayout) => void; reflow?: (plan: ParagraphLayout) => Application; element: HTMLElement; runtime: ReaderRuntime; options: KnuthPlassOptions; visible: boolean; dirty: boolean; undo?: (changed?: ReadonlySet<Node>) => void; width?: number; font?: string; observer: MutationObserver; disposed: boolean }\nconst jobs = new Map<HTMLElement, Job>(), queue = new Set<Job>();\nlet frame = 0, resize: ResizeObserver | undefined, intersection: IntersectionObserver | undefined;\nlet listening = false;\n\nfunction selected(element: HTMLElement) {\n const selection = element.ownerDocument.getSelection();\n return !!selection?.rangeCount && !selection.isCollapsed && selection.getRangeAt(0).intersectsNode(element);\n}\nfunction defer(job: Job) {\n const state = selected(job.element) ? 'wrap' : 'clip';\n if (job.element.dataset.limrKpStale !== state) job.element.dataset.limrKpStale = state;\n}\nfunction enqueue(job: Job) {\n if (job.disposed) return;\n job.dirty = true;\n if (!job.visible) return;\n queue.add(job);\n if (!frame) frame = requestAnimationFrame(flush);\n}\nfunction observe(job: Job) { job.observer.observe(job.element, { subtree: true, childList: true, characterData: true, attributes: true, attributeFilter: ['class', 'style', 'hidden'] }); }\nfunction restore(job: Job, changed?: ReadonlySet<Node>) {\n job.observer.disconnect(); job.undo?.(changed); job.undo = undefined; job.update = undefined; job.reflow = undefined; job.plan = undefined;\n}\nfunction flush() {\n frame = 0;\n const end = performance.now() + 6, writes: (() => void)[] = [];\n for (const job of queue) {\n queue.delete(job);\n if (job.disposed || !job.visible || selected(job.element)) continue;\n const animations = job.element.getAnimations({ subtree: true }).filter(animation => animation.playState === 'running' && animation.effect?.getTiming().iterations !== Infinity);\n if (animations.length) { void Promise.allSettled(animations.map(animation => animation.finished)).then(() => enqueue(job)); continue; }\n const apply = prepare(job);\n writes.push(() => {\n if (job.disposed) return;\n apply?.(); job.element.removeAttribute('data-limr-kp-stale'); job.dirty = false; observe(job); if (apply) job.runtime.requestLayout();\n });\n if (performance.now() >= end) break;\n }\n // Batch reads before writes so paragraph measurements share a layout pass.\n for (const write of writes) write();\n if (queue.size) frame = requestAnimationFrame(flush);\n}\nfunction initialize() {\n if (listening) return;\n listening = true;\n resize = new ResizeObserver(entries => {\n const narrower: Job[] = [];\n for (const entry of entries) {\n const job = jobs.get(entry.target as HTMLElement);\n if (job) {\n const font = fontKey(getComputedStyle(job.element));\n if (job.undo && entry.contentRect.width < (job.width ?? entry.contentRect.width) && (!job.visible || selected(job.element))) narrower.push(job);\n if (job.width !== entry.contentRect.width || font !== job.font) { job.width = entry.contentRect.width; job.font = font; enqueue(job); }\n }\n }\n // Keep cached/offscreen DOM and active native ranges intact on shrink. Clip\n // only stale horizontal paint offscreen; rewrapping every cached paragraph\n // would duplicate native layout before its exact plan is needed. Selected\n // paragraphs may wrap without changing their live Range's text nodes.\n // Visible unselected jobs already have priority in the next frame: avoid a\n // second native-wrap layout immediately before applying their exact plan.\n // Write after all font reads to avoid repeatedly flushing styles in the loop.\n for (const job of narrower) defer(job);\n });\n intersection = new IntersectionObserver(entries => {\n for (const entry of entries) {\n const job = jobs.get(entry.target as HTMLElement);\n if (!job) continue;\n job.visible = entry.isIntersecting;\n if (job.visible && (job.dirty || !job.undo)) enqueue(job);\n // Earlier paragraphs can change height before this job runs, moving it\n // out of the queue's visible region after ResizeObserver saw it inside.\n else if (!job.visible && job.dirty && job.undo) defer(job);\n }\n }, { rootMargin: '600px' });\n document.addEventListener('selectionchange', selectionChanged);\n document.fonts.addEventListener('loadingdone', fontsChanged);\n}\nfunction selectionChanged() { for (const job of jobs.values()) if ((job.dirty || !job.undo) && !selected(job.element)) enqueue(job); }\nfunction fontsChanged() { wordWidths.clear(); plans.clear(); for (const job of jobs.values()) { job.prepared = undefined; enqueue(job); } }\n\n/** Registers stable paragraphs only. Original nodes are restored before React\n * commits an update, keeping source bindings, controls and React ownership. */\nexport function typeset(root: HTMLElement, runtime: ReaderRuntime, options: KnuthPlassOptions = {}): () => void {\n initialize();\n const elements = [root, ...root.querySelectorAll<HTMLElement>('p,.limr-paragraph,li')].filter(element => element.matches('p,.limr-paragraph,li') && !element.closest('pre,[data-limr-ignore]') && !element.querySelector('p,ul,ol,blockquote,aside,[data-limr-atomic=\"block\"]'));\n const owned: Job[] = [];\n for (const element of elements) {\n if (jobs.has(element)) continue;\n const job: Job = { element, runtime, options, visible: false, dirty: true, disposed: false, observer: new MutationObserver(records => {\n // Highlight paint is out of flow and does not change typography. Including\n // it creates a reflow -> paint -> reflow loop, especially while scrolling.\n const relevant = records.filter(record => {\n const target = record.target instanceof Element ? record.target : record.target.parentElement;\n if (target?.closest('.limr-highlight-layer,.limr-paint-layer')) return false;\n return record.type !== 'childList' || ![...record.addedNodes, ...record.removedNodes].every(node => node instanceof Element && node.matches('.limr-highlight-layer,.limr-paint-layer'));\n });\n if (!relevant.length) return;\n job.prepared = undefined;\n restore(job, new Set(relevant.filter(record => record.type === 'characterData').map(record => record.target)));\n observe(job); enqueue(job);\n }) };\n owned.push(job); jobs.set(element, job); resize!.observe(element); intersection!.observe(element); observe(job);\n }\n return () => {\n for (const job of owned) { job.disposed = true; queue.delete(job); restore(job); resize!.unobserve(job.element); intersection!.unobserve(job.element); jobs.delete(job.element); }\n if (!jobs.size) {\n resize?.disconnect(); intersection?.disconnect(); cancelAnimationFrame(frame); frame = 0;\n document.removeEventListener('selectionchange', selectionChanged); document.fonts.removeEventListener('loadingdone', fontsChanged); listening = false;\n }\n };\n}\n\nfunction collect(element: HTMLElement): Segment[] {\n const segments: Segment[] = []; let offset = 0;\n function visit(node: Node) {\n if (node instanceof Text) {\n const text = node.data; if (text) { segments.push({ node, start: offset, end: offset + text.length, text }); offset += text.length; }\n } else if (node instanceof Element) {\n const style = getComputedStyle(node);\n if (node.hasAttribute('hidden') || node.matches('.limr-highlight-layer,.limr-paint-layer') || style.display === 'none' || style.position === 'absolute' || style.position === 'fixed') return;\n if (node.tagName === 'BR' || node.matches('[data-limr-atomic], [data-limr-ignore], code, img, svg, button, input')) {\n segments.push({ node, start: offset, end: ++offset, text: node.tagName === 'BR' ? '\\u2028' : '\\ufffc' });\n } else node.childNodes.forEach(visit);\n }\n }\n element.childNodes.forEach(visit);\n return segments;\n}\nfunction fontKey(style: CSSStyleDeclaration) {\n // The font shorthand may be empty with explicit kerning/variant settings.\n return [style.fontFamily, style.fontSize, style.fontWeight, style.fontStyle, style.fontStretch, style.fontVariantLigatures, style.fontFeatureSettings, style.fontVariationSettings, style.letterSpacing, style.wordSpacing, style.textTransform, style.fontKerning, style.getPropertyValue('text-spacing-trim')].join('|');\n}\nfunction itemize(element: HTMLElement, options: KnuthPlassOptions): Preparation | undefined {\n const segments = collect(element), text = segments.map(segment => segment.text).join('');\n const segmentStarts = new Map(segments.map(segment => [segment.start, segment]));\n if (!text.trim()) return;\n const breaks = new Map<number, { required?: boolean; hyphen?: boolean; automatic?: boolean }>();\n const breaker = new LineBreaker(text);\n for (let next = breaker.nextBreak(); next; next = breaker.nextBreak()) if (next.position < text.length) breaks.set(next.position, { required: next.required });\n if (options.hyphenate !== false) for (const word of text.matchAll(/[a-zA-Z]{5,}/g)) {\n let pieces = options.hyphenate ? options.hyphenate(word[0]) : hyphens.get(word[0]);\n if (!pieces) { pieces = hypher.hyphenate(word[0]); hyphens.set(word[0], pieces); }\n if (pieces.join('') !== word[0]) continue;\n let at = word.index!;\n for (const piece of pieces.slice(0, -1)) { at += piece.length; if (!breaks.has(at)) breaks.set(at, { hyphen: true, automatic: true }); }\n }\n const atomics: Preparation['atomics'] = [];\n const items: Item[] = [], styleCache = new Map<Element, { key: string; space: number; hyphen: number; em: number; wordSpacing: number }>();\n const range = measurementRange(element.ownerDocument);\n function metrics(parent: Element) {\n let found = styleCache.get(parent); if (found) return found;\n const style = getComputedStyle(parent), font = style.font || `${style.fontStyle} ${style.fontWeight} ${style.fontSize} ${style.fontFamily}`;\n canvas ??= document.createElement('canvas').getContext('2d');\n canvas!.font = font;\n const spacing = parseFloat(style.letterSpacing) || 0;\n const wordSpacing = parseFloat(style.wordSpacing) || 0;\n found = { key: fontKey(style), space: canvas!.measureText(' ').width + spacing + wordSpacing, hyphen: canvas!.measureText('-').width + spacing, em: parseFloat(style.fontSize), wordSpacing };\n styleCache.set(parent, found); return found;\n }\n function measure(node: Text, from: number, to: number, key: string) {\n const text = node.data.slice(from, to), cacheKey = `${key}\\0${text}`;\n const cached = wordWidths.get(cacheKey); if (cached !== undefined) return cached;\n range.setStart(node, from); range.setEnd(node, to);\n const measured = [...range.getClientRects()].reduce((sum, rect) => sum + rect.width, 0);\n wordWidths.set(cacheKey, measured); return measured;\n }\n for (const segment of segments) {\n const { node } = segment;\n if (!(node instanceof Text)) {\n if (node.tagName === 'BR') items.push({ type: 'glue', width: 0, stretch: 1, shrink: 0, infinite: true }, { type: 'penalty', width: 0, penalty: -10000, anchor: { node, start: 0, end: 0, existingBreak: true } });\n else { const width = node.getBoundingClientRect().width; items.push({ type: 'box', width }); atomics.push({ element: node, width }); }\n continue;\n }\n const style = metrics(node.parentElement!);\n const points = new Set([0, segment.text.length]);\n for (const at of breaks.keys()) if (at > segment.start && at <= segment.end) points.add(at - segment.start);\n for (const space of segment.text.matchAll(/[ \\t\\r\\n\\f]+/g)) { points.add(space.index!); points.add(space.index! + space[0].length); }\n const sorted = [...points].sort((a, b) => a - b);\n for (let i = 1; i < sorted.length; i++) {\n const start = sorted[i - 1], end = sorted[i], value = segment.text.slice(start, end);\n const anchor = { node, start, end, wordSpacing: style.wordSpacing };\n if (/^[ \\t\\r\\n\\f]+$/.test(value)) {\n const preceding = items.at(-1);\n const space = preceding?.type === 'glue' ? 0 : style.space;\n items.push({ type: 'glue', width: space, stretch: space / 2, shrink: space / 3, anchor });\n } else {\n items.push({ type: 'box', width: measure(node, start, end, style.key) });\n const point = segment.start + end, opportunity = breaks.get(point);\n // An annotation marker belongs to the preceding word/atomic object.\n const next = segmentStarts.get(point);\n if (opportunity && !(next?.node instanceof Element && next.node.hasAttribute('data-limr-ignore'))) {\n const at = { node, start: end, end };\n if (opportunity.hyphen) items.push({ type: 'penalty', width: style.hyphen, penalty: options.hyphenPenalty ?? 50, flagged: true, automatic: opportunity.automatic, anchor: at });\n else if (opportunity.required) items.push({ type: 'glue', width: 0, stretch: 1, shrink: 0, infinite: true }, { type: 'penalty', width: 0, penalty: -10000, anchor: at });\n else if (!/[ \\t\\r\\n\\f]/.test(text[point] ?? '')) items.push({ type: 'glue', width: 0, stretch: style.em * .15, shrink: 0, anchor: at });\n }\n }\n }\n }\n items.push({ type: 'penalty', width: 0, penalty: 10000 }, { type: 'glue', width: 0, stretch: 1, shrink: 0, infinite: true }, { type: 'penalty', width: 0, penalty: -10000 });\n return { items, atomics, layout: prepareKnuthPlass(items), styles: new Map([...styleCache].map(([element, style]) => [element, style.key])), signature: JSON.stringify([options, items.map(({ anchor: _anchor, ...item }) => item)]) };\n}\nfunction prepare(job: Job): (() => void) | undefined {\n const { element, options } = job, base = getComputedStyle(element);\n const width = element.clientWidth - parseFloat(base.paddingLeft) - parseFloat(base.paddingRight);\n if (width <= 0) return;\n if (job.prepared && ([...job.prepared.styles].some(([element, key]) => !element.isConnected || fontKey(getComputedStyle(element)) !== key) || job.prepared.atomics.some(({ element, width }) => element.getBoundingClientRect().width !== width))) job.prepared = undefined;\n if (!job.prepared) { restore(job); job.prepared = itemize(element, options); }\n const prepared = job.prepared; if (!prepared) return;\n const { items } = prepared;\n const indent = (parseFloat(base.textIndent) || 0) * (base.textIndent.endsWith('%') ? width / 100 : 1);\n const lengths = indent ? [width - indent, width] : width;\n // Browser prose contains non-breaking controls and mixed font runs. Allow a\n // TeX emergency stretch of three em before its artificial overfull fallback;\n // it influences break scoring only, never the visible glue calculation.\n const emergencyStretch = options.emergencyStretch ?? parseFloat(base.fontSize) * 3;\n const signature = `${width}:${indent}:${emergencyStretch}:${prepared.signature}`;\n let plan = plans.get(signature);\n if (!plan) { plan = prepared.layout(lengths, { ...options, emergencyStretch }); plans.set(signature, plan); }\n if (!plan.lines.length) return;\n if (job.plan?.lines.length === plan.lines.length && job.plan.lines.every((line, index) => line.index === plan!.lines[index].index && line.ratio === plan!.lines[index].ratio)) return;\n if (job.update && job.plan?.lines.length === plan.lines.length && job.plan.lines.every((line, index) => line.index === plan!.lines[index].index)) {\n // A width change often changes glue without changing any break. Keep text,\n // ranges and paint bindings in place and only update the actual glue widths.\n return () => { job.observer.disconnect(); job.update!(plan!); job.plan = plan; };\n }\n return () => {\n job.observer.disconnect();\n const applied = job.reflow ? job.reflow(plan!) : apply(element, items, plan!);\n job.undo = applied.undo; job.update = applied.update; job.reflow = applied.reflow; job.plan = plan;\n };\n}\n\ninterface Insertion { start: number; end: number; width?: number; spacing?: number; measure?: (plan: ParagraphLayout) => number; break?: boolean; hyphen?: boolean }\ninterface Original { node: Text; value: string; shell: HTMLSpanElement }\ninterface Application { undo: (changed?: ReadonlySet<Node>) => void; update: (plan: ParagraphLayout) => void; reflow: (plan: ParagraphLayout) => Application }\nfunction apply(element: HTMLElement, items: Item[], plan: ParagraphLayout, previous: Original[] = []): Application {\n const saved = new Map(previous.map(original => [original.node, original]));\n const insertions = new Map<Text, Insertion[]>();\n const patches: ((plan: ParagraphLayout) => void)[] = [];\n const add = (anchor: Anchor | undefined, insertion: Omit<Insertion, 'start' | 'end'>) => {\n if (anchor?.node instanceof Text) insertions.set(anchor.node, [...insertions.get(anchor.node) ?? [], { start: anchor.start, end: anchor.end, ...insertion }]);\n };\n let line = 0;\n for (let i = 0; i < items.length; i++) {\n while (line < plan.lines.length - 1 && i > plan.lines[line].index) line++;\n const current = plan.lines[line], item = items[i], last = line === plan.lines.length - 1;\n if (item.type === 'glue' && item.anchor) {\n const boundary = i <= current.start || i === current.index;\n const lineIndex = line;\n const measure = (next: ParagraphLayout) => {\n const ratio = next.lines[lineIndex].ratio;\n return boundary ? 0 : Math.max(0, item.width + ratio * (ratio < 0 ? item.shrink : item.stretch));\n };\n const width = measure(plan);\n const spacing = !boundary && item.width > 0 && item.anchor.end > item.anchor.start ? (item.anchor.wordSpacing ?? 0) + width - item.width : undefined;\n if (width || item.anchor.end !== item.anchor.start || i === current.index || item.stretch) add(item.anchor, { width, spacing, measure: spacing === undefined ? measure : next => (item.anchor!.wordSpacing ?? 0) + measure(next) - item.width, break: !last && i === current.index });\n } else if (item.type === 'penalty' && i === current.index && !last && !item.anchor?.existingBreak) add(item.anchor, { break: true, hyphen: !!item.width });\n }\n const originals: Original[] = [];\n for (const [node, changes] of insertions) {\n const old = saved.get(node), value = old?.value ?? node.data, fragment = document.createDocumentFragment();\n let at = 0, group: Insertion[] = [];\n const flush = (end: number) => {\n const regular = group.find(change => change.spacing !== undefined), spacing = regular?.spacing;\n const append = (end: number) => {\n if (end <= at) return;\n const text = document.createTextNode(value.slice(at, end));\n // One word-spacing run per line has exactly the same TeX glue widths as\n // a span per space. It greatly reduces DOM, range and paint work without\n // changing the computed breaks, shaping or original source characters.\n if (spacing !== undefined && /\\s/.test(text.data)) {\n const run = document.createElement('span'); run.dataset.limrKpRun = ''; run.style.wordSpacing = `${spacing}px`; run.append(text); fragment.append(run);\n patches.push(next => { run.style.wordSpacing = `${regular!.measure!(next)}px`; });\n } else fragment.append(text);\n at = end;\n };\n for (const change of group) {\n if (change.spacing !== undefined && change.spacing === spacing) continue;\n append(change.start);\n if (change.width !== undefined) {\n const glue = document.createElement('span'); glue.className = 'limr-kp-glue'; glue.style.width = `${change.width}px`; glue.textContent = value.slice(change.start, change.end); fragment.append(glue);\n if (change.measure) patches.push(next => { glue.style.width = `${change.measure!(next)}px`; });\n }\n if (change.hyphen) { const hyphen = document.createElement('span'); hyphen.className = 'limr-kp-hyphen'; hyphen.dataset.limrIgnore = 'true'; hyphen.setAttribute('aria-hidden', 'true'); fragment.append(hyphen); }\n if (change.break) { const br = document.createElement('br'); br.dataset.limrIgnore = 'true'; fragment.append(br); }\n at = change.end;\n }\n append(end); group = [];\n };\n for (const change of changes.sort((a, b) => a.start - b.start)) { group.push(change); if (change.break) flush(change.end); }\n flush(value.length);\n const shell = old?.shell ?? document.createElement('span'); shell.dataset.limrKpText = '';\n shell.replaceChildren(fragment);\n // Keep React's original Text node at its exact parent/index for restoration.\n // One disposable root per original text also makes resize restoration one\n // subtree removal, not hundreds of live-Range updates for individual nodes.\n if (!old) { node.data = ''; node.after(shell); }\n originals.push({ node, value, shell }); saved.delete(node);\n }\n for (const { node, value, shell } of saved.values()) { node.data = value; shell.remove(); }\n element.dataset.limrKp = plan.pass;\n element.dataset.limrKpLines = String(plan.lines.length);\n const undo = (changed?: ReadonlySet<Node>) => {\n const selection = element.ownerDocument.getSelection();\n const position = (node: Node | null, offset: number) => {\n if (!node || !element.contains(node)) return;\n const range = measurementRange(element.ownerDocument); range.selectNodeContents(element); range.setEnd(node, offset); return range.toString().length;\n };\n const anchor = selection?.anchorNode, focus = selection?.focusNode, anchorOffset = selection?.anchorOffset ?? 0, focusOffset = selection?.focusOffset ?? 0;\n const from = position(anchor ?? null, anchorOffset), to = position(focus ?? null, focusOffset);\n for (const { node, value, shell } of originals) { if (!changed?.has(node)) node.data = value; shell.remove(); }\n delete element.dataset.limrKp; delete element.dataset.limrKpLines; delete element.dataset.limrKpStale;\n if (selection && (from !== undefined || to !== undefined)) {\n const locate = (offset: number): [Node, number] => {\n const walker = document.createTreeWalker(element, NodeFilter.SHOW_TEXT); let tail: Text | undefined;\n for (let text = walker.nextNode() as Text | null; text; text = walker.nextNode() as Text | null) { tail = text; if (offset <= text.length) return [text, offset]; offset -= text.length; }\n return tail ? [tail, tail.length] : [element, 0];\n };\n const start = from === undefined ? [anchor!, anchorOffset] as const : locate(from), end = to === undefined ? [focus!, focusOffset] as const : locate(to);\n if (start[0]?.isConnected && end[0]?.isConnected) selection.setBaseAndExtent(start[0], start[1], end[0], end[1]);\n }\n };\n return { undo, update(next: ParagraphLayout) { for (const patch of patches) patch(next); element.dataset.limrKp = next.pass; }, reflow: next => apply(element, items, next, originals) };\n}\n"],"mappings":"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","names":["apply","text","element","width","flush","end"]}
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { L as LiMRLocale, h as DocumentProviderProps,
|
|
2
|
-
export { a as AnnotationContentProps, b as AnnotationExpansion, e as AnnotationSidebarPreviewProps, f as AnnotationType, D as DocumentCommands, g as DocumentProvider, M as Markdown, i as MarkdownProps, N as NodeRenderer, j as NodeRendererProps, R as RendererExtension, k as RendererParameters, T as TextToken,
|
|
1
|
+
import { L as LiMRLocale, h as DocumentProviderProps, n as StyledProps, S as SelectionAction, c as AnnotationOverlayCardProps, d as AnnotationPresentation, A as ActionContext } from '../translations-BXzSwLBJ.js';
|
|
2
|
+
export { a as AnnotationContentProps, b as AnnotationExpansion, e as AnnotationSidebarPreviewProps, f as AnnotationType, D as DocumentCommands, g as DocumentProvider, M as Markdown, i as MarkdownProps, N as NodeRenderer, j as NodeRendererProps, R as RendererExtension, k as RendererOverride, l as RendererParameters, m as StreamEffect, T as TextToken, o as ToolbarActionContext, r as TypographyMode, V as ViewConfiguration, u as useAnchor, s as useAnnotation, v as useAnnotationState, w as useAnnotations, x as useDocument, y as useDocumentSelector, z as useLiMR, B as useLocale, C as useRendererParameter, E as useSelection } from '../translations-BXzSwLBJ.js';
|
|
3
3
|
import * as react from 'react';
|
|
4
4
|
import { ReactNode, SVGProps, ButtonHTMLAttributes } from 'react';
|
|
5
|
-
import { b as AnnotationOccurrence } from '../
|
|
5
|
+
import { b as AnnotationOccurrence } from '../knuth-plass-C8mgFm7W.js';
|
|
6
|
+
export { K as KnuthPlassOptions } from '../knuth-plass-C8mgFm7W.js';
|
|
6
7
|
import 'micromark-util-types';
|
|
7
8
|
import 'mdast-util-from-markdown';
|
|
8
9
|
|
|
@@ -29,7 +30,7 @@ interface TableOfContentsProps extends StyledProps {
|
|
|
29
30
|
}
|
|
30
31
|
declare function TableOfContents({ title, maxDepth, followActive, topInset, updateHash, className, style }: TableOfContentsProps): react.JSX.Element;
|
|
31
32
|
|
|
32
|
-
/** anchorTop is the first
|
|
33
|
+
/** anchorTop is the first referenced text line, falling back to the marker. */
|
|
33
34
|
interface SidebarItem {
|
|
34
35
|
id: string;
|
|
35
36
|
anchorTop: number;
|
|
@@ -39,6 +40,7 @@ type SidebarPositioner = (items: readonly SidebarItem[], context: {
|
|
|
39
40
|
activeId: string | null;
|
|
40
41
|
gap: number;
|
|
41
42
|
height?: number;
|
|
43
|
+
prioritizeActive?: boolean;
|
|
42
44
|
}) => ReadonlyMap<string, number>;
|
|
43
45
|
declare const alignSidebar: SidebarPositioner;
|
|
44
46
|
interface AnnotationSidebarProps extends StyledProps {
|
|
@@ -96,7 +98,7 @@ interface SelectionToolbarProps extends StyledProps {
|
|
|
96
98
|
}
|
|
97
99
|
declare function SelectionToolbar({ actions, portalRoot, maxPanelHeight, className, style, render }: SelectionToolbarProps): react.JSX.Element | null;
|
|
98
100
|
|
|
99
|
-
type ToolIconName = 'eye' | 'eye-off' | 'question' | 'highlight' | 'edit' | 'close' | 'copy' | 'background' | 'underline' | 'dotted' | 'wavy' | 'chevron' | 'check' | 'trash' | 'note' | 'footnote' | 'comment' | 'sparkles';
|
|
101
|
+
type ToolIconName = 'eye' | 'eye-off' | 'question' | 'highlight' | 'edit' | 'close' | 'copy' | 'background' | 'underline' | 'dotted' | 'wavy' | 'chevron' | 'check' | 'trash' | 'note' | 'footnote' | 'comment' | 'sparkles' | 'zoom-in' | 'zoom-out' | 'source' | 'image';
|
|
100
102
|
/** A shared optical grid for the built-in tools and example plugins. */
|
|
101
103
|
declare function ToolIcon({ name, ...props }: SVGProps<SVGSVGElement> & {
|
|
102
104
|
name: ToolIconName;
|
package/dist/react/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
SelectionToolbar,
|
|
8
8
|
TableOfContents,
|
|
9
9
|
alignSidebar
|
|
10
|
-
} from "../chunk-
|
|
10
|
+
} from "../chunk-GU2RPESF.js";
|
|
11
11
|
import {
|
|
12
12
|
AnnotationCard,
|
|
13
13
|
DocumentProvider,
|
|
@@ -23,10 +23,13 @@ import {
|
|
|
23
23
|
useDocument,
|
|
24
24
|
useDocumentSelector,
|
|
25
25
|
useLiMR,
|
|
26
|
+
useLocale,
|
|
26
27
|
useRendererParameter,
|
|
27
28
|
useSelection
|
|
28
|
-
} from "../chunk-
|
|
29
|
-
import "../chunk-
|
|
29
|
+
} from "../chunk-SUAAUGAX.js";
|
|
30
|
+
import "../chunk-BG5QUQFR.js";
|
|
31
|
+
import "../chunk-BVHHOVMT.js";
|
|
32
|
+
import "../chunk-FJZCQY2S.js";
|
|
30
33
|
import "../chunk-6N6TFHEN.js";
|
|
31
34
|
export {
|
|
32
35
|
AnnotationCard,
|
|
@@ -51,6 +54,7 @@ export {
|
|
|
51
54
|
useDocument,
|
|
52
55
|
useDocumentSelector,
|
|
53
56
|
useLiMR,
|
|
57
|
+
useLocale,
|
|
54
58
|
useRendererParameter,
|
|
55
59
|
useSelection
|
|
56
60
|
};
|