@hwp-editor/react 1.4.0 → 1.4.2
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 +212 -142
- 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 +2 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +91 -21
- 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,13 +2997,15 @@ 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);
|
|
3002
|
+
const refusal = engineRefusalKind(error);
|
|
2940
3003
|
return Object.assign(
|
|
2941
|
-
new
|
|
3004
|
+
new import_core16.HwpEngineError(error.code, text, {
|
|
2942
3005
|
...error.status === void 0 ? {} : { status: error.status },
|
|
2943
3006
|
cause: error,
|
|
2944
3007
|
...insertion === void 0 ? {} : { insertion },
|
|
3008
|
+
...refusal === void 0 ? {} : { refusal },
|
|
2945
3009
|
// The marker survives too: a host's `onError` branches on the same
|
|
2946
3010
|
// structured fields the transport set, so a wrapper that drops one
|
|
2947
3011
|
// hands it a failure it cannot classify (#91).
|
|
@@ -2959,11 +3023,14 @@ function refusalReason(message) {
|
|
|
2959
3023
|
}
|
|
2960
3024
|
function isRefusedInsertion(error) {
|
|
2961
3025
|
if (insertionOf(error) !== void 0) return true;
|
|
2962
|
-
return (0,
|
|
3026
|
+
return (0, import_core16.isHwpEngineError)(error) && (error.code === "failed" || error.code === "bad_request");
|
|
2963
3027
|
}
|
|
2964
3028
|
function insertionFailure(error, blocks, t) {
|
|
2965
3029
|
const message = error instanceof Error ? error.message : String(error);
|
|
2966
3030
|
if (!isRefusedInsertion(error)) return error;
|
|
3031
|
+
if (engineRefusalKind(error) === "output_validation") {
|
|
3032
|
+
return wrapped(error, t("error.outputValidation"), message);
|
|
3033
|
+
}
|
|
2967
3034
|
const insertion = insertionOf(error);
|
|
2968
3035
|
if (insertion?.kind === "unknown_style") {
|
|
2969
3036
|
return wrapped(error, t("components.unknownStyle", { style: insertion.style }), message);
|
|
@@ -2987,7 +3054,7 @@ var STEP_KEYS = {
|
|
|
2987
3054
|
component_load: "components.step.load"
|
|
2988
3055
|
};
|
|
2989
3056
|
function componentRefusalText(error, t) {
|
|
2990
|
-
if (!(0,
|
|
3057
|
+
if (!(0, import_core16.isComponentError)(error)) return null;
|
|
2991
3058
|
return t("components.refused", {
|
|
2992
3059
|
code: error.code,
|
|
2993
3060
|
source: error.source,
|
|
@@ -3016,7 +3083,7 @@ var PRESET_LABEL_KEYS = {
|
|
|
3016
3083
|
};
|
|
3017
3084
|
function ComposePanel(props) {
|
|
3018
3085
|
const { engine, t, onError, store, state, loadEpoch, loadSettled, loadInFlight } = useHwpEditorContext();
|
|
3019
|
-
const components = props.components ??
|
|
3086
|
+
const components = props.components ?? import_core17.STARTER_COMPONENTS;
|
|
3020
3087
|
const [preset, setPreset] = (0, import_react11.useState)("official");
|
|
3021
3088
|
const [title, setTitle] = (0, import_react11.useState)("");
|
|
3022
3089
|
const [author, setAuthor] = (0, import_react11.useState)("");
|
|
@@ -3138,7 +3205,7 @@ function ComposePanel(props) {
|
|
|
3138
3205
|
const source = store.getState().document;
|
|
3139
3206
|
try {
|
|
3140
3207
|
const written = title.trim();
|
|
3141
|
-
const spec = assembling ? (0,
|
|
3208
|
+
const spec = assembling ? (0, import_core17.documentSpecFromComponents)(
|
|
3142
3209
|
assembly.map((row) => ({ component: row.component, values: row.values })),
|
|
3143
3210
|
written === "" ? {} : { title: written }
|
|
3144
3211
|
) : buildDocumentSpec(preset, { title, author, body });
|
|
@@ -3383,18 +3450,18 @@ function ComposePanel(props) {
|
|
|
3383
3450
|
|
|
3384
3451
|
// src/ComponentsPanel.tsx
|
|
3385
3452
|
var import_react12 = require("react");
|
|
3386
|
-
var
|
|
3453
|
+
var import_core18 = require("@hwp-editor/core");
|
|
3387
3454
|
var import_jsx_runtime12 = require("react/jsx-runtime");
|
|
3388
3455
|
function componentsSupportReason(capabilities, t) {
|
|
3389
3456
|
if (capabilities === null) return "";
|
|
3390
3457
|
if (capabilities.editOps !== "v1") return t("components.disabledChannel");
|
|
3391
|
-
if (!(0,
|
|
3392
|
-
return t("components.disabledVersion", { version:
|
|
3458
|
+
if (!(0, import_core18.editReportSupported)(capabilities.version)) {
|
|
3459
|
+
return t("components.disabledVersion", { version: import_core18.EDIT_REPORT_MIN_VERSION });
|
|
3393
3460
|
}
|
|
3394
3461
|
return "";
|
|
3395
3462
|
}
|
|
3396
3463
|
function ComponentsPanel({
|
|
3397
|
-
components =
|
|
3464
|
+
components = import_core18.STARTER_COMPONENTS,
|
|
3398
3465
|
disabledReason = "",
|
|
3399
3466
|
beforeDisabledReason = "",
|
|
3400
3467
|
refusalFor,
|
|
@@ -3618,7 +3685,7 @@ function pendingTargetLabel(op, t, resolvers = {}, envelope = null) {
|
|
|
3618
3685
|
}
|
|
3619
3686
|
|
|
3620
3687
|
// src/messages.ts
|
|
3621
|
-
var
|
|
3688
|
+
var import_core19 = require("@hwp-editor/core");
|
|
3622
3689
|
var en = {
|
|
3623
3690
|
// Toolbar
|
|
3624
3691
|
"toolbar.toolsAria": "Editing tools",
|
|
@@ -3988,13 +4055,14 @@ var en = {
|
|
|
3988
4055
|
"error.staleReplacement": "The document changed during template work; reopen it and try again.",
|
|
3989
4056
|
"error.staleCompose": "The open document changed while the new document was being composed; compose again.",
|
|
3990
4057
|
"error.stalePreview": "The document changed while this preview was being made; preview again on the open document.",
|
|
4058
|
+
"error.outputValidation": "The engine's output preservation check refused to write the edited file. One known cause is HWPX font metadata (typeInfo) that HWP5 cannot represent. In that case, save as .hwpx to preserve the metadata. If you accept its loss, explicitly run ahwp convert in.hwpx -o in.hwp without --strict, reopen in.hwp, and retry. For other causes, rerun the same edit with the engine's --verify option and inspect the verification report.",
|
|
3991
4059
|
"error.unmatchedReplace": "The engine found no text to replace in that paragraph, so nothing was applied. Select the text again and retry.",
|
|
3992
4060
|
"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
4061
|
"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
4062
|
"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":
|
|
4063
|
+
"error.stoppedWithoutDiagnostic": import_core19.STOPPED_WITHOUT_DIAGNOSTIC,
|
|
3996
4064
|
// The same rule for a failure with stderr but no Error: line (#140).
|
|
3997
|
-
"error.noEngineCause":
|
|
4065
|
+
"error.noEngineCause": import_core19.NO_ENGINE_CAUSE,
|
|
3998
4066
|
"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
4067
|
"error.readOnlyReplacement": "The editor became read-only before the template could be applied; switch to an editable document and retry.",
|
|
4000
4068
|
"error.pendingReplacement": "Pending edits would be lost; apply or clear them before replacing this document.",
|
|
@@ -4070,14 +4138,14 @@ var en = {
|
|
|
4070
4138
|
"image.insert": "Insert image",
|
|
4071
4139
|
"image.delete": "Delete image",
|
|
4072
4140
|
"image.file": "PNG/JPEG image file",
|
|
4073
|
-
"image.fileHint": `Choose a PNG or JPEG image up to ${
|
|
4141
|
+
"image.fileHint": `Choose a PNG or JPEG image up to ${import_core19.MAX_IMAGE_ASSET_MIB} MiB.`,
|
|
4074
4142
|
"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
4143
|
"image.anchor": "Insert after paragraph text",
|
|
4076
4144
|
"image.deleteAnchor": "Image anchor text to delete",
|
|
4077
4145
|
"image.width": "Width (mm)",
|
|
4078
4146
|
"image.height": "Height (mm)",
|
|
4079
4147
|
"image.reading": "Reading image...",
|
|
4080
|
-
"image.invalidSize": `The image is empty or exceeds ${
|
|
4148
|
+
"image.invalidSize": `The image is empty or exceeds ${import_core19.MAX_IMAGE_ASSET_MIB} MiB; choose a smaller PNG/JPEG file.`,
|
|
4081
4149
|
"image.invalidType": "The file is not PNG/JPEG image data; choose a supported image.",
|
|
4082
4150
|
"image.readError": "The image could not be read; select the file again.",
|
|
4083
4151
|
"error.prefix.image": "Image operation failed",
|
|
@@ -4446,6 +4514,7 @@ var ko = {
|
|
|
4446
4514
|
"error.staleReplacement": "\uD15C\uD50C\uB9BF \uC791\uC5C5 \uC911 \uBB38\uC11C\uAC00 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uBB38\uC11C\uB97C \uB2E4\uC2DC \uC5F0 \uB4A4 \uC7AC\uC2DC\uB3C4\uD558\uC138\uC694.",
|
|
4447
4515
|
"error.staleCompose": "\uC0C8 \uBB38\uC11C\uB97C \uC791\uC131\uD558\uB294 \uB3D9\uC548 \uC5F4\uB9B0 \uBB38\uC11C\uAC00 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uB2E4\uC2DC \uC791\uC131\uD558\uC138\uC694.",
|
|
4448
4516
|
"error.stalePreview": "\uBBF8\uB9AC\uBCF4\uAE30\uB97C \uB9CC\uB4DC\uB294 \uB3D9\uC548 \uBB38\uC11C\uAC00 \uBC14\uB00C\uC5C8\uC2B5\uB2C8\uB2E4. \uC5F4\uB9B0 \uBB38\uC11C\uC5D0\uC11C \uB2E4\uC2DC \uBBF8\uB9AC\uBCF4\uAE30\uD558\uC138\uC694.",
|
|
4517
|
+
"error.outputValidation": "\uC5D4\uC9C4\uC758 \uCD9C\uB825 \uBCF4\uC874 \uAC80\uC0AC\uC5D0\uC11C \uD3B8\uC9D1 \uACB0\uACFC \uD30C\uC77C \uC4F0\uAE30\uB97C \uAC70\uBD80\uD588\uC2B5\uB2C8\uB2E4. \uC54C\uB824\uC9C4 \uC6D0\uC778 \uC911 \uD558\uB098\uB294 HWP5\uB85C \uD45C\uD604\uD560 \uC218 \uC5C6\uB294 HWPX \uAE00\uAF34 \uBA54\uD0C0\uB370\uC774\uD130(typeInfo)\uC785\uB2C8\uB2E4. \uC774 \uACBD\uC6B0 \uBA54\uD0C0\uB370\uC774\uD130\uB97C \uBCF4\uC874\uD558\uB824\uBA74 .hwpx\uB85C \uC800\uC7A5\uD558\uC138\uC694. \uBA54\uD0C0\uB370\uC774\uD130 \uC190\uC2E4\uC744 \uC218\uC6A9\uD55C\uB2E4\uBA74 ahwp convert in.hwpx -o in.hwp\uB97C --strict \uC5C6\uC774 \uBA85\uC2DC\uC801\uC73C\uB85C \uC2E4\uD589\uD558\uACE0, in.hwp\uB97C \uB2E4\uC2DC \uC5F0 \uB4A4 \uC7AC\uC2DC\uB3C4\uD558\uC138\uC694. \uB2E4\uB978 \uC6D0\uC778\uC774\uBA74 \uAC19\uC740 \uD3B8\uC9D1\uC744 \uC5D4\uC9C4\uC758 --verify \uC635\uC158\uACFC \uD568\uAED8 \uB2E4\uC2DC \uC2E4\uD589\uD558\uACE0 \uAC80\uC99D \uBCF4\uACE0\uC11C\uB97C \uD655\uC778\uD558\uC138\uC694.",
|
|
4449
4518
|
"error.unmatchedReplace": "\uD574\uB2F9 \uBB38\uB2E8\uC5D0\uC11C \uBC14\uAFC0 \uD14D\uC2A4\uD2B8\uB97C \uC5D4\uC9C4\uC774 \uCC3E\uC9C0 \uBABB\uD574 \uC544\uBB34\uAC83\uB3C4 \uC801\uC6A9\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uD14D\uC2A4\uD2B8\uB97C \uB2E4\uC2DC \uC120\uD0DD\uD55C \uB4A4 \uC7AC\uC2DC\uB3C4\uD558\uC138\uC694.",
|
|
4450
4519
|
"error.unresolvableAddress": "\uC5D4\uC9C4\uC774 \uD3B8\uC9D1 \uB300\uC0C1 \uBB38\uB2E8\uC774\uB098 run\uC744 \uCC3E\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uC77C\uBD80 \uC911\uCCA9 \uBB38\uB2E8 \uC548\uC758 run\uC740 \uC5D4\uC9C4\uC774 \uC8FC\uC18C\uB85C \uC9C0\uC815\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uCD5C\uC0C1\uC704 \uBB38\uB2E8\uC774\uB098 \uD45C \uC140\uC758 \uD14D\uC2A4\uD2B8\uC5D0 \uC11C\uC2DD\uC744 \uC9C0\uC815\uD558\uAC70\uB098, \uC774 \uB300\uC0C1\uC740 \uC6CC\uB4DC\uD504\uB85C\uC138\uC11C\uC5D0\uC11C \uD3B8\uC9D1\uD558\uC138\uC694.",
|
|
4451
4520
|
"error.runRangeConflict": "\uAC19\uC740 \uBB38\uB2E8\uC5D0 \uB300\uAE30 \uC911\uC778 \uC55E\uC120 \uBCC0\uACBD(\uD14D\uC2A4\uD2B8, \uB9C1\uD06C, \uD544\uB4DC, \uCC45\uAC08\uD53C, \uC774\uBBF8\uC9C0, \uC140)\uC774 \uBB38\uB2E8 \uD14D\uC2A4\uD2B8\uB97C \uBC14\uAFC0 \uC218 \uC788\uC5B4 run\uC774 \uB354 \uC774\uC0C1 \uAC19\uC740 \uAE00\uC790\uB97C \uAC00\uB9AC\uD0A4\uC9C0 \uC54A\uC744 \uC218 \uC788\uC73C\uBBC0\uB85C run \uC11C\uC2DD \uBCC0\uACBD\uC774 \uAC70\uBD80\uB418\uC5C8\uC2B5\uB2C8\uB2E4. \uC544\uBB34\uAC83\uB3C4 \uC801\uC6A9\uB418\uC9C0 \uC54A\uC558\uC2B5\uB2C8\uB2E4. \uB300\uAE30 \uBAA9\uB85D\uC5D0\uC11C \uC11C\uC2DD \uBCC0\uACBD\uC744 \uC81C\uAC70\uD558\uACE0 \uB098\uBA38\uC9C0\uB97C \uC801\uC6A9\uD55C \uB4A4 run \uC11C\uC2DD\uC744 \uB2E4\uC2DC \uC9C0\uC815\uD558\uAC70\uB098, \uC11C\uC2DD \uBCC0\uACBD\uC744 \uB2E4\uB978 \uBCC0\uACBD\uBCF4\uB2E4 \uBA3C\uC800 \uB300\uAE30\uC5F4\uC5D0 \uB123\uC73C\uC138\uC694.",
|
|
@@ -4527,14 +4596,14 @@ var ko = {
|
|
|
4527
4596
|
"image.insert": "\uC774\uBBF8\uC9C0 \uC0BD\uC785",
|
|
4528
4597
|
"image.delete": "\uC774\uBBF8\uC9C0 \uC0AD\uC81C",
|
|
4529
4598
|
"image.file": "PNG/JPEG \uC774\uBBF8\uC9C0 \uD30C\uC77C",
|
|
4530
|
-
"image.fileHint": `${
|
|
4599
|
+
"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
4600
|
"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
4601
|
"image.anchor": "\uC774 \uBB38\uB2E8 \uBB38\uC790\uC5F4 \uB4A4\uC5D0 \uC0BD\uC785",
|
|
4533
4602
|
"image.deleteAnchor": "\uC0AD\uC81C\uD560 \uC774\uBBF8\uC9C0\uC758 \uC704\uCE58 \uBB38\uC790\uC5F4",
|
|
4534
4603
|
"image.width": "\uB108\uBE44 (mm)",
|
|
4535
4604
|
"image.height": "\uB192\uC774 (mm)",
|
|
4536
4605
|
"image.reading": "\uC774\uBBF8\uC9C0 \uC77D\uB294 \uC911...",
|
|
4537
|
-
"image.invalidSize": `\uC774\uBBF8\uC9C0\uAC00 \uBE44\uC5B4 \uC788\uAC70\uB098 ${
|
|
4606
|
+
"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
4607
|
"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
4608
|
"image.readError": "\uC774\uBBF8\uC9C0\uB97C \uC77D\uC744 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uD30C\uC77C\uC744 \uB2E4\uC2DC \uC120\uD0DD\uD558\uC138\uC694.",
|
|
4540
4609
|
"error.prefix.image": "\uC774\uBBF8\uC9C0 \uC791\uC5C5 \uC2E4\uD328",
|
|
@@ -4597,16 +4666,16 @@ function selectionParagraphs(envelope, state) {
|
|
|
4597
4666
|
const seen = /* @__PURE__ */ new Set();
|
|
4598
4667
|
const paragraphs = [];
|
|
4599
4668
|
for (const ref of refs) {
|
|
4600
|
-
const segment = (0,
|
|
4669
|
+
const segment = (0, import_core20.segmentAtRef)(envelope, ref);
|
|
4601
4670
|
if (segment === void 0) continue;
|
|
4602
|
-
for (const paragraph of (0,
|
|
4671
|
+
for (const paragraph of (0, import_core20.resolveSelection)(envelope, segment).paragraphs) {
|
|
4603
4672
|
const key = paragraph.id ?? `${paragraph.section}:${paragraph.para}:${paragraph.start}`;
|
|
4604
4673
|
if (seen.has(key)) continue;
|
|
4605
4674
|
seen.add(key);
|
|
4606
4675
|
paragraphs.push(paragraph);
|
|
4607
4676
|
}
|
|
4608
4677
|
}
|
|
4609
|
-
return paragraphs.sort(
|
|
4678
|
+
return paragraphs.sort(import_core20.compareSegments);
|
|
4610
4679
|
}
|
|
4611
4680
|
function insertAnchor(covered, position) {
|
|
4612
4681
|
const paragraph = position === "before" ? covered[0] : covered[covered.length - 1];
|
|
@@ -4626,7 +4695,8 @@ var REFUSAL_MESSAGE = {
|
|
|
4626
4695
|
unmatched_replace: "error.unmatchedReplace",
|
|
4627
4696
|
run_range_conflict: "error.runRangeConflict",
|
|
4628
4697
|
range_tag: "error.rangeTagRefused",
|
|
4629
|
-
unresolvable_address: "error.unresolvableAddress"
|
|
4698
|
+
unresolvable_address: "error.unresolvableAddress",
|
|
4699
|
+
output_validation: "error.outputValidation"
|
|
4630
4700
|
};
|
|
4631
4701
|
var HwpEditor = (0, import_react13.forwardRef)(
|
|
4632
4702
|
function HwpEditor2(props, ref) {
|
|
@@ -4644,7 +4714,7 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
4644
4714
|
className,
|
|
4645
4715
|
style
|
|
4646
4716
|
} = props;
|
|
4647
|
-
const catalogue = components ??
|
|
4717
|
+
const catalogue = components ?? import_core20.STARTER_COMPONENTS;
|
|
4648
4718
|
const cbRef = (0, import_react13.useRef)({ onReady, onError, onChange, onDirtyChange });
|
|
4649
4719
|
(0, import_react13.useEffect)(() => {
|
|
4650
4720
|
cbRef.current = { onReady, onError, onChange, onDirtyChange };
|
|
@@ -4662,7 +4732,7 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
4662
4732
|
cbRef.current.onDirtyChange?.(dirty2);
|
|
4663
4733
|
}, []);
|
|
4664
4734
|
const t = (0, import_react13.useMemo)(() => createT(locale, messages), [locale, messages]);
|
|
4665
|
-
const [store] = (0, import_react13.useState)(() => (0,
|
|
4735
|
+
const [store] = (0, import_react13.useState)(() => (0, import_core20.createStore)());
|
|
4666
4736
|
const state = (0, import_react13.useSyncExternalStore)(store.subscribe, store.getState, store.getState);
|
|
4667
4737
|
const [envelope, setEnvelope] = (0, import_react13.useState)(null);
|
|
4668
4738
|
const [capabilities, setCapabilities] = (0, import_react13.useState)(null);
|
|
@@ -4715,9 +4785,9 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
4715
4785
|
const readEnvelope = (0, import_react13.useCallback)(async (target) => {
|
|
4716
4786
|
const read = await engine.read(target);
|
|
4717
4787
|
try {
|
|
4718
|
-
return (0,
|
|
4788
|
+
return (0, import_core20.validateCatEnvelope)(read);
|
|
4719
4789
|
} catch (e) {
|
|
4720
|
-
throw new
|
|
4790
|
+
throw new import_core20.HwpEngineError(
|
|
4721
4791
|
"failed",
|
|
4722
4792
|
latestT.current("error.badEnvelope", { detail: envelopeProblem(e instanceof Error ? e.message : String(e)) }),
|
|
4723
4793
|
{ cause: e }
|
|
@@ -4736,7 +4806,7 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
4736
4806
|
insertedTriedFor.current = envelope;
|
|
4737
4807
|
const hidden = [];
|
|
4738
4808
|
const paragraphs = pendingInserted.flatMap((id) => {
|
|
4739
|
-
const segment = (0,
|
|
4809
|
+
const segment = (0, import_core20.segmentAtRef)(envelope, { id, section: 0, para: 0 });
|
|
4740
4810
|
if (segment === void 0) hidden.push(id);
|
|
4741
4811
|
return segment === void 0 || segment.kind !== "para" ? [] : [segment];
|
|
4742
4812
|
});
|
|
@@ -4744,9 +4814,9 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
4744
4814
|
if (paragraphs.length === 0) return;
|
|
4745
4815
|
store.dispatch({
|
|
4746
4816
|
type: "selectMany",
|
|
4747
|
-
selections: paragraphs.map(
|
|
4748
|
-
primary: (0,
|
|
4749
|
-
anchor: (0,
|
|
4817
|
+
selections: paragraphs.map(import_core20.segmentRef),
|
|
4818
|
+
primary: (0, import_core20.segmentRef)(paragraphs[0]),
|
|
4819
|
+
anchor: (0, import_core20.segmentRef)(paragraphs[0])
|
|
4750
4820
|
});
|
|
4751
4821
|
setInsertedHidden(hidden.length === 0 ? null : { envelope, selections: store.getState().selections, ids: hidden });
|
|
4752
4822
|
}, [envelope, pendingInserted, store]);
|
|
@@ -4827,22 +4897,22 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
4827
4897
|
const queueImage = (0, import_react13.useCallback)((op, asset) => {
|
|
4828
4898
|
const snapshot = store.getState();
|
|
4829
4899
|
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
|
|
4900
|
+
if (capabilities?.imageAssets !== "v1") throw new import_core20.HwpEngineError("unavailable", t("image.unsupported"));
|
|
4901
|
+
if (op.path !== asset.name) throw new import_core20.HwpEngineError("bad_request", t("image.referenceMismatch"));
|
|
4832
4902
|
const active = snapshot.pendingOps.flatMap((pending) => {
|
|
4833
4903
|
const stored = imageAssets.current.get(pending);
|
|
4834
4904
|
return stored === void 0 ? [] : [stored];
|
|
4835
4905
|
});
|
|
4836
|
-
if (active.length + 1 >
|
|
4837
|
-
throw new
|
|
4906
|
+
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) {
|
|
4907
|
+
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
4908
|
}
|
|
4839
|
-
(0,
|
|
4909
|
+
(0, import_core20.validateImageAssets)([...active, asset]);
|
|
4840
4910
|
imageAssets.current.set(op, { name: asset.name, data: asset.data.slice() });
|
|
4841
4911
|
store.dispatch({ type: "queueOp", op });
|
|
4842
4912
|
}, [editable, envelope, capabilities, store, t]);
|
|
4843
4913
|
(0, import_react13.useEffect)(() => {
|
|
4844
4914
|
if (envelope === null || state.selection === null) return;
|
|
4845
|
-
const segment = (0,
|
|
4915
|
+
const segment = (0, import_core20.segmentAtRef)(envelope, state.selection);
|
|
4846
4916
|
if (segment === void 0) return;
|
|
4847
4917
|
const next = hostsTable(envelope, segment) ? "table" : "para";
|
|
4848
4918
|
setTab((current) => current === "components" || current === "styles" ? current : next);
|
|
@@ -4989,17 +5059,17 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
4989
5059
|
noteRefusal(t("error.loadingReplacement"));
|
|
4990
5060
|
return;
|
|
4991
5061
|
}
|
|
4992
|
-
const segment = snapshot.selection === null ? void 0 : (0,
|
|
5062
|
+
const segment = snapshot.selection === null ? void 0 : (0, import_core20.segmentAtRef)(envelope, snapshot.selection);
|
|
4993
5063
|
const covered = selectionParagraphs(envelope, snapshot);
|
|
4994
5064
|
const address = segment === void 0 ? null : insertAnchor(covered, position);
|
|
4995
5065
|
if (address === null) return;
|
|
4996
|
-
if (position === "before" && covered[0] !== void 0 && (0,
|
|
5066
|
+
if (position === "before" && covered[0] !== void 0 && (0, import_core20.isSectionDefinitionParagraph)(covered[0])) return;
|
|
4997
5067
|
let blocks;
|
|
4998
5068
|
let styles2;
|
|
4999
5069
|
try {
|
|
5000
|
-
const filled = (0,
|
|
5070
|
+
const filled = (0, import_core20.substituteParams)(component, values, component.name);
|
|
5001
5071
|
blocks = filled.blocks;
|
|
5002
|
-
styles2 = (0,
|
|
5072
|
+
styles2 = (0, import_core20.componentStyleMap)([filled]);
|
|
5003
5073
|
} catch (error) {
|
|
5004
5074
|
const shown = toError(componentFailure(error, t));
|
|
5005
5075
|
noteNotice(shown.message, shown);
|
|
@@ -5052,7 +5122,7 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
5052
5122
|
}
|
|
5053
5123
|
let ids;
|
|
5054
5124
|
try {
|
|
5055
|
-
ids = (0,
|
|
5125
|
+
ids = (0, import_core20.insertedParagraphIds)(outcome);
|
|
5056
5126
|
} catch (error) {
|
|
5057
5127
|
noteNotice(toError(error).message, error);
|
|
5058
5128
|
return;
|
|
@@ -5063,12 +5133,12 @@ var HwpEditor = (0, import_react13.forwardRef)(
|
|
|
5063
5133
|
[emitError, engine, envelope, noteRefusal, replaceDocument, store, t]
|
|
5064
5134
|
);
|
|
5065
5135
|
const selectedTargets = envelope === null || state.selection === null ? void 0 : (() => {
|
|
5066
|
-
const segment = (0,
|
|
5067
|
-
return segment === void 0 ? void 0 : (0,
|
|
5136
|
+
const segment = (0, import_core20.segmentAtRef)(envelope, state.selection);
|
|
5137
|
+
return segment === void 0 ? void 0 : (0, import_core20.resolveSelection)(envelope, segment);
|
|
5068
5138
|
})();
|
|
5069
5139
|
const componentAnchor = envelope === null || state.selection === null ? [] : selectionParagraphs(envelope, state);
|
|
5070
5140
|
const selectedAddress = insertAnchor(componentAnchor, "after");
|
|
5071
|
-
const beforeDisabledReason = componentAnchor[0] !== void 0 && (0,
|
|
5141
|
+
const beforeDisabledReason = componentAnchor[0] !== void 0 && (0, import_core20.isSectionDefinitionParagraph)(componentAnchor[0]) ? t("components.positionBeforeLocked") : "";
|
|
5072
5142
|
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
5143
|
const componentRefusal = (0, import_react13.useCallback)(
|
|
5074
5144
|
(component) => insertionPreflight(component.blocks, state.document?.name ?? "", t),
|