@hwp-editor/react 1.4.0 → 1.4.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/dist/index.cjs +203 -141
- package/dist/index.cjs.map +1 -1
- package/dist/index.css +3 -0
- package/dist/index.css.map +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +82 -20
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -58,7 +58,7 @@ module.exports = __toCommonJS(index_exports);
|
|
|
58
58
|
|
|
59
59
|
// src/HwpEditor.tsx
|
|
60
60
|
var import_react13 = require("react");
|
|
61
|
-
var
|
|
61
|
+
var import_core20 = require("@hwp-editor/core");
|
|
62
62
|
|
|
63
63
|
// src/context.ts
|
|
64
64
|
var import_react = require("react");
|
|
@@ -75,7 +75,7 @@ function useHwpEditorContext() {
|
|
|
75
75
|
|
|
76
76
|
// src/PageCanvas.tsx
|
|
77
77
|
var import_react2 = require("react");
|
|
78
|
-
var
|
|
78
|
+
var import_core3 = require("@hwp-editor/core");
|
|
79
79
|
|
|
80
80
|
// src/geometry.ts
|
|
81
81
|
var import_core = require("@hwp-editor/core");
|
|
@@ -130,21 +130,46 @@ function idIndex(envelope) {
|
|
|
130
130
|
idIndexes.set(envelope, index);
|
|
131
131
|
return index;
|
|
132
132
|
}
|
|
133
|
+
var pathIndexes = /* @__PURE__ */ new WeakMap();
|
|
134
|
+
function pathIndex(envelope) {
|
|
135
|
+
const cached = pathIndexes.get(envelope);
|
|
136
|
+
if (cached !== void 0) return cached;
|
|
137
|
+
const index = /* @__PURE__ */ new Map();
|
|
138
|
+
for (const segment of envelope.segments) {
|
|
139
|
+
if (segment.id !== void 0 || segment.kind !== "para") continue;
|
|
140
|
+
const key = [segment.section, ...segment.indices ?? [segment.para]].join(".");
|
|
141
|
+
if (!index.has(key)) index.set(key, segment);
|
|
142
|
+
}
|
|
143
|
+
pathIndexes.set(envelope, index);
|
|
144
|
+
return index;
|
|
145
|
+
}
|
|
146
|
+
function rowSegment(envelope, rowId) {
|
|
147
|
+
const byId = idIndex(envelope).get(rowId);
|
|
148
|
+
if (byId !== void 0) return byId;
|
|
149
|
+
const path = (0, import_core.segmentIdPath)(rowId);
|
|
150
|
+
return path.length === 0 ? void 0 : pathIndex(envelope).get(path.join("."));
|
|
151
|
+
}
|
|
152
|
+
function hasIds(envelope) {
|
|
153
|
+
return envelope.segments.some((segment) => segment.id !== void 0);
|
|
154
|
+
}
|
|
155
|
+
function rowDraws(envelope, rowId, segment) {
|
|
156
|
+
if (segment.id !== void 0) return rowId === segment.id;
|
|
157
|
+
return rowSegment(envelope, rowId) === segment;
|
|
158
|
+
}
|
|
133
159
|
function segmentOnPage(envelope, page, xFraction, yFraction, pageIndex, pageCount) {
|
|
134
|
-
if (page.layout === void 0 || !envelope.
|
|
160
|
+
if (page.layout === void 0 || !hasIds(envelope) && page.layout.rows.every((row) => rowSegment(envelope, row.id) === void 0)) {
|
|
135
161
|
return nearestSegment(envelope, pageIndex, yFraction, pageCount);
|
|
136
162
|
}
|
|
137
163
|
const { width_pt, height_pt, rows } = page.layout;
|
|
138
164
|
const x = clamp(xFraction, 0, 1) * width_pt;
|
|
139
165
|
const y = clamp(yFraction, 0, 1) * height_pt;
|
|
140
|
-
const byId = idIndex(envelope);
|
|
141
166
|
let best;
|
|
142
167
|
let bestVertical = Infinity;
|
|
143
168
|
let bestHorizontal = Infinity;
|
|
144
169
|
let bestArea = Infinity;
|
|
145
170
|
for (const row of rows) {
|
|
146
171
|
const box = row.box;
|
|
147
|
-
const segment =
|
|
172
|
+
const segment = rowSegment(envelope, row.id);
|
|
148
173
|
if (box === null || segment === void 0) continue;
|
|
149
174
|
const dx = Math.max(box.x0 - x, 0, x - box.x1);
|
|
150
175
|
const dy = Math.max(box.y0 - y, 0, y - box.y1);
|
|
@@ -161,13 +186,13 @@ function segmentOnPage(envelope, page, xFraction, yFraction, pageIndex, pageCoun
|
|
|
161
186
|
return best;
|
|
162
187
|
}
|
|
163
188
|
function bandsOnPage(envelope, segment, page, pageIndex, pageCount) {
|
|
164
|
-
if (page.layout === void 0
|
|
189
|
+
if (page.layout === void 0) {
|
|
165
190
|
const band = segmentBand(envelope, segment, pageCount);
|
|
166
|
-
return band?.pageIndex === pageIndex ? [{ left: 0, top: band.top, width: 100, height: band.height }] : [];
|
|
191
|
+
return band?.pageIndex === pageIndex ? [{ left: 0, top: band.top, width: 100, height: band.height, approximate: true }] : [];
|
|
167
192
|
}
|
|
168
193
|
const target = ["run", "image", "field"].includes(segment.kind) && segment.indices !== void 0 ? envelope.segments.find((candidate) => candidate.kind === "para" && candidate.section === segment.section && candidate.indices !== void 0 && candidate.indices.length === segment.indices.length - 1 && candidate.indices.every((value, index) => value === segment.indices[index])) ?? segment : segment;
|
|
169
194
|
const { width_pt, height_pt, rows } = page.layout;
|
|
170
|
-
return rows.filter((row) => row.
|
|
195
|
+
return rows.filter((row) => row.box !== null && rowDraws(envelope, row.id, target)).map((row) => {
|
|
171
196
|
const box = row.box;
|
|
172
197
|
return {
|
|
173
198
|
left: box.x0 / width_pt * 100,
|
|
@@ -179,6 +204,7 @@ function bandsOnPage(envelope, segment, page, pageIndex, pageCount) {
|
|
|
179
204
|
}
|
|
180
205
|
|
|
181
206
|
// src/text.ts
|
|
207
|
+
var import_core2 = require("@hwp-editor/core");
|
|
182
208
|
function plainSegmentText(markdownSlice) {
|
|
183
209
|
return markdownSlice.split("\n").map(stripLine).join("\n").trim();
|
|
184
210
|
}
|
|
@@ -192,6 +218,41 @@ function stripLine(line) {
|
|
|
192
218
|
out = out.replace(/`([^`]*)`/g, "$1");
|
|
193
219
|
return out;
|
|
194
220
|
}
|
|
221
|
+
var LIST_MARKER = /^[ \t]*(?:\d{1,9}[.)]|[-*+])[ \t]+/;
|
|
222
|
+
function paragraphSourceText(envelope, para, pages = []) {
|
|
223
|
+
const plain = plainSegmentText((0, import_core2.segmentText)(envelope, para));
|
|
224
|
+
const marker = LIST_MARKER.exec(plain);
|
|
225
|
+
if (marker === null) return plain;
|
|
226
|
+
const stripped = plain.slice(marker[0].length);
|
|
227
|
+
if (para.indices !== void 0) {
|
|
228
|
+
const first = envelope.segments.find((candidate) => candidate.kind === "run" && candidate.section === para.section && candidate.indices !== void 0 && candidate.indices.length === para.indices.length + 1 && para.indices.every((value, index) => candidate.indices[index] === value));
|
|
229
|
+
if (first !== void 0) {
|
|
230
|
+
const lead = [...(0, import_core2.segmentText)(envelope, para)].slice(0, Math.max(0, first.start - para.start)).join("");
|
|
231
|
+
return LIST_MARKER.test(lead) && lead.trim() === marker[0].trim() ? stripped : plain;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
const length = sourceLength(para, pages);
|
|
235
|
+
if (length === void 0) return plain;
|
|
236
|
+
return stripped.length === length && plain.length !== length ? stripped : plain;
|
|
237
|
+
}
|
|
238
|
+
function sourceLength(para, pages) {
|
|
239
|
+
let start = Infinity;
|
|
240
|
+
let end = -Infinity;
|
|
241
|
+
for (const page of pages) {
|
|
242
|
+
for (const row of page.layout?.rows ?? []) {
|
|
243
|
+
if (row.kind !== "para" || row.source_chars === null || !rowMatches(row.id, para)) continue;
|
|
244
|
+
start = Math.min(start, row.source_chars.start);
|
|
245
|
+
end = Math.max(end, row.source_chars.end);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return end >= start ? end - start : void 0;
|
|
249
|
+
}
|
|
250
|
+
function rowMatches(rowId, segment) {
|
|
251
|
+
if (segment.id !== void 0) return rowId === segment.id;
|
|
252
|
+
const path = (0, import_core2.segmentIdPath)(rowId);
|
|
253
|
+
const own = [segment.section, ...segment.indices ?? [segment.para]];
|
|
254
|
+
return path.length === own.length && path.every((value, index) => value === own[index]);
|
|
255
|
+
}
|
|
195
256
|
|
|
196
257
|
// src/PageCanvas.tsx
|
|
197
258
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
@@ -206,11 +267,11 @@ function PageCanvas() {
|
|
|
206
267
|
if (envelope !== null) {
|
|
207
268
|
const refs = state.selections?.length ? state.selections : selection === null ? [] : [selection];
|
|
208
269
|
for (const ref of refs) {
|
|
209
|
-
const segment = (0,
|
|
270
|
+
const segment = (0, import_core3.segmentAtRef)(envelope, ref);
|
|
210
271
|
if (segment !== void 0) selectedSegments.add(segment);
|
|
211
272
|
}
|
|
212
273
|
}
|
|
213
|
-
if (pages.length === 0) {
|
|
274
|
+
if (pages.length === 0 || envelope === null) {
|
|
214
275
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hwped-canvas", role: "main", "aria-label": t("canvas.aria"), children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hwped-empty", children: t("canvas.emptyPages") }) });
|
|
215
276
|
}
|
|
216
277
|
const selectAt = (pageIndex, xFraction, yFraction, modifiers) => {
|
|
@@ -218,7 +279,7 @@ function PageCanvas() {
|
|
|
218
279
|
const segment = segmentOnPage(envelope, pages[pageIndex], xFraction, yFraction, pageIndex, pages.length);
|
|
219
280
|
if (segment !== void 0) {
|
|
220
281
|
const mode = modifiers?.shiftKey ? "extend" : modifiers?.metaKey || modifiers?.ctrlKey ? "toggle" : "single";
|
|
221
|
-
store.dispatch((0,
|
|
282
|
+
store.dispatch((0, import_core3.selectionAction)(envelope, store.getState(), segment, mode));
|
|
222
283
|
}
|
|
223
284
|
};
|
|
224
285
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "hwped-canvas", role: "main", "aria-label": t("canvas.aria"), children: pages.map((page, pageIndex) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -264,7 +325,7 @@ function bandsForPage(envelope, page, pageIndex, pageCount, selected, pendingKey
|
|
|
264
325
|
bands.push({
|
|
265
326
|
...band,
|
|
266
327
|
key: `${isSelected ? "sel" : "pend"}-${key}-${bandIdentity(segment)}-${index}`,
|
|
267
|
-
className: isSelected ? "hwped-band hwped-band-selected" : "hwped-band hwped-band-pending"
|
|
328
|
+
className: (isSelected ? "hwped-band hwped-band-selected" : "hwped-band hwped-band-pending") + (band.approximate ? " hwped-band-approximate" : "")
|
|
268
329
|
});
|
|
269
330
|
}
|
|
270
331
|
}
|
|
@@ -276,7 +337,7 @@ function PageView(props) {
|
|
|
276
337
|
const label = t("page.label", { page: page.page });
|
|
277
338
|
const imgSrc = (0, import_react2.useMemo)(() => {
|
|
278
339
|
const mime = page.format === "jpeg" ? "image/jpeg" : page.format === "svg" ? "image/svg+xml" : `image/${page.format}`;
|
|
279
|
-
return `data:${mime};base64,${
|
|
340
|
+
return `data:${mime};base64,${import_core3.base64.encode(page.data)}`;
|
|
280
341
|
}, [page]);
|
|
281
342
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
282
343
|
"div",
|
|
@@ -308,6 +369,7 @@ function PageView(props) {
|
|
|
308
369
|
"div",
|
|
309
370
|
{
|
|
310
371
|
className: band.className,
|
|
372
|
+
"data-approximate": band.className.includes("hwped-band-approximate") ? "true" : void 0,
|
|
311
373
|
style: { top: `${band.top}%`, height: `${band.height}%`, left: `${band.left}%`, width: `${band.width}%` }
|
|
312
374
|
},
|
|
313
375
|
band.key
|
|
@@ -340,7 +402,7 @@ function targetsSegment(op, envelope, segment) {
|
|
|
340
402
|
return "run" in at ? segment.kind === "run" && segment.indices?.length === 2 && segment.indices[1] === at.run : segment.kind === "para" && (segment.indices === void 0 || segment.indices.length === 1);
|
|
341
403
|
}
|
|
342
404
|
const target = opSearchText(op);
|
|
343
|
-
return target !== null && target !== "" && plainSegmentText((0,
|
|
405
|
+
return target !== null && target !== "" && plainSegmentText((0, import_core3.segmentText)(envelope, segment)).includes(target);
|
|
344
406
|
}
|
|
345
407
|
|
|
346
408
|
// src/unit-input.ts
|
|
@@ -351,7 +413,7 @@ function isPlainDecimal(value) {
|
|
|
351
413
|
|
|
352
414
|
// src/SegmentInspector.tsx
|
|
353
415
|
var import_react3 = require("react");
|
|
354
|
-
var
|
|
416
|
+
var import_core4 = require("@hwp-editor/core");
|
|
355
417
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
356
418
|
var ALIGNMENTS = [
|
|
357
419
|
{ value: "left", key: "segment.alignLeft" },
|
|
@@ -381,15 +443,15 @@ function SegmentInspector() {
|
|
|
381
443
|
const paragraphKeys = /* @__PURE__ */ new Set();
|
|
382
444
|
const paragraphs = (envelope?.segments.filter((candidate) => {
|
|
383
445
|
if (candidate.kind !== "para") return false;
|
|
384
|
-
if (!(0,
|
|
446
|
+
if (!(0, import_core4.hasOwnRef)(candidate)) return false;
|
|
385
447
|
const key = candidate.id ?? `${candidate.section}:${candidate.para}`;
|
|
386
448
|
if (paragraphKeys.has(key)) return false;
|
|
387
449
|
paragraphKeys.add(key);
|
|
388
450
|
return true;
|
|
389
|
-
}) ?? []).sort(
|
|
390
|
-
const selected = envelope === null ? [] : (0,
|
|
391
|
-
const segment = envelope !== null && selection !== null ? (0,
|
|
392
|
-
const targets = envelope !== null && segment !== void 0 ? (0,
|
|
451
|
+
}) ?? []).sort(import_core4.compareSegments);
|
|
452
|
+
const selected = envelope === null ? [] : (0, import_core4.selectedParagraphs)(envelope, state);
|
|
453
|
+
const segment = envelope !== null && selection !== null ? (0, import_core4.segmentAtRef)(envelope, selection) : void 0;
|
|
454
|
+
const targets = envelope !== null && segment !== void 0 ? (0, import_core4.resolveSelection)(envelope, segment) : void 0;
|
|
393
455
|
const paragraphTargets = targets?.paragraphs ?? [];
|
|
394
456
|
const singleParagraph = targets?.paragraph;
|
|
395
457
|
const directStyleRow = (() => {
|
|
@@ -397,13 +459,13 @@ function SegmentInspector() {
|
|
|
397
459
|
if (id === void 0 || styles === null) return void 0;
|
|
398
460
|
return styles.styles.find((item) => item.kind === "paragraph" && item.used_by.includes(id));
|
|
399
461
|
})();
|
|
400
|
-
const directStyleWhy = directStyleRow !== void 0 ? null : stylesStatus === "loading" ? "segment.directStyleLoading" : stylesStatus === "failed" ? "segment.directStyleFailed" : stylesStatus === "unsupported" ? "styles.unavailableHost" : capabilities === null ? "styles.checkingHost" : capabilities.styles !== "v1" ? (0,
|
|
462
|
+
const directStyleWhy = directStyleRow !== void 0 ? null : stylesStatus === "loading" ? "segment.directStyleLoading" : stylesStatus === "failed" ? "segment.directStyleFailed" : stylesStatus === "unsupported" ? "styles.unavailableHost" : capabilities === null ? "styles.checkingHost" : capabilities.styles !== "v1" ? (0, import_core4.stylesVersionSupported)(capabilities.version) ? "styles.unavailableHost" : "segment.directStyleUnavailable" : "segment.directStyleUnknown";
|
|
401
463
|
const refusalText = (reason) => reason === null || reason === void 0 ? null : reason === "cell" ? t("segment.cellSelectionRefused") : reason === "table" ? t("segment.tableSelectionRefused") : reason === "container" ? t("segment.containerSelectionRefused") : t("segment.noParagraphSelection");
|
|
402
464
|
const clickRefusedText = (reason) => reason === null || reason === void 0 ? null : t(CLICK_REFUSAL_MESSAGE[reason]);
|
|
403
465
|
const refusalReason2 = refusalText(targets?.refusal);
|
|
404
|
-
const targetLabel = segment === void 0 ? "" : segment.kind === "cell" ? t("segment.selectedCell", { path: (0,
|
|
405
|
-
const currentText = envelope !== null && paragraphTargets.length > 0 ?
|
|
406
|
-
const markdownText = envelope !== null && singleParagraph !== void 0 ? (0,
|
|
466
|
+
const targetLabel = segment === void 0 ? "" : segment.kind === "cell" ? t("segment.selectedCell", { path: (0, import_core4.segmentPath)(segment), count: paragraphTargets.length }) : singleParagraph === void 0 ? "" : t("segment.selectedPara", { path: (0, import_core4.segmentPath)(singleParagraph) });
|
|
467
|
+
const currentText = envelope !== null && paragraphTargets.length > 0 ? paragraphTargets.map((candidate) => paragraphSourceText(envelope, candidate, state.pages)).join("\n").trim() : "";
|
|
468
|
+
const markdownText = envelope !== null && singleParagraph !== void 0 ? (0, import_core4.segmentText)(envelope, singleParagraph) : "";
|
|
407
469
|
const supplementaryStarts = (0, import_react3.useMemo)(() => {
|
|
408
470
|
const positions = [];
|
|
409
471
|
let offset = 0;
|
|
@@ -439,19 +501,19 @@ function SegmentInspector() {
|
|
|
439
501
|
setPlaceholderName("");
|
|
440
502
|
}, [selection]);
|
|
441
503
|
const find = currentText;
|
|
442
|
-
const address = singleParagraph === void 0 ? void 0 : (0,
|
|
504
|
+
const address = singleParagraph === void 0 ? void 0 : (0, import_core4.paragraphAddress)(singleParagraph);
|
|
443
505
|
const siblings = singleParagraph?.indices === void 0 ? [] : paragraphs.filter((candidate) => candidate.section === singleParagraph.section && candidate.id !== void 0 && candidate.indices !== void 0 && candidate.indices.length === singleParagraph.indices.length && singleParagraph.indices.slice(0, -1).every((index, at) => candidate.indices[at] === index));
|
|
444
506
|
const siblingAt = siblings.findIndex((candidate) => candidate.id === singleParagraph?.id);
|
|
445
507
|
const addressedUnavailable = capabilities?.editOps !== "v1";
|
|
446
508
|
const disabled = !editable || addressedUnavailable || state.status === "applying";
|
|
447
509
|
const selectedRefs = state.selections?.length ? state.selections : selection === null ? [] : [selection];
|
|
448
510
|
const explicitSegments = envelope === null ? [] : selectedRefs.flatMap((ref) => {
|
|
449
|
-
const item = (0,
|
|
511
|
+
const item = (0, import_core4.segmentAtRef)(envelope, ref);
|
|
450
512
|
return item === void 0 ? [] : [item];
|
|
451
513
|
});
|
|
452
514
|
const hasRunSelection = explicitSegments.some((item) => item.kind === "run");
|
|
453
515
|
const multiSelection = explicitSegments.length > 1;
|
|
454
|
-
const paragraphRun = multiSelection && explicitSegments.every((item) => item.kind === "para") ? [...explicitSegments].sort(
|
|
516
|
+
const paragraphRun = multiSelection && explicitSegments.every((item) => item.kind === "para") ? [...explicitSegments].sort(import_core4.compareSegments) : null;
|
|
455
517
|
const runStart = paragraphRun === null ? -1 : siblings.findIndex((candidate) => candidate.id === paragraphRun[0]?.id);
|
|
456
518
|
const runContiguous = paragraphRun !== null && runStart >= 0 && paragraphRun.every((item, at) => siblings[runStart + at]?.id === item.id);
|
|
457
519
|
const runEnd = runContiguous ? runStart + paragraphRun.length - 1 : -1;
|
|
@@ -462,7 +524,7 @@ function SegmentInspector() {
|
|
|
462
524
|
if (insertionRun === null || !insertionCurrent || runParent === void 0) return [];
|
|
463
525
|
const section = insertionRun[0].section;
|
|
464
526
|
return insertedHidden.ids.flatMap((id) => {
|
|
465
|
-
const [idSection, ...indices] = (0,
|
|
527
|
+
const [idSection, ...indices] = (0, import_core4.segmentIdPath)(id);
|
|
466
528
|
if (idSection !== section || indices.length !== runParent.length + 1) return [];
|
|
467
529
|
if (!runParent.every((index, at) => indices[at] === index)) return [];
|
|
468
530
|
return [{ id, index: indices[indices.length - 1] }];
|
|
@@ -473,16 +535,16 @@ function SegmentInspector() {
|
|
|
473
535
|
if (published === void 0) return void 0;
|
|
474
536
|
const publishedIndex = published.indices?.[published.indices.length - 1];
|
|
475
537
|
const beyond = hiddenInRun.filter((hidden) => publishedIndex === void 0 || (edge === "first" ? hidden.index < publishedIndex : hidden.index > publishedIndex));
|
|
476
|
-
if (beyond.length === 0) return (0,
|
|
538
|
+
if (beyond.length === 0) return (0, import_core4.paragraphAddress)(published);
|
|
477
539
|
const pick = beyond.reduce((best, hidden) => (edge === "first" ? hidden.index < best.index : hidden.index > best.index) ? hidden : best);
|
|
478
540
|
return { id: pick.id };
|
|
479
541
|
};
|
|
480
542
|
const textSelectionRestricted = multiSelection || hasRunSelection || state.range != null;
|
|
481
543
|
const singleTargetDisabled = disabled || textSelectionRestricted || address === void 0;
|
|
482
544
|
const reorderRefused = multiSelection && !runContiguous;
|
|
483
|
-
const definitionLocked = paragraphRun === null ? singleParagraph !== void 0 && (0,
|
|
545
|
+
const definitionLocked = paragraphRun === null ? singleParagraph !== void 0 && (0, import_core4.isSectionDefinitionParagraph)(singleParagraph) : paragraphRun.some(import_core4.isSectionDefinitionParagraph);
|
|
484
546
|
const moveUpNeighbour = siblings[(paragraphRun === null ? siblingAt : runStart) - 1];
|
|
485
|
-
const definitionAbove = moveUpNeighbour !== void 0 && (0,
|
|
547
|
+
const definitionAbove = moveUpNeighbour !== void 0 && (0, import_core4.isSectionDefinitionParagraph)(moveUpNeighbour);
|
|
486
548
|
const deleteDisabled = disabled || definitionLocked || (paragraphRun === null ? textSelectionRestricted || address === void 0 : !runContiguous);
|
|
487
549
|
const moveUpDisabled = deleteDisabled || definitionAbove || (paragraphRun === null ? siblingAt <= 0 : runStart <= 0);
|
|
488
550
|
const moveDownDisabled = deleteDisabled || (paragraphRun === null ? siblingAt < 0 || siblingAt >= siblings.length - 1 : runEnd >= siblings.length - 1);
|
|
@@ -490,12 +552,12 @@ function SegmentInspector() {
|
|
|
490
552
|
const legacyLinkSeparator = capabilities?.editOps !== "v1" && [currentText, linkText, linkUrl].some((value) => value.includes("=>"));
|
|
491
553
|
const validShape = isPlainDecimal(shapeValue) && (shapeKey !== "line-spacing" || Number(shapeValue) > 0);
|
|
492
554
|
const validFontSize = fontSize.trim() === "" || isPlainDecimal(fontSize) && Number(fontSize) > 0;
|
|
493
|
-
const formatInputs = envelope === null ? [] : explicitSegments.flatMap((item) => item.kind === "run" ? [item] : (0,
|
|
494
|
-
const formatTargets = envelope === null ? [] : (0,
|
|
495
|
-
const runs = envelope === null || singleParagraph === void 0 ? [] : (0,
|
|
555
|
+
const formatInputs = envelope === null ? [] : explicitSegments.flatMap((item) => item.kind === "run" ? [item] : (0, import_core4.resolveSelection)(envelope, item).paragraphs).sort(import_core4.compareSegments);
|
|
556
|
+
const formatTargets = envelope === null ? [] : (0, import_core4.formatTargets)(envelope, formatInputs, state.range, (0, import_core4.documentFormat)(state.document?.name, state.document?.data));
|
|
557
|
+
const runs = envelope === null || singleParagraph === void 0 ? [] : (0, import_core4.paragraphRuns)(envelope, singleParagraph);
|
|
496
558
|
const formatNoRuns = state.range == null && singleParagraph !== void 0 && singleParagraph.start !== singleParagraph.end && singleParagraph.indices === void 0 && runs.length === 0;
|
|
497
559
|
const rangeAvailable = !multiSelection && runs.some((run) => run.id !== void 0 || singleParagraph?.indices?.length === 1 && run.indices?.length === 2);
|
|
498
|
-
const charPrimary = segment?.kind === "run" ? segment : envelope !== null && state.range != null && formatTargets[0]?.address.id !== void 0 ? (0,
|
|
560
|
+
const charPrimary = segment?.kind === "run" ? segment : envelope !== null && state.range != null && formatTargets[0]?.address.id !== void 0 ? (0, import_core4.segmentAtRef)(envelope, { id: formatTargets[0].address.id, section: 0, para: 0 }) ?? singleParagraph : singleParagraph;
|
|
499
561
|
const plainParagraph = (() => {
|
|
500
562
|
if (envelope === null || singleParagraph === void 0) return void 0;
|
|
501
563
|
const depth = singleParagraph.indices?.length;
|
|
@@ -506,7 +568,7 @@ function SegmentInspector() {
|
|
|
506
568
|
const contentEnd = singleParagraph.start + points.length;
|
|
507
569
|
const holdsControl = envelope.segments.some((item) => (item.kind === "field" || item.kind === "image" || item.kind === "bookmark") && item.start < contentEnd && item.end > singleParagraph.start);
|
|
508
570
|
if (holdsControl) return void 0;
|
|
509
|
-
const ordered = (0,
|
|
571
|
+
const ordered = (0, import_core4.paragraphRuns)(envelope, singleParagraph);
|
|
510
572
|
let cursor = singleParagraph.start;
|
|
511
573
|
for (const run of ordered) {
|
|
512
574
|
if (run.start !== cursor || run.end < run.start || run.end > contentEnd) return void 0;
|
|
@@ -522,7 +584,7 @@ function SegmentInspector() {
|
|
|
522
584
|
if (/^(?:[-+]|\d{1,3}[.)])\s/u.test(text)) return void 0;
|
|
523
585
|
return { runs: ordered, texts, text };
|
|
524
586
|
})();
|
|
525
|
-
const rangeRuns = envelope !== null && singleParagraph !== void 0 && state.range != null ? (0,
|
|
587
|
+
const rangeRuns = envelope !== null && singleParagraph !== void 0 && state.range != null ? (0, import_core4.paragraphRuns)(envelope, singleParagraph, state.range) : [];
|
|
526
588
|
const rangeFrom = rangeRuns.length === 0 ? -1 : Math.min(...rangeRuns.map((item) => item.start));
|
|
527
589
|
const rangeTo = rangeRuns.length === 0 ? -1 : Math.max(...rangeRuns.map((item) => item.end));
|
|
528
590
|
const wholeRuns = state.range != null && rangeRuns.length > 0 && rangeFrom === state.range.start && rangeTo === state.range.end;
|
|
@@ -555,7 +617,7 @@ function SegmentInspector() {
|
|
|
555
617
|
};
|
|
556
618
|
const activateSelection = (target, mode) => {
|
|
557
619
|
if (envelope === null) return;
|
|
558
|
-
store.dispatch((0,
|
|
620
|
+
store.dispatch((0, import_core4.selectionAction)(envelope, store.getState(), target, mode));
|
|
559
621
|
};
|
|
560
622
|
const handleOptionKeyDown = (event, target) => {
|
|
561
623
|
if (event.key !== "Enter" && event.key !== " ") return;
|
|
@@ -566,11 +628,11 @@ function SegmentInspector() {
|
|
|
566
628
|
if (envelope === null || singleParagraph === void 0) return;
|
|
567
629
|
const match = level === "char" ? charPrimary : singleParagraph;
|
|
568
630
|
if (match === void 0) return;
|
|
569
|
-
const refs = (0,
|
|
631
|
+
const refs = (0, import_core4.selectSimilar)(envelope, match, level);
|
|
570
632
|
if (refs.length === 0) return;
|
|
571
633
|
const activeMatch = refs.find((ref) => {
|
|
572
|
-
const item = (0,
|
|
573
|
-
const parent = item === void 0 ? void 0 : (0,
|
|
634
|
+
const item = (0, import_core4.segmentAtRef)(envelope, ref);
|
|
635
|
+
const parent = item === void 0 ? void 0 : (0, import_core4.resolveSelection)(envelope, item).paragraph;
|
|
574
636
|
return parent === singleParagraph || parent?.id !== void 0 && parent.id === singleParagraph.id || parent !== void 0 && parent.id === void 0 && singleParagraph.id === void 0 && parent.section === singleParagraph.section && parent.para === singleParagraph.para;
|
|
575
637
|
});
|
|
576
638
|
const primary = activeMatch ?? refs[0];
|
|
@@ -593,7 +655,7 @@ function SegmentInspector() {
|
|
|
593
655
|
type: "queueOp",
|
|
594
656
|
op: {
|
|
595
657
|
kind: "move-para",
|
|
596
|
-
address: (0,
|
|
658
|
+
address: (0, import_core4.paragraphAddress)(neighbour2),
|
|
597
659
|
to: { address: anchor2, position: direction === -1 ? "after" : "before" }
|
|
598
660
|
}
|
|
599
661
|
});
|
|
@@ -607,7 +669,7 @@ function SegmentInspector() {
|
|
|
607
669
|
op: {
|
|
608
670
|
kind: "move-para",
|
|
609
671
|
address,
|
|
610
|
-
to: { address: (0,
|
|
672
|
+
to: { address: (0, import_core4.paragraphAddress)(neighbour2), position: direction === -1 ? "before" : "after" }
|
|
611
673
|
}
|
|
612
674
|
});
|
|
613
675
|
return;
|
|
@@ -620,7 +682,7 @@ function SegmentInspector() {
|
|
|
620
682
|
type: "queueOp",
|
|
621
683
|
op: {
|
|
622
684
|
kind: "move-para",
|
|
623
|
-
address: (0,
|
|
685
|
+
address: (0, import_core4.paragraphAddress)(neighbour),
|
|
624
686
|
to: { address: anchor, position: direction === -1 ? "after" : "before" }
|
|
625
687
|
}
|
|
626
688
|
});
|
|
@@ -645,7 +707,7 @@ function SegmentInspector() {
|
|
|
645
707
|
store.dispatch({
|
|
646
708
|
type: "queueOps",
|
|
647
709
|
ops: [
|
|
648
|
-
...paragraphRun.map((item) => ({ kind: "delete-para", address: (0,
|
|
710
|
+
...paragraphRun.map((item) => ({ kind: "delete-para", address: (0, import_core4.paragraphAddress)(item) })),
|
|
649
711
|
// The insertion's unpublished paragraphs go with it (#521).
|
|
650
712
|
...hiddenInRun.map((hidden) => ({ kind: "delete-para", address: { id: hidden.id } }))
|
|
651
713
|
]
|
|
@@ -669,7 +731,7 @@ function SegmentInspector() {
|
|
|
669
731
|
style: { maxHeight: "12rem", overflowY: "auto" },
|
|
670
732
|
children: paragraphs.map((candidate, index) => {
|
|
671
733
|
const isSelected = selected.some((item) => item === candidate || item.id !== void 0 && item.id === candidate.id || item.id === void 0 && candidate.id === void 0 && item.section === candidate.section && item.para === candidate.para);
|
|
672
|
-
const snippet = plainSegmentText((0,
|
|
734
|
+
const snippet = plainSegmentText((0, import_core4.segmentText)(envelope, candidate)).trim().replace(/\s+/g, " ");
|
|
673
735
|
const text = snippet.length > 96 ? `${snippet.slice(0, 93)}...` : snippet || t("segment.emptyPara");
|
|
674
736
|
const label = t("segment.choiceLabel", { index: index + 1, text });
|
|
675
737
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
@@ -845,7 +907,7 @@ function SegmentInspector() {
|
|
|
845
907
|
disabled: disabled || selected.length === 0,
|
|
846
908
|
onClick: () => store.dispatch({
|
|
847
909
|
type: "queueOps",
|
|
848
|
-
ops: selected.map((target) => ({ kind: "set-align", address: (0,
|
|
910
|
+
ops: selected.map((target) => ({ kind: "set-align", address: (0, import_core4.paragraphAddress)(target), alignment: align.value }))
|
|
849
911
|
}),
|
|
850
912
|
children: t(align.key)
|
|
851
913
|
},
|
|
@@ -891,7 +953,7 @@ function SegmentInspector() {
|
|
|
891
953
|
type: "button",
|
|
892
954
|
className: "hwped-btn",
|
|
893
955
|
disabled: disabled || selected.length === 0 || !validShape,
|
|
894
|
-
onClick: () => store.dispatch({ type: "queueOps", ops: selected.map((target) => ({ kind: "set-para", address: (0,
|
|
956
|
+
onClick: () => store.dispatch({ type: "queueOps", ops: selected.map((target) => ({ kind: "set-para", address: (0, import_core4.paragraphAddress)(target), key: shapeKey, value: `${shapeValue.trim()}${shapeKey === "line-spacing" ? lineSpacingUnit : "mm"}` })) }),
|
|
895
957
|
children: t("segment.setPara")
|
|
896
958
|
}
|
|
897
959
|
)
|
|
@@ -907,7 +969,7 @@ function SegmentInspector() {
|
|
|
907
969
|
charPrimary?.directChar === void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "hwped-hint", children: t("segment.similarCharUnavailable") }),
|
|
908
970
|
singleParagraph.directPara === void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "hwped-hint", children: t("segment.similarParaUnavailable") })
|
|
909
971
|
] }),
|
|
910
|
-
singleParagraph !== void 0 && (0,
|
|
972
|
+
singleParagraph !== void 0 && (0, import_core4.hasDirectFormatting)(singleParagraph) && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "hwped-field", children: [
|
|
911
973
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "hwped-label", children: t("segment.directFormatting") }),
|
|
912
974
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "hwped-hint", children: t("segment.directFormattingHint") }),
|
|
913
975
|
directStyleRow === void 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "hwped-hint", children: t(directStyleWhy ?? "segment.directStyleUnknown") }) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
@@ -916,7 +978,7 @@ function SegmentInspector() {
|
|
|
916
978
|
type: "button",
|
|
917
979
|
className: "hwped-btn",
|
|
918
980
|
disabled,
|
|
919
|
-
onClick: () => store.dispatch({ type: "queueOp", op: { kind: "apply-style", address: (0,
|
|
981
|
+
onClick: () => store.dispatch({ type: "queueOp", op: { kind: "apply-style", address: (0, import_core4.paragraphAddress)(singleParagraph), style: directStyleRow.id, clearDirect: true } }),
|
|
920
982
|
children: t("segment.clearDirect")
|
|
921
983
|
}
|
|
922
984
|
)
|
|
@@ -990,7 +1052,7 @@ function SegmentInspector() {
|
|
|
990
1052
|
}
|
|
991
1053
|
setRangeSplit(false);
|
|
992
1054
|
store.dispatch({ type: "setRange", range: start === end ? null : {
|
|
993
|
-
paragraph: (0,
|
|
1055
|
+
paragraph: (0, import_core4.segmentRef)(singleParagraph),
|
|
994
1056
|
start: singleParagraph.start + start,
|
|
995
1057
|
end: singleParagraph.start + end
|
|
996
1058
|
} });
|
|
@@ -1008,7 +1070,7 @@ function SegmentInspector() {
|
|
|
1008
1070
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("button", { type: "button", className: "hwped-btn", onClick: () => {
|
|
1009
1071
|
setRangeSplit(false);
|
|
1010
1072
|
rangeInput.current?.setSelectionRange(0, 0);
|
|
1011
|
-
if (hasRunSelection) store.dispatch({ type: "select", selection: (0,
|
|
1073
|
+
if (hasRunSelection) store.dispatch({ type: "select", selection: (0, import_core4.segmentRef)(singleParagraph) });
|
|
1012
1074
|
else store.dispatch({ type: "setRange", range: null });
|
|
1013
1075
|
}, children: t("segment.rangeClear") })
|
|
1014
1076
|
] })
|
|
@@ -1168,7 +1230,7 @@ function wholeRunText(run, markdown) {
|
|
|
1168
1230
|
|
|
1169
1231
|
// src/StylesPanel.tsx
|
|
1170
1232
|
var import_react4 = require("react");
|
|
1171
|
-
var
|
|
1233
|
+
var import_core5 = require("@hwp-editor/core");
|
|
1172
1234
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
1173
1235
|
var ALIGNMENTS2 = ["justify", "left", "right", "center", "distribute"];
|
|
1174
1236
|
var ALIGN_LABEL = {
|
|
@@ -1241,7 +1303,7 @@ function DefinitionForm(props) {
|
|
|
1241
1303
|
type: "queueOps",
|
|
1242
1304
|
ops: paragraphs.map((paragraph) => ({
|
|
1243
1305
|
kind: "apply-style",
|
|
1244
|
-
address: (0,
|
|
1306
|
+
address: (0, import_core5.paragraphAddress)(paragraph),
|
|
1245
1307
|
style: row.id
|
|
1246
1308
|
}))
|
|
1247
1309
|
});
|
|
@@ -1365,12 +1427,12 @@ function StylesPanel() {
|
|
|
1365
1427
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hwped-panel", role: "region", "aria-label": t("tabs.styles"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "hwped-hint", role: "status", children: t("styles.checkingHost") }) });
|
|
1366
1428
|
}
|
|
1367
1429
|
if (capabilities.styles !== "v1") {
|
|
1368
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hwped-panel", role: "region", "aria-label": t("tabs.styles"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "hwped-hint", role: "status", children: (0,
|
|
1430
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hwped-panel", role: "region", "aria-label": t("tabs.styles"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "hwped-hint", role: "status", children: (0, import_core5.stylesVersionSupported)(capabilities.version) ? t("styles.unavailableHost") : t("styles.unavailable", { version: capabilities.version }) }) });
|
|
1369
1431
|
}
|
|
1370
1432
|
if (engine.styles === void 0) {
|
|
1371
1433
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "hwped-panel", role: "region", "aria-label": t("tabs.styles"), children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("p", { className: "hwped-hint", role: "status", children: t("styles.unavailableHost") }) });
|
|
1372
1434
|
}
|
|
1373
|
-
const paragraphs = envelope === null ? [] : (0,
|
|
1435
|
+
const paragraphs = envelope === null ? [] : (0, import_core5.selectedParagraphs)(envelope, state);
|
|
1374
1436
|
const rows = styles?.styles ?? [];
|
|
1375
1437
|
const row = rows.find((item) => item.id === selectedId) ?? null;
|
|
1376
1438
|
const paragraphRow = row !== null && row.kind === "paragraph" ? row : null;
|
|
@@ -1380,8 +1442,8 @@ function StylesPanel() {
|
|
|
1380
1442
|
setSelectedId(item.id);
|
|
1381
1443
|
if (envelope === null || item.used_by.length === 0) return;
|
|
1382
1444
|
const refs = item.used_by.flatMap((id) => {
|
|
1383
|
-
const segment = (0,
|
|
1384
|
-
return segment === void 0 ? [] : [(0,
|
|
1445
|
+
const segment = (0, import_core5.segmentAtRef)(envelope, { id, section: 0, para: 0 });
|
|
1446
|
+
return segment === void 0 ? [] : [(0, import_core5.segmentRef)(segment)];
|
|
1385
1447
|
});
|
|
1386
1448
|
if (refs.length === 0) return;
|
|
1387
1449
|
store.dispatch({ type: "selectMany", selections: refs, primary: refs[0], anchor: refs[0] });
|
|
@@ -1392,12 +1454,12 @@ function StylesPanel() {
|
|
|
1392
1454
|
const shape = base === void 0 ? void 0 : base.direct ?? base.style;
|
|
1393
1455
|
if (name === "" || base === void 0 || shape === void 0 || envelope === null) return;
|
|
1394
1456
|
const face = firstFace(shape);
|
|
1395
|
-
const paragraph = (0,
|
|
1457
|
+
const paragraph = (0, import_core5.resolveSelection)(envelope, base).paragraph ?? base;
|
|
1396
1458
|
const id = paragraph.id;
|
|
1397
1459
|
const own = id === void 0 ? void 0 : rows.find((item) => item.kind === "paragraph" && item.used_by.includes(id));
|
|
1398
|
-
const targets = (0,
|
|
1399
|
-
const segment = (0,
|
|
1400
|
-
return segment === void 0 ? [] : [(0,
|
|
1460
|
+
const targets = (0, import_core5.selectSimilar)(envelope, paragraph, "para").flatMap((ref) => {
|
|
1461
|
+
const segment = (0, import_core5.segmentAtRef)(envelope, ref);
|
|
1462
|
+
return segment === void 0 ? [] : [(0, import_core5.paragraphAddress)(segment)];
|
|
1401
1463
|
});
|
|
1402
1464
|
const align = shape.para === void 0 ? void 0 : writableAlignment(shape.para.alignment);
|
|
1403
1465
|
store.dispatch({
|
|
@@ -1433,7 +1495,7 @@ function StylesPanel() {
|
|
|
1433
1495
|
const switchPreset = () => {
|
|
1434
1496
|
if (styles === null || envelope === null) return;
|
|
1435
1497
|
const epoch = loadEpoch();
|
|
1436
|
-
const styleOps = (0,
|
|
1498
|
+
const styleOps = (0, import_core5.presetStyleOps)(styles, preset, envelope);
|
|
1437
1499
|
const carriedStyleOp = styleOps.length > 0;
|
|
1438
1500
|
const batch = [
|
|
1439
1501
|
...styleOps,
|
|
@@ -1443,10 +1505,10 @@ function StylesPanel() {
|
|
|
1443
1505
|
let unstyled = false;
|
|
1444
1506
|
let changed = false;
|
|
1445
1507
|
void replaceDocument(async (current) => {
|
|
1446
|
-
const styled = await engine.edit(current, batch, (0,
|
|
1447
|
-
const reading = (0,
|
|
1508
|
+
const styled = await engine.edit(current, batch, (0, import_core5.presetBatchOptions)(batch, { verify: true }));
|
|
1509
|
+
const reading = (0, import_core5.readPresetBatch)(styled.report);
|
|
1448
1510
|
if (reading.refusal !== null) {
|
|
1449
|
-
throw new
|
|
1511
|
+
throw new import_core5.HwpEngineError(reading.refusal.code, reading.refusal.message);
|
|
1450
1512
|
}
|
|
1451
1513
|
unstyled = reading.unstyledTable;
|
|
1452
1514
|
changed = !reading.unchanged;
|
|
@@ -1529,7 +1591,7 @@ function StylesPanel() {
|
|
|
1529
1591
|
disabled,
|
|
1530
1592
|
"aria-label": t("styles.presetLabel"),
|
|
1531
1593
|
onChange: (e) => setPreset(e.target.value),
|
|
1532
|
-
children:
|
|
1594
|
+
children: import_core5.STYLE_TABLE_PRESETS.map((value) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("option", { value, children: t(PRESET_LABEL[value]) }, value))
|
|
1533
1595
|
}
|
|
1534
1596
|
),
|
|
1535
1597
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
@@ -1550,10 +1612,10 @@ function StylesPanel() {
|
|
|
1550
1612
|
|
|
1551
1613
|
// src/TableGrid.tsx
|
|
1552
1614
|
var import_react5 = require("react");
|
|
1553
|
-
var
|
|
1615
|
+
var import_core7 = require("@hwp-editor/core");
|
|
1554
1616
|
|
|
1555
1617
|
// src/tables.ts
|
|
1556
|
-
var
|
|
1618
|
+
var import_core6 = require("@hwp-editor/core");
|
|
1557
1619
|
var GFM_DELIMITER_CELL = /^:?-{2,}:?$/;
|
|
1558
1620
|
function endsWithCellDelimiter(row) {
|
|
1559
1621
|
if (!row.endsWith("|")) return false;
|
|
@@ -1620,7 +1682,7 @@ function findTables(envelope) {
|
|
|
1620
1682
|
tables.push({
|
|
1621
1683
|
tableIndex: tables.length,
|
|
1622
1684
|
segment,
|
|
1623
|
-
rows: parseMarkdownTable((0,
|
|
1685
|
+
rows: parseMarkdownTable((0, import_core6.segmentText)(envelope, segment))
|
|
1624
1686
|
});
|
|
1625
1687
|
}
|
|
1626
1688
|
return tables;
|
|
@@ -1690,7 +1752,7 @@ function TableGrid() {
|
|
|
1690
1752
|
}
|
|
1691
1753
|
)
|
|
1692
1754
|
] });
|
|
1693
|
-
const mismatch = envelope === null ? null : (0,
|
|
1755
|
+
const mismatch = envelope === null ? null : (0, import_core7.tableCountMismatch)(envelope);
|
|
1694
1756
|
if (mismatch !== null) {
|
|
1695
1757
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "hwped-panel", role: "region", "aria-label": t("table.panelAria"), children: [
|
|
1696
1758
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("p", { className: "hwped-hint", children: t("table.indexMismatch", mismatch) }),
|
|
@@ -1925,10 +1987,10 @@ function TableGrid() {
|
|
|
1925
1987
|
|
|
1926
1988
|
// src/FieldsPanel.tsx
|
|
1927
1989
|
var import_react6 = require("react");
|
|
1928
|
-
var
|
|
1990
|
+
var import_core9 = require("@hwp-editor/core");
|
|
1929
1991
|
|
|
1930
1992
|
// src/fields.ts
|
|
1931
|
-
var
|
|
1993
|
+
var import_core8 = require("@hwp-editor/core");
|
|
1932
1994
|
var SLOT_PATTERN = /\{\{\s*([^{}]+?)\s*\}\}/g;
|
|
1933
1995
|
var CONTROL_KINDS = /* @__PURE__ */ new Set(["field", "image", "bookmark"]);
|
|
1934
1996
|
function innermostAt(envelope, offset) {
|
|
@@ -1956,10 +2018,10 @@ function extractFieldSlots(envelope) {
|
|
|
1956
2018
|
const offset = [...envelope.markdown.slice(0, match.index ?? 0)].length;
|
|
1957
2019
|
const hit = innermostAt(envelope, offset);
|
|
1958
2020
|
if (hit === void 0 || seen.has(name)) continue;
|
|
1959
|
-
const paragraph = (0,
|
|
2021
|
+
const paragraph = (0, import_core8.resolveSelection)(envelope, hit).paragraph;
|
|
1960
2022
|
if (paragraph === void 0) continue;
|
|
1961
2023
|
seen.add(name);
|
|
1962
|
-
slots.push({ name, segment: (0,
|
|
2024
|
+
slots.push({ name, segment: (0, import_core8.segmentRef)(paragraph) });
|
|
1963
2025
|
}
|
|
1964
2026
|
return slots;
|
|
1965
2027
|
}
|
|
@@ -1993,8 +2055,8 @@ function FieldsPanel() {
|
|
|
1993
2055
|
children: [
|
|
1994
2056
|
legacy && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "hwped-hint", children: t("fields.legacySeparatorHint") }),
|
|
1995
2057
|
slots.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("p", { className: "hwped-hint", children: t("fields.hint") }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ul", { className: "hwped-fields", children: slots.map((slot) => {
|
|
1996
|
-
const segment = envelope === null ? void 0 : (0,
|
|
1997
|
-
const snippet = envelope === null || segment === void 0 ? "" : (0,
|
|
2058
|
+
const segment = envelope === null ? void 0 : (0, import_core9.segmentAtRef)(envelope, slot.segment);
|
|
2059
|
+
const snippet = envelope === null || segment === void 0 ? "" : (0, import_core9.segmentText)(envelope, segment).trim().slice(0, 40);
|
|
1998
2060
|
const draft = drafts[slot.name] ?? "";
|
|
1999
2061
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("li", { className: "hwped-field-item", children: [
|
|
2000
2062
|
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)("div", { className: "hwped-row", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
@@ -2063,19 +2125,19 @@ function FieldsPanel() {
|
|
|
2063
2125
|
|
|
2064
2126
|
// src/TemplatePanel.tsx
|
|
2065
2127
|
var import_react7 = require("react");
|
|
2066
|
-
var
|
|
2128
|
+
var import_core13 = require("@hwp-editor/core");
|
|
2067
2129
|
|
|
2068
2130
|
// src/errors.ts
|
|
2069
|
-
var
|
|
2131
|
+
var import_core10 = require("@hwp-editor/core");
|
|
2070
2132
|
function toEditorError(e) {
|
|
2071
2133
|
const refusal = engineRefusalKind(e);
|
|
2072
|
-
const base = (0,
|
|
2134
|
+
const base = (0, import_core10.isHwpEngineError)(e) && (0, import_core10.isHwpErrorCode)(e.code) ? { code: e.code, message: e.message } : { message: e instanceof Error ? e.message : String(e) };
|
|
2073
2135
|
return refusal === void 0 ? base : { ...base, refusal };
|
|
2074
2136
|
}
|
|
2075
2137
|
function engineRefusalKind(e) {
|
|
2076
2138
|
if (typeof e !== "object" || e === null) return void 0;
|
|
2077
2139
|
const refusal = e.refusal;
|
|
2078
|
-
return (0,
|
|
2140
|
+
return (0, import_core10.isEditRefusalKind)(refusal) ? refusal : void 0;
|
|
2079
2141
|
}
|
|
2080
2142
|
function engineStoppedWithoutDiagnostic(e) {
|
|
2081
2143
|
return typeof e === "object" && e !== null && e.stopped === true;
|
|
@@ -2145,8 +2207,8 @@ function ErrorLine(props) {
|
|
|
2145
2207
|
}
|
|
2146
2208
|
|
|
2147
2209
|
// src/template-support.ts
|
|
2148
|
-
var import_core10 = require("@hwp-editor/core");
|
|
2149
2210
|
var import_core11 = require("@hwp-editor/core");
|
|
2211
|
+
var import_core12 = require("@hwp-editor/core");
|
|
2150
2212
|
var METHOD_LABEL_KEYS = {
|
|
2151
2213
|
slots: "templates.methodSlots",
|
|
2152
2214
|
fill: "templates.methodFill",
|
|
@@ -2156,7 +2218,7 @@ var METHOD_LABEL_KEYS = {
|
|
|
2156
2218
|
create: "templates.methodCreate"
|
|
2157
2219
|
};
|
|
2158
2220
|
function templateMethodStatus(engine, capabilities, method) {
|
|
2159
|
-
if (!(0,
|
|
2221
|
+
if (!(0, import_core11.templateVersionSupported)(capabilities?.version ?? "")) {
|
|
2160
2222
|
return { supported: false, reason: "version" };
|
|
2161
2223
|
}
|
|
2162
2224
|
if (typeof engine[method] !== "function") {
|
|
@@ -2168,7 +2230,7 @@ function templateMethodStatus(engine, capabilities, method) {
|
|
|
2168
2230
|
return { supported: true, reason: null };
|
|
2169
2231
|
}
|
|
2170
2232
|
function templateStatusReason(t, status, method) {
|
|
2171
|
-
if (status.reason === "version") return t("templates.versionRequired", { version:
|
|
2233
|
+
if (status.reason === "version") return t("templates.versionRequired", { version: import_core12.TEMPLATE_MIN_VERSION });
|
|
2172
2234
|
const label = t(METHOD_LABEL_KEYS[method]);
|
|
2173
2235
|
if (status.reason === "missing") return t("templates.methodMissing", { method: label });
|
|
2174
2236
|
if (status.reason === "unadvertised") return t("templates.methodUnadvertised", { method: label });
|
|
@@ -2190,7 +2252,7 @@ function initialListRow(fields, supplied = {}) {
|
|
|
2190
2252
|
}
|
|
2191
2253
|
function pageData(page) {
|
|
2192
2254
|
const mime = page.format === "svg" ? "image/svg+xml" : `image/${page.format}`;
|
|
2193
|
-
return `data:${mime};base64,${
|
|
2255
|
+
return `data:${mime};base64,${import_core13.base64.encode(page.data)}`;
|
|
2194
2256
|
}
|
|
2195
2257
|
function kindLabel(input, t) {
|
|
2196
2258
|
if (input.kind === "slot") return t("templates.kindSlot");
|
|
@@ -2681,7 +2743,7 @@ function DocumentPanel() {
|
|
|
2681
2743
|
|
|
2682
2744
|
// src/ImagePanel.tsx
|
|
2683
2745
|
var import_react10 = require("react");
|
|
2684
|
-
var
|
|
2746
|
+
var import_core14 = require("@hwp-editor/core");
|
|
2685
2747
|
var import_jsx_runtime10 = require("react/jsx-runtime");
|
|
2686
2748
|
function ImagePanel() {
|
|
2687
2749
|
const { state, store, envelope, capabilities, editable, queueImage, onError, t } = useHwpEditorContext();
|
|
@@ -2719,14 +2781,14 @@ function ImagePanel() {
|
|
|
2719
2781
|
if (file === void 0) return;
|
|
2720
2782
|
setReading(true);
|
|
2721
2783
|
try {
|
|
2722
|
-
if (file.size === 0 || file.size >
|
|
2784
|
+
if (file.size === 0 || file.size > import_core14.MAX_IMAGE_ASSET_BYTES) throw new Error(t("image.invalidSize"));
|
|
2723
2785
|
let bytes;
|
|
2724
2786
|
try {
|
|
2725
2787
|
bytes = await file.arrayBuffer();
|
|
2726
2788
|
} catch {
|
|
2727
2789
|
throw new Error(t("image.readError"));
|
|
2728
2790
|
}
|
|
2729
|
-
const data = new Uint8Array(bytes), mediaType = (0,
|
|
2791
|
+
const data = new Uint8Array(bytes), mediaType = (0, import_core14.imageAssetMediaType)(data);
|
|
2730
2792
|
if (mediaType === null) throw new Error(t("image.invalidType"));
|
|
2731
2793
|
if (generation.current === version && store.getState().document === source) {
|
|
2732
2794
|
setChosen({ name: file.name, data, extension: mediaType === "image/png" ? "png" : "jpg" });
|
|
@@ -2784,12 +2846,12 @@ function ImagePanel() {
|
|
|
2784
2846
|
|
|
2785
2847
|
// src/ComposePanel.tsx
|
|
2786
2848
|
var import_react11 = require("react");
|
|
2787
|
-
var
|
|
2849
|
+
var import_core17 = require("@hwp-editor/core");
|
|
2788
2850
|
|
|
2789
2851
|
// src/presets.ts
|
|
2790
|
-
var
|
|
2791
|
-
var COMPOSE_PRESETS = [...
|
|
2792
|
-
var PRESET_PROFILES =
|
|
2852
|
+
var import_core15 = require("@hwp-editor/core");
|
|
2853
|
+
var COMPOSE_PRESETS = [...import_core15.DOCUMENT_PROFILE_NAMES];
|
|
2854
|
+
var PRESET_PROFILES = import_core15.DOCUMENT_PROFILES;
|
|
2793
2855
|
function bodyToBlocks(body) {
|
|
2794
2856
|
const blocks = [];
|
|
2795
2857
|
for (const chunk of body.split(/\n\s*\n/)) {
|
|
@@ -2850,17 +2912,17 @@ function buildDocumentSpec(preset, input) {
|
|
|
2850
2912
|
},
|
|
2851
2913
|
heading: {
|
|
2852
2914
|
font_family: profile.fontFamily,
|
|
2853
|
-
font_size_pt: profile.bodySizePt +
|
|
2915
|
+
font_size_pt: profile.bodySizePt + import_core15.COMPOSE_STYLE_ROWS.heading.sizeDeltaPt,
|
|
2854
2916
|
bold: true,
|
|
2855
|
-
spacing_before_pt:
|
|
2856
|
-
spacing_after_pt:
|
|
2917
|
+
spacing_before_pt: import_core15.COMPOSE_STYLE_ROWS.heading.spacingBeforePt,
|
|
2918
|
+
spacing_after_pt: import_core15.COMPOSE_STYLE_ROWS.heading.spacingAfterPt
|
|
2857
2919
|
},
|
|
2858
2920
|
title: {
|
|
2859
2921
|
font_family: profile.fontFamily,
|
|
2860
|
-
font_size_pt: profile.bodySizePt +
|
|
2922
|
+
font_size_pt: profile.bodySizePt + import_core15.COMPOSE_STYLE_ROWS.title.sizeDeltaPt,
|
|
2861
2923
|
bold: true,
|
|
2862
2924
|
align: "center",
|
|
2863
|
-
spacing_after_pt:
|
|
2925
|
+
spacing_after_pt: import_core15.COMPOSE_STYLE_ROWS.title.spacingAfterPt
|
|
2864
2926
|
}
|
|
2865
2927
|
},
|
|
2866
2928
|
sections: [section]
|
|
@@ -2869,7 +2931,7 @@ function buildDocumentSpec(preset, input) {
|
|
|
2869
2931
|
}
|
|
2870
2932
|
|
|
2871
2933
|
// src/components-support.ts
|
|
2872
|
-
var
|
|
2934
|
+
var import_core16 = require("@hwp-editor/core");
|
|
2873
2935
|
function millimetres(value) {
|
|
2874
2936
|
return `${Math.round(value * 10) / 10} mm`;
|
|
2875
2937
|
}
|
|
@@ -2925,7 +2987,7 @@ function insertionPreflight(blocks, documentName, t) {
|
|
|
2925
2987
|
function insertionOf(error) {
|
|
2926
2988
|
if (typeof error !== "object" || error === null) return void 0;
|
|
2927
2989
|
const value = error.insertion;
|
|
2928
|
-
return (0,
|
|
2990
|
+
return (0, import_core16.isInsertionRefusal)(value) ? value : void 0;
|
|
2929
2991
|
}
|
|
2930
2992
|
function overflowingBodyMm(error) {
|
|
2931
2993
|
const insertion = insertionOf(error);
|
|
@@ -2935,10 +2997,10 @@ function isLayoutOverflow(error) {
|
|
|
2935
2997
|
return insertionOf(error)?.kind === "layout_overflow";
|
|
2936
2998
|
}
|
|
2937
2999
|
function wrapped(error, text, detail) {
|
|
2938
|
-
if ((0,
|
|
3000
|
+
if ((0, import_core16.isHwpEngineError)(error)) {
|
|
2939
3001
|
const insertion = insertionOf(error);
|
|
2940
3002
|
return Object.assign(
|
|
2941
|
-
new
|
|
3003
|
+
new import_core16.HwpEngineError(error.code, text, {
|
|
2942
3004
|
...error.status === void 0 ? {} : { status: error.status },
|
|
2943
3005
|
cause: error,
|
|
2944
3006
|
...insertion === void 0 ? {} : { insertion },
|
|
@@ -2959,7 +3021,7 @@ function refusalReason(message) {
|
|
|
2959
3021
|
}
|
|
2960
3022
|
function isRefusedInsertion(error) {
|
|
2961
3023
|
if (insertionOf(error) !== void 0) return true;
|
|
2962
|
-
return (0,
|
|
3024
|
+
return (0, import_core16.isHwpEngineError)(error) && (error.code === "failed" || error.code === "bad_request");
|
|
2963
3025
|
}
|
|
2964
3026
|
function insertionFailure(error, blocks, t) {
|
|
2965
3027
|
const message = error instanceof Error ? error.message : String(error);
|
|
@@ -2987,7 +3049,7 @@ var STEP_KEYS = {
|
|
|
2987
3049
|
component_load: "components.step.load"
|
|
2988
3050
|
};
|
|
2989
3051
|
function componentRefusalText(error, t) {
|
|
2990
|
-
if (!(0,
|
|
3052
|
+
if (!(0, import_core16.isComponentError)(error)) return null;
|
|
2991
3053
|
return t("components.refused", {
|
|
2992
3054
|
code: error.code,
|
|
2993
3055
|
source: error.source,
|
|
@@ -3016,7 +3078,7 @@ var PRESET_LABEL_KEYS = {
|
|
|
3016
3078
|
};
|
|
3017
3079
|
function ComposePanel(props) {
|
|
3018
3080
|
const { engine, t, onError, store, state, loadEpoch, loadSettled, loadInFlight } = useHwpEditorContext();
|
|
3019
|
-
const components = props.components ??
|
|
3081
|
+
const components = props.components ?? import_core17.STARTER_COMPONENTS;
|
|
3020
3082
|
const [preset, setPreset] = (0, import_react11.useState)("official");
|
|
3021
3083
|
const [title, setTitle] = (0, import_react11.useState)("");
|
|
3022
3084
|
const [author, setAuthor] = (0, import_react11.useState)("");
|
|
@@ -3138,7 +3200,7 @@ function ComposePanel(props) {
|
|
|
3138
3200
|
const source = store.getState().document;
|
|
3139
3201
|
try {
|
|
3140
3202
|
const written = title.trim();
|
|
3141
|
-
const spec = assembling ? (0,
|
|
3203
|
+
const spec = assembling ? (0, import_core17.documentSpecFromComponents)(
|
|
3142
3204
|
assembly.map((row) => ({ component: row.component, values: row.values })),
|
|
3143
3205
|
written === "" ? {} : { title: written }
|
|
3144
3206
|
) : buildDocumentSpec(preset, { title, author, body });
|
|
@@ -3383,18 +3445,18 @@ function ComposePanel(props) {
|
|
|
3383
3445
|
|
|
3384
3446
|
// src/ComponentsPanel.tsx
|
|
3385
3447
|
var import_react12 = require("react");
|
|
3386
|
-
var
|
|
3448
|
+
var import_core18 = require("@hwp-editor/core");
|
|
3387
3449
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
3388
3450
|
function componentsSupportReason(capabilities, t) {
|
|
3389
3451
|
if (capabilities === null) return "";
|
|
3390
3452
|
if (capabilities.editOps !== "v1") return t("components.disabledChannel");
|
|
3391
|
-
if (!(0,
|
|
3392
|
-
return t("components.disabledVersion", { version:
|
|
3453
|
+
if (!(0, import_core18.editReportSupported)(capabilities.version)) {
|
|
3454
|
+
return t("components.disabledVersion", { version: import_core18.EDIT_REPORT_MIN_VERSION });
|
|
3393
3455
|
}
|
|
3394
3456
|
return "";
|
|
3395
3457
|
}
|
|
3396
3458
|
function ComponentsPanel({
|
|
3397
|
-
components =
|
|
3459
|
+
components = import_core18.STARTER_COMPONENTS,
|
|
3398
3460
|
disabledReason = "",
|
|
3399
3461
|
beforeDisabledReason = "",
|
|
3400
3462
|
refusalFor,
|
|
@@ -3618,7 +3680,7 @@ function pendingTargetLabel(op, t, resolvers = {}, envelope = null) {
|
|
|
3618
3680
|
}
|
|
3619
3681
|
|
|
3620
3682
|
// src/messages.ts
|
|
3621
|
-
var
|
|
3683
|
+
var import_core19 = require("@hwp-editor/core");
|
|
3622
3684
|
var en = {
|
|
3623
3685
|
// Toolbar
|
|
3624
3686
|
"toolbar.toolsAria": "Editing tools",
|
|
@@ -3992,9 +4054,9 @@ var en = {
|
|
|
3992
4054
|
"error.unresolvableAddress": "The engine could not address the edit's paragraph or run. Runs inside some nested paragraphs cannot be addressed. Format text in a top-level paragraph or a table cell, or edit this target in a word processor.",
|
|
3993
4055
|
"error.runRangeConflict": "A run format change was refused because an earlier pending change in that paragraph (text, a link, a field, a bookmark, an image or a cell) may change its text, so the run might no longer name the same characters. Nothing was applied. Remove the format change from the pending list, apply the rest, then format the run again; or queue the format change before the others.",
|
|
3994
4056
|
"error.rangeTagRefused": "This HWP document holds a range mark the engine cannot move, so a pending edit was refused and nothing was applied. Edits that move text around the mark are refused: changing a paragraph's text length, changing a field's value to one of a different length, inserting or deleting a link, field, bookmark or image, or deleting a table. A table cell that holds a mark refuses any change to its content. The engine does not say which edit. Remove those pending edits from the pending list (a same-length text replacement in a paragraph, or a same-length field value, is accepted) and apply the rest. To make those edits, convert the document to HWPX, which drops the range marks, or remove the mark in Hangul, then reopen it; reopening drops the pending list.",
|
|
3995
|
-
"error.stoppedWithoutDiagnostic":
|
|
4057
|
+
"error.stoppedWithoutDiagnostic": import_core19.STOPPED_WITHOUT_DIAGNOSTIC,
|
|
3996
4058
|
// The same rule for a failure with stderr but no Error: line (#140).
|
|
3997
|
-
"error.noEngineCause":
|
|
4059
|
+
"error.noEngineCause": import_core19.NO_ENGINE_CAUSE,
|
|
3998
4060
|
"error.badEnvelope": (p) => `The host returned a document read this editor cannot use: ${p.detail}. Have the host emit segment-envelope-v2 data, then reload.`,
|
|
3999
4061
|
"error.readOnlyReplacement": "The editor became read-only before the template could be applied; switch to an editable document and retry.",
|
|
4000
4062
|
"error.pendingReplacement": "Pending edits would be lost; apply or clear them before replacing this document.",
|
|
@@ -4070,14 +4132,14 @@ var en = {
|
|
|
4070
4132
|
"image.insert": "Insert image",
|
|
4071
4133
|
"image.delete": "Delete image",
|
|
4072
4134
|
"image.file": "PNG/JPEG image file",
|
|
4073
|
-
"image.fileHint": `Choose a PNG or JPEG image up to ${
|
|
4135
|
+
"image.fileHint": `Choose a PNG or JPEG image up to ${import_core19.MAX_IMAGE_ASSET_MIB} MiB.`,
|
|
4074
4136
|
"image.unsupported": "Image upload needs a host with an upload command. With the agent-hwp engine, use 1.4.0 or newer, the version this editor verifies uploads against. A supplied engine has to advertise image-asset uploads. The desktop app has no upload command, and this editor cannot insert a picture from a local file, so insert the picture in a word processor and reopen the document here.",
|
|
4075
4137
|
"image.anchor": "Insert after paragraph text",
|
|
4076
4138
|
"image.deleteAnchor": "Image anchor text to delete",
|
|
4077
4139
|
"image.width": "Width (mm)",
|
|
4078
4140
|
"image.height": "Height (mm)",
|
|
4079
4141
|
"image.reading": "Reading image...",
|
|
4080
|
-
"image.invalidSize": `The image is empty or exceeds ${
|
|
4142
|
+
"image.invalidSize": `The image is empty or exceeds ${import_core19.MAX_IMAGE_ASSET_MIB} MiB; choose a smaller PNG/JPEG file.`,
|
|
4081
4143
|
"image.invalidType": "The file is not PNG/JPEG image data; choose a supported image.",
|
|
4082
4144
|
"image.readError": "The image could not be read; select the file again.",
|
|
4083
4145
|
"error.prefix.image": "Image operation failed",
|
|
@@ -4527,14 +4589,14 @@ var ko = {
|
|
|
4527
4589
|
"image.insert": "\uC774\uBBF8\uC9C0 \uC0BD\uC785",
|
|
4528
4590
|
"image.delete": "\uC774\uBBF8\uC9C0 \uC0AD\uC81C",
|
|
4529
4591
|
"image.file": "PNG/JPEG \uC774\uBBF8\uC9C0 \uD30C\uC77C",
|
|
4530
|
-
"image.fileHint": `${
|
|
4592
|
+
"image.fileHint": `${import_core19.MAX_IMAGE_ASSET_MIB} MiB \uC774\uD558\uC758 PNG \uB610\uB294 JPEG \uC774\uBBF8\uC9C0\uB97C \uC120\uD0DD\uD558\uC138\uC694.`,
|
|
4531
4593
|
"image.unsupported": "\uC774\uBBF8\uC9C0 \uC5C5\uB85C\uB4DC\uB294 \uC5C5\uB85C\uB4DC \uBA85\uB839\uC774 \uC788\uB294 \uD638\uC2A4\uD2B8\uAC00 \uD544\uC694\uD569\uB2C8\uB2E4. agent-hwp \uC5D4\uC9C4\uC774\uB77C\uBA74 \uC774 \uD3B8\uC9D1\uAE30\uAC00 \uC5C5\uB85C\uB4DC\uB97C \uAC80\uC99D\uD55C 1.4.0 \uC774\uC0C1\uC744 \uC0AC\uC6A9\uD558\uC138\uC694. \uC5D4\uC9C4\uC744 \uC9C1\uC811 \uACF5\uAE09\uD558\uB294 \uD638\uC2A4\uD2B8\uB294 \uC774\uBBF8\uC9C0 \uC790\uC0B0 \uC5C5\uB85C\uB4DC\uB97C \uC9C0\uC6D0\uD55C\uB2E4\uACE0 \uC54C\uB824\uC57C \uD569\uB2C8\uB2E4. \uB370\uC2A4\uD06C\uD1B1 \uC571\uC5D0\uB294 \uC5C5\uB85C\uB4DC \uBA85\uB839\uC774 \uC5C6\uACE0 \uC774 \uD3B8\uC9D1\uAE30\uB294 \uB85C\uCEEC \uD30C\uC77C\uC5D0\uC11C \uADF8\uB9BC\uC744 \uB123\uC744 \uC218 \uC5C6\uC73C\uBBC0\uB85C, \uC6CC\uB4DC\uD504\uB85C\uC138\uC11C\uC5D0\uC11C \uADF8\uB9BC\uC744 \uB123\uC740 \uB4A4 \uC774 \uD3B8\uC9D1\uAE30\uC5D0\uC11C \uBB38\uC11C\uB97C \uB2E4\uC2DC \uC5EC\uC138\uC694.",
|
|
4532
4594
|
"image.anchor": "\uC774 \uBB38\uB2E8 \uBB38\uC790\uC5F4 \uB4A4\uC5D0 \uC0BD\uC785",
|
|
4533
4595
|
"image.deleteAnchor": "\uC0AD\uC81C\uD560 \uC774\uBBF8\uC9C0\uC758 \uC704\uCE58 \uBB38\uC790\uC5F4",
|
|
4534
4596
|
"image.width": "\uB108\uBE44 (mm)",
|
|
4535
4597
|
"image.height": "\uB192\uC774 (mm)",
|
|
4536
4598
|
"image.reading": "\uC774\uBBF8\uC9C0 \uC77D\uB294 \uC911...",
|
|
4537
|
-
"image.invalidSize": `\uC774\uBBF8\uC9C0\uAC00 \uBE44\uC5B4 \uC788\uAC70\uB098 ${
|
|
4599
|
+
"image.invalidSize": `\uC774\uBBF8\uC9C0\uAC00 \uBE44\uC5B4 \uC788\uAC70\uB098 ${import_core19.MAX_IMAGE_ASSET_MIB} MiB\uB97C \uCD08\uACFC\uD569\uB2C8\uB2E4. \uB354 \uC791\uC740 PNG/JPEG \uD30C\uC77C\uC744 \uC120\uD0DD\uD558\uC138\uC694.`,
|
|
4538
4600
|
"image.invalidType": "PNG/JPEG \uC774\uBBF8\uC9C0 \uB370\uC774\uD130\uAC00 \uC544\uB2D9\uB2C8\uB2E4. \uC9C0\uC6D0\uD558\uB294 \uC774\uBBF8\uC9C0 \uD30C\uC77C\uC744 \uC120\uD0DD\uD558\uC138\uC694.",
|
|
4539
4601
|
"image.readError": "\uC774\uBBF8\uC9C0\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uD30C\uC77C\uC744 \uB2E4\uC2DC \uC120\uD0DD\uD558\uC138\uC694.",
|
|
4540
4602
|
"error.prefix.image": "\uC774\uBBF8\uC9C0 \uC791\uC5C5 \uC2E4\uD328",
|
|
@@ -4597,16 +4659,16 @@ function selectionParagraphs(envelope, state) {
|
|
|
4597
4659
|
const seen = /* @__PURE__ */ new Set();
|
|
4598
4660
|
const paragraphs = [];
|
|
4599
4661
|
for (const ref of refs) {
|
|
4600
|
-
const segment = (0,
|
|
4662
|
+
const segment = (0, import_core20.segmentAtRef)(envelope, ref);
|
|
4601
4663
|
if (segment === void 0) continue;
|
|
4602
|
-
for (const paragraph of (0,
|
|
4664
|
+
for (const paragraph of (0, import_core20.resolveSelection)(envelope, segment).paragraphs) {
|
|
4603
4665
|
const key = paragraph.id ?? `${paragraph.section}:${paragraph.para}:${paragraph.start}`;
|
|
4604
4666
|
if (seen.has(key)) continue;
|
|
4605
4667
|
seen.add(key);
|
|
4606
4668
|
paragraphs.push(paragraph);
|
|
4607
4669
|
}
|
|
4608
4670
|
}
|
|
4609
|
-
return paragraphs.sort(
|
|
4671
|
+
return paragraphs.sort(import_core20.compareSegments);
|
|
4610
4672
|
}
|
|
4611
4673
|
function insertAnchor(covered, position) {
|
|
4612
4674
|
const paragraph = position === "before" ? covered[0] : covered[covered.length - 1];
|
|
@@ -4644,7 +4706,7 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
4644
4706
|
className,
|
|
4645
4707
|
style
|
|
4646
4708
|
} = props;
|
|
4647
|
-
const catalogue = components ??
|
|
4709
|
+
const catalogue = components ?? import_core20.STARTER_COMPONENTS;
|
|
4648
4710
|
const cbRef = (0, import_react13.useRef)({ onReady, onError, onChange, onDirtyChange });
|
|
4649
4711
|
(0, import_react13.useEffect)(() => {
|
|
4650
4712
|
cbRef.current = { onReady, onError, onChange, onDirtyChange };
|
|
@@ -4662,7 +4724,7 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
4662
4724
|
cbRef.current.onDirtyChange?.(dirty2);
|
|
4663
4725
|
}, []);
|
|
4664
4726
|
const t = (0, import_react13.useMemo)(() => createT(locale, messages), [locale, messages]);
|
|
4665
|
-
const [store] = (0, import_react13.useState)(() => (0,
|
|
4727
|
+
const [store] = (0, import_react13.useState)(() => (0, import_core20.createStore)());
|
|
4666
4728
|
const state = (0, import_react13.useSyncExternalStore)(store.subscribe, store.getState, store.getState);
|
|
4667
4729
|
const [envelope, setEnvelope] = (0, import_react13.useState)(null);
|
|
4668
4730
|
const [capabilities, setCapabilities] = (0, import_react13.useState)(null);
|
|
@@ -4715,9 +4777,9 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
4715
4777
|
const readEnvelope = (0, import_react13.useCallback)(async (target) => {
|
|
4716
4778
|
const read = await engine.read(target);
|
|
4717
4779
|
try {
|
|
4718
|
-
return (0,
|
|
4780
|
+
return (0, import_core20.validateCatEnvelope)(read);
|
|
4719
4781
|
} catch (e) {
|
|
4720
|
-
throw new
|
|
4782
|
+
throw new import_core20.HwpEngineError(
|
|
4721
4783
|
"failed",
|
|
4722
4784
|
latestT.current("error.badEnvelope", { detail: envelopeProblem(e instanceof Error ? e.message : String(e)) }),
|
|
4723
4785
|
{ cause: e }
|
|
@@ -4736,7 +4798,7 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
4736
4798
|
insertedTriedFor.current = envelope;
|
|
4737
4799
|
const hidden = [];
|
|
4738
4800
|
const paragraphs = pendingInserted.flatMap((id) => {
|
|
4739
|
-
const segment = (0,
|
|
4801
|
+
const segment = (0, import_core20.segmentAtRef)(envelope, { id, section: 0, para: 0 });
|
|
4740
4802
|
if (segment === void 0) hidden.push(id);
|
|
4741
4803
|
return segment === void 0 || segment.kind !== "para" ? [] : [segment];
|
|
4742
4804
|
});
|
|
@@ -4744,9 +4806,9 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
4744
4806
|
if (paragraphs.length === 0) return;
|
|
4745
4807
|
store.dispatch({
|
|
4746
4808
|
type: "selectMany",
|
|
4747
|
-
selections: paragraphs.map(
|
|
4748
|
-
primary: (0,
|
|
4749
|
-
anchor: (0,
|
|
4809
|
+
selections: paragraphs.map(import_core20.segmentRef),
|
|
4810
|
+
primary: (0, import_core20.segmentRef)(paragraphs[0]),
|
|
4811
|
+
anchor: (0, import_core20.segmentRef)(paragraphs[0])
|
|
4750
4812
|
});
|
|
4751
4813
|
setInsertedHidden(hidden.length === 0 ? null : { envelope, selections: store.getState().selections, ids: hidden });
|
|
4752
4814
|
}, [envelope, pendingInserted, store]);
|
|
@@ -4827,22 +4889,22 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
4827
4889
|
const queueImage = (0, import_react13.useCallback)((op, asset) => {
|
|
4828
4890
|
const snapshot = store.getState();
|
|
4829
4891
|
if (!editable || envelope === null || snapshot.document === null || snapshot.status === "applying") return;
|
|
4830
|
-
if (capabilities?.imageAssets !== "v1") throw new
|
|
4831
|
-
if (op.path !== asset.name) throw new
|
|
4892
|
+
if (capabilities?.imageAssets !== "v1") throw new import_core20.HwpEngineError("unavailable", t("image.unsupported"));
|
|
4893
|
+
if (op.path !== asset.name) throw new import_core20.HwpEngineError("bad_request", t("image.referenceMismatch"));
|
|
4832
4894
|
const active = snapshot.pendingOps.flatMap((pending) => {
|
|
4833
4895
|
const stored = imageAssets.current.get(pending);
|
|
4834
4896
|
return stored === void 0 ? [] : [stored];
|
|
4835
4897
|
});
|
|
4836
|
-
if (active.length + 1 >
|
|
4837
|
-
throw new
|
|
4898
|
+
if (active.length + 1 > import_core20.MAX_IMAGE_ASSETS || active.reduce((bytes, image) => bytes + image.data.length, asset.data.length) > import_core20.MAX_IMAGE_ASSETS_TOTAL_BYTES) {
|
|
4899
|
+
throw new import_core20.HwpEngineError("bad_request", t("image.queueLimit", { count: import_core20.MAX_IMAGE_ASSETS, miB: import_core20.MAX_IMAGE_ASSETS_TOTAL_BYTES / (1024 * 1024) }));
|
|
4838
4900
|
}
|
|
4839
|
-
(0,
|
|
4901
|
+
(0, import_core20.validateImageAssets)([...active, asset]);
|
|
4840
4902
|
imageAssets.current.set(op, { name: asset.name, data: asset.data.slice() });
|
|
4841
4903
|
store.dispatch({ type: "queueOp", op });
|
|
4842
4904
|
}, [editable, envelope, capabilities, store, t]);
|
|
4843
4905
|
(0, import_react13.useEffect)(() => {
|
|
4844
4906
|
if (envelope === null || state.selection === null) return;
|
|
4845
|
-
const segment = (0,
|
|
4907
|
+
const segment = (0, import_core20.segmentAtRef)(envelope, state.selection);
|
|
4846
4908
|
if (segment === void 0) return;
|
|
4847
4909
|
const next = hostsTable(envelope, segment) ? "table" : "para";
|
|
4848
4910
|
setTab((current) => current === "components" || current === "styles" ? current : next);
|
|
@@ -4989,17 +5051,17 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
4989
5051
|
noteRefusal(t("error.loadingReplacement"));
|
|
4990
5052
|
return;
|
|
4991
5053
|
}
|
|
4992
|
-
const segment = snapshot.selection === null ? void 0 : (0,
|
|
5054
|
+
const segment = snapshot.selection === null ? void 0 : (0, import_core20.segmentAtRef)(envelope, snapshot.selection);
|
|
4993
5055
|
const covered = selectionParagraphs(envelope, snapshot);
|
|
4994
5056
|
const address = segment === void 0 ? null : insertAnchor(covered, position);
|
|
4995
5057
|
if (address === null) return;
|
|
4996
|
-
if (position === "before" && covered[0] !== void 0 && (0,
|
|
5058
|
+
if (position === "before" && covered[0] !== void 0 && (0, import_core20.isSectionDefinitionParagraph)(covered[0])) return;
|
|
4997
5059
|
let blocks;
|
|
4998
5060
|
let styles2;
|
|
4999
5061
|
try {
|
|
5000
|
-
const filled = (0,
|
|
5062
|
+
const filled = (0, import_core20.substituteParams)(component, values, component.name);
|
|
5001
5063
|
blocks = filled.blocks;
|
|
5002
|
-
styles2 = (0,
|
|
5064
|
+
styles2 = (0, import_core20.componentStyleMap)([filled]);
|
|
5003
5065
|
} catch (error) {
|
|
5004
5066
|
const shown = toError(componentFailure(error, t));
|
|
5005
5067
|
noteNotice(shown.message, shown);
|
|
@@ -5052,7 +5114,7 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
5052
5114
|
}
|
|
5053
5115
|
let ids;
|
|
5054
5116
|
try {
|
|
5055
|
-
ids = (0,
|
|
5117
|
+
ids = (0, import_core20.insertedParagraphIds)(outcome);
|
|
5056
5118
|
} catch (error) {
|
|
5057
5119
|
noteNotice(toError(error).message, error);
|
|
5058
5120
|
return;
|
|
@@ -5063,12 +5125,12 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
5063
5125
|
[emitError, engine, envelope, noteRefusal, replaceDocument, store, t]
|
|
5064
5126
|
);
|
|
5065
5127
|
const selectedTargets = envelope === null || state.selection === null ? void 0 : (() => {
|
|
5066
|
-
const segment = (0,
|
|
5067
|
-
return segment === void 0 ? void 0 : (0,
|
|
5128
|
+
const segment = (0, import_core20.segmentAtRef)(envelope, state.selection);
|
|
5129
|
+
return segment === void 0 ? void 0 : (0, import_core20.resolveSelection)(envelope, segment);
|
|
5068
5130
|
})();
|
|
5069
5131
|
const componentAnchor = envelope === null || state.selection === null ? [] : selectionParagraphs(envelope, state);
|
|
5070
5132
|
const selectedAddress = insertAnchor(componentAnchor, "after");
|
|
5071
|
-
const beforeDisabledReason = componentAnchor[0] !== void 0 && (0,
|
|
5133
|
+
const beforeDisabledReason = componentAnchor[0] !== void 0 && (0, import_core20.isSectionDefinitionParagraph)(componentAnchor[0]) ? t("components.positionBeforeLocked") : "";
|
|
5072
5134
|
const componentDisabled = componentsSupportReason(capabilities, t) || (state.pendingOps.length > 0 ? t("components.pendingEdits") : "") || (state.selection === null ? t("components.noSelection") : selectedAddress !== null ? "" : selectedTargets?.refusal === "cell" ? t("segment.cellSelectionRefused") : selectedTargets?.refusal === "table" ? t("segment.tableSelectionRefused") : selectedTargets?.refusal === "container" ? t("segment.containerSelectionRefused") : t("components.noAddress"));
|
|
5073
5135
|
const componentRefusal = (0, import_react13.useCallback)(
|
|
5074
5136
|
(component) => insertionPreflight(component.blocks, state.document?.name ?? "", t),
|