@hyebook/vue3-adapter 0.2.0 → 0.2.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.
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"editor-workbench.d.ts","sourceRoot":"","sources":["../../../../../core/src/workbench/editor-workbench.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,QAAQ,EAKR,kBAAkB,EAWnB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"editor-workbench.d.ts","sourceRoot":"","sources":["../../../../../core/src/workbench/editor-workbench.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,QAAQ,EAKR,kBAAkB,EAWnB,MAAM,gBAAgB,CAAC;AAkJxB,MAAM,WAAW,uBAAuB;IACtC,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,sBAAsB;IACrC,UAAU,CAAC,EAAE,QAAQ,CAAC;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAC,uBAAuB,CAAC,CAAC;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,4BAA4B,CAAC;IACtC,UAAU,CAAC,EAAE,gCAAgC,CAAC;IAC9C,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,QAAQ,KAAK,IAAI,CAAC;CAC5C;AAED,MAAM,WAAW,gCAAgC;IAC/C,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,qBAAqB,GAAG,OAAO,GAAG,OAAO,CAAC;AAEtD,MAAM,WAAW,kBAAkB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,qBAAqB,CAAC;IAC7B,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,2BAA2B;IAC1C,UAAU,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3D;AAED,MAAM,WAAW,wBAAyB,SAAQ,2BAA2B;CAAG;AAEhF,MAAM,WAAW,uBAAwB,SAAQ,2BAA2B;IAC1E,SAAS,EAAE,qBAAqB,CAAC;CAClC;AAED,MAAM,WAAW,4BAA4B;IAC3C,UAAU,CAAC,EAAE,CACX,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,uBAAuB,KAC7B,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjC,WAAW,CAAC,EAAE,CACZ,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,wBAAwB,KAC9B,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACjC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,WAAW,EAAE,MAAM,QAAQ,CAAC;IAC5B,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,YAAY,EAAE,MAAM,MAAM,CAAC;IAC3B,UAAU,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1C,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IAC9B,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;IACjD,sBAAsB,EAAE,CACtB,WAAW,EAAE,kBAAkB,GAAG,IAAI,GAAG,SAAS,KAC/C,kBAAkB,CAAC;IACxB,WAAW,EAAE,MAAM,uBAAuB,CAAC;IAC3C,WAAW,EAAE,CAAC,QAAQ,EAAE,OAAO,CAAC,uBAAuB,CAAC,KAAK,IAAI,CAAC;CACnE;AAED,eAAO,MAAM,iCAAiC,EAAE,uBAM/C,CAAC;AAEF,KAAK,IAAI,GAAG,QAAQ,GAAG,SAAS,CAAC;AAsQjC,wBAAgB,8BAA8B,IAAI,QAAQ,CA6GzD;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,WAAW,EACtB,OAAO,GAAE,sBAA2B,GACnC,qBAAqB,CAszIvB"}
|
|
@@ -22,7 +22,7 @@ const WORKBENCH_CSS = `
|
|
|
22
22
|
.hyewb-field-icon{position:absolute;left:10px;top:50%;transform:translateY(-50%);display:inline-flex;align-items:center;justify-content:center;color:#64748b;pointer-events:none;z-index:1}
|
|
23
23
|
.hyewb-field-icon svg{width:14px;height:14px;stroke-width:2}
|
|
24
24
|
.hyewb-field-with-icon .hyewb-select,.hyewb-field-with-icon .hyewb-number{padding-left:30px}
|
|
25
|
-
.hyewb-shell{border:1px dashed #b8c3d1;border-radius:10px;background:#eef4ff;padding:10px;overflow-x:auto}
|
|
25
|
+
.hyewb-shell{border:1px dashed #b8c3d1;border-radius:10px;background:#eef4ff;padding:10px;overflow-x:auto;overflow-y:auto;overscroll-behavior:auto;-webkit-overflow-scrolling:touch}
|
|
26
26
|
.hyewb-canvas{position:relative;background:#fff;border:1px solid #d9e3ee;border-radius:8px;min-height:420px;padding:20px 24px;box-shadow:0 6px 16px rgba(15,23,42,.08);margin:0 auto}
|
|
27
27
|
.hyewb-editor{min-height:360px;outline:none;line-height:1.7;font-size:16px;color:#1e293b}
|
|
28
28
|
.hyewb-float{position:fixed;z-index:9999;display:none;align-items:center;gap:6px;padding:6px 8px;border-radius:10px;border:1px solid #0f172a;background:rgba(15,23,42,.96);box-shadow:0 10px 24px rgba(15,23,42,.22)}
|
|
@@ -81,18 +81,20 @@ const WORKBENCH_CSS = `
|
|
|
81
81
|
.hyewb-table-picker-row{display:flex;align-items:center;gap:8px}
|
|
82
82
|
.hyewb-table-picker-confirm{border:1px solid #0b7285;background:#0b7285;color:#fff;border-radius:8px;height:32px;padding:0 10px;cursor:pointer}
|
|
83
83
|
.hyewb-table-tools{display:none !important}
|
|
84
|
-
.hyewb-table-tools.show{display:
|
|
84
|
+
.hyewb-table-tools.show{display:flex !important}
|
|
85
85
|
.hyewb-table-tools .hyewb-btn{width:30px;height:30px;border-color:#334155;background:#1e293b;color:#f8fafc}
|
|
86
86
|
.hyewb-table-tools .hyewb-number{width:68px;height:30px;padding:4px 6px;border-color:#334155;background:#1e293b;color:#f8fafc}
|
|
87
87
|
.hyewb-table-tools label{font-size:12px;color:#e2e8f0;display:inline-flex;align-items:center;gap:4px}
|
|
88
|
-
.hyewb-table-row-delete{position:fixed;display:none;z-index:10026;width:
|
|
88
|
+
.hyewb-table-row-delete{position:fixed;display:none;z-index:10026;width:20px;height:20px;border:1px solid #ef4444;background:#fff;color:#dc2626;border-radius:999px;align-items:center;justify-content:center;cursor:pointer;box-shadow:0 8px 18px rgba(15,23,42,.2);padding:0}
|
|
89
89
|
.hyewb-table-row-delete.show{display:inline-flex}
|
|
90
90
|
.hyewb-table-row-delete::before{content:"";position:absolute;left:-14px;top:-8px;width:20px;height:44px}
|
|
91
|
-
.hyewb-table-handle{position:fixed;display:none;z-index:10030;width:
|
|
91
|
+
.hyewb-table-handle{position:fixed;display:none;z-index:10030;width:16px;height:16px;border-radius:999px;border:1px solid #0284c7;background:#ffffff;color:#0369a1;align-items:center;justify-content:center;cursor:grab;box-shadow:0 8px 18px rgba(15,23,42,.2);padding:0}
|
|
92
92
|
.hyewb-table-handle.show{display:inline-flex}
|
|
93
93
|
.hyewb-table-handle:active{cursor:grabbing}
|
|
94
94
|
.hyewb-table-handle.scale{cursor:nwse-resize}
|
|
95
95
|
.hyewb-table-handle.scale:active{cursor:nwse-resize}
|
|
96
|
+
.hyewb-table-handle .hyewb-icon,.hyewb-table-row-delete .hyewb-icon{display:inline-flex;align-items:center;justify-content:center}
|
|
97
|
+
.hyewb-table-handle svg,.hyewb-table-row-delete svg{width:8px;height:8px;stroke-width:2.25;flex:0 0 auto}
|
|
96
98
|
.hyewb-table-edge-layer{position:fixed;display:none;z-index:10028;pointer-events:none}
|
|
97
99
|
.hyewb-table-edge-layer.show{display:block}
|
|
98
100
|
.hyewb-table-edge-hit{position:absolute;display:flex;align-items:center;justify-content:center;border:1px solid #cbd5e1;background:#f8fafc;color:#0369a1;border-radius:0px;cursor:grab;pointer-events:auto;line-height:1;font-size:12px;padding:0}
|
|
@@ -100,7 +102,7 @@ const WORKBENCH_CSS = `
|
|
|
100
102
|
.hyewb-table-edge-hit.active{border-color:#0284c7;background:#e0f2fe;color:#0c4a6e}
|
|
101
103
|
.hyewb-table-edge-layer.col .hyewb-table-edge-hit{height:14px}
|
|
102
104
|
.hyewb-table-edge-layer.row .hyewb-table-edge-hit{width:14px}
|
|
103
|
-
.hyewb-table-gap-insert{position:fixed;display:none;z-index:10029;width:
|
|
105
|
+
.hyewb-table-gap-insert{position:fixed;display:none;z-index:10029;width:18px;height:18px;border-radius:999px;border:1px solid #0284c7;background:#ffffff;color:#0369a1;cursor:pointer;align-items:center;justify-content:center;padding:0;font-size:14px;line-height:1;box-shadow:0 8px 18px rgba(15,23,42,.2)}
|
|
104
106
|
.hyewb-table-gap-insert.show{display:inline-flex}
|
|
105
107
|
.hyewb-table-drop-indicator{position:fixed;display:none;z-index:10024;background:#0284c7;pointer-events:none;border-radius:999px}
|
|
106
108
|
.hyewb-table-drop-indicator.show{display:block}
|
|
@@ -137,6 +139,8 @@ const WORKBENCH_CSS = `
|
|
|
137
139
|
.hyewb-upload-progress{height:8px;background:#e2e8f0;border-radius:999px;overflow:hidden}
|
|
138
140
|
.hyewb-upload-progress > span{display:block;height:100%;width:0;background:#0b7285;transition:width .18s ease}
|
|
139
141
|
.hyewb-upload-error{min-height:18px;font-size:12px;color:#b91c1c;margin:0}
|
|
142
|
+
.hyewb-root:fullscreen .hyewb-editor,.hyewb-root:fullscreen .hyewb-preview{min-height:1000px}
|
|
143
|
+
.hyewb-root:-webkit-full-screen .hyewb-editor,.hyewb-root:-webkit-full-screen .hyewb-preview{min-height:1000px}
|
|
140
144
|
`;
|
|
141
145
|
export const DEFAULT_EDITOR_WORKBENCH_FEATURES = {
|
|
142
146
|
textToolbar: true,
|
|
@@ -155,6 +159,8 @@ const WORKBENCH_ICON_PATHS = {
|
|
|
155
159
|
bold: '<path d="M7 4h6a3 3 0 0 1 0 6H7z"/><path d="M7 10h7a3 3 0 0 1 0 6H7z"/>',
|
|
156
160
|
"chevron-left": '<polyline points="15 18 9 12 15 6"/>',
|
|
157
161
|
"chevron-right": '<polyline points="9 18 15 12 9 6"/>',
|
|
162
|
+
"fullscreen-enter": '<polyline points="9 3 3 3 3 9"/><line x1="3" y1="3" x2="10" y2="10"/><polyline points="15 3 21 3 21 9"/><line x1="14" y1="10" x2="21" y2="3"/><polyline points="3 15 3 21 9 21"/><line x1="3" y1="21" x2="10" y2="14"/><polyline points="15 21 21 21 21 15"/><line x1="14" y1="14" x2="21" y2="21"/>',
|
|
163
|
+
"fullscreen-exit": '<polyline points="10 14 10 21 3 21"/><line x1="10" y1="14" x2="3" y2="21"/><polyline points="14 10 21 10 21 3"/><line x1="14" y1="10" x2="21" y2="3"/><polyline points="3 9 3 3 9 3"/><line x1="3" y1="3" x2="10" y2="10"/><polyline points="21 15 21 21 15 21"/><line x1="21" y1="21" x2="14" y2="14"/>',
|
|
158
164
|
"file-up": '<path d="M14 2H8a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h8a2 2 0 0 0 2-2V8z"/><path d="M14 2v6h6"/><line x1="12" y1="18" x2="12" y2="12"/><polyline points="9.5 14.5 12 12 14.5 14.5"/>',
|
|
159
165
|
image: '<rect x="3" y="5" width="18" height="14" rx="2"/><circle cx="9" cy="10" r="1.5"/><path d="M6 17l4-4 3 3 3-2 2 3"/>',
|
|
160
166
|
italic: '<line x1="10" y1="4" x2="16" y2="4"/><line x1="8" y1="20" x2="14" y2="20"/><line x1="14" y1="4" x2="10" y2="20"/>',
|
|
@@ -163,10 +169,11 @@ const WORKBENCH_ICON_PATHS = {
|
|
|
163
169
|
"paint-bucket": '<path d="M7 10l6-6 7 7-6 6z"/><path d="M12 5l7 7"/><path d="M5 19a2 2 0 1 0 4 0c0-1-1-2-2-3-1 1-2 2-2 3z"/>',
|
|
164
170
|
palette: '<path d="M12 3a9 9 0 1 0 0 18h1.5a2.5 2.5 0 0 0 0-5h-1a2 2 0 0 1 0-4H16a5 5 0 0 0-4-9z"/><circle cx="7.5" cy="10" r="1"/><circle cx="10" cy="7.5" r="1"/><circle cx="14" cy="7.5" r="1"/>',
|
|
165
171
|
pilcrow: '<path d="M9 4h7v16"/><path d="M12 4v16"/><path d="M9 4a4 4 0 0 0 0 8h3"/>',
|
|
172
|
+
"resize-se": '<polyline points="11 13 13 13 13 11"/><line x1="10" y1="14" x2="14" y2="10"/><polyline points="15 19 19 19 19 15"/><line x1="14" y1="20" x2="20" y2="14"/>',
|
|
166
173
|
"square-plus": '<rect x="3" y="3" width="18" height="18" rx="2"/><line x1="12" y1="8" x2="12" y2="16"/><line x1="8" y1="12" x2="16" y2="12"/>',
|
|
167
174
|
strikethrough: '<path d="M16 5a4 4 0 0 0-8 0c0 2.2 2 3.2 4 4"/><path d="M8 19a4 4 0 0 0 8 0c0-2.2-2-3.2-4-4"/><line x1="4" y1="12" x2="20" y2="12"/>',
|
|
168
|
-
subscript: '<
|
|
169
|
-
superscript: '<
|
|
175
|
+
subscript: '<line x1="4" y1="8" x2="10" y2="16"/><line x1="10" y1="8" x2="4" y2="16"/><path d="M14 15c0-1.1.9-2 2-2s2 .9 2 2c0 .7-.3 1.2-.9 1.7L14 20h4"/>',
|
|
176
|
+
superscript: '<line x1="4" y1="8" x2="10" y2="16"/><line x1="10" y1="8" x2="4" y2="16"/><path d="M14 6c0-1.1.9-2 2-2s2 .9 2 2c0 .7-.3 1.2-.9 1.7L14 11h4"/>',
|
|
170
177
|
table: '<rect x="3" y="5" width="18" height="14" rx="1"/><line x1="3" y1="10" x2="21" y2="10"/><line x1="9" y1="5" x2="9" y2="19"/><line x1="15" y1="5" x2="15" y2="19"/>',
|
|
171
178
|
underline: '<path d="M6 4v6a6 6 0 0 0 12 0V4"/><line x1="4" y1="20" x2="20" y2="20"/>',
|
|
172
179
|
video: '<rect x="3" y="6" width="14" height="12" rx="2"/><polygon points="10 10 10 14 13 12"/><path d="M17 10l4-2v8l-4-2z"/>',
|
|
@@ -191,6 +198,7 @@ const WORKBENCH_BUTTONS = {
|
|
|
191
198
|
alignCenter: { icon: "align-center", ariaLabel: "居中" },
|
|
192
199
|
alignRight: { icon: "align-right", ariaLabel: "右对齐" },
|
|
193
200
|
alignJustify: { icon: "align-justify", ariaLabel: "两端对齐" },
|
|
201
|
+
fullscreen: { icon: "fullscreen-enter", ariaLabel: "全屏" },
|
|
194
202
|
close: { icon: "x", ariaLabel: "关闭" },
|
|
195
203
|
};
|
|
196
204
|
const COLOR_SWATCHES = [
|
|
@@ -265,6 +273,7 @@ const RESIZE_HANDLES = [
|
|
|
265
273
|
"sw",
|
|
266
274
|
"w",
|
|
267
275
|
];
|
|
276
|
+
const DEFAULT_FLOW_BLOCK_WIDTH = 620;
|
|
268
277
|
export function createDefaultWorkbenchDocument() {
|
|
269
278
|
const now = new Date().toISOString();
|
|
270
279
|
return {
|
|
@@ -393,6 +402,7 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
393
402
|
const title = document.createElement("div");
|
|
394
403
|
title.className = "hyewb-title";
|
|
395
404
|
title.textContent = options.title ?? "hy-ebook Editor Workbench";
|
|
405
|
+
const fullscreenBtn = createButton("fullscreen");
|
|
396
406
|
header.append(title);
|
|
397
407
|
const toolbar = document.createElement("div");
|
|
398
408
|
toolbar.className = "hyewb-row";
|
|
@@ -611,7 +621,7 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
611
621
|
tableScaleHandle.className = "hyewb-table-handle scale";
|
|
612
622
|
tableScaleHandle.title = "按比例缩放表格";
|
|
613
623
|
tableScaleHandle.setAttribute("aria-label", "按比例缩放表格");
|
|
614
|
-
tableScaleHandle.append(createIconPlaceholder("
|
|
624
|
+
tableScaleHandle.append(createIconPlaceholder("resize-se"));
|
|
615
625
|
const tableColEdgeLayer = document.createElement("div");
|
|
616
626
|
tableColEdgeLayer.className = "hyewb-table-edge-layer col";
|
|
617
627
|
const tableRowEdgeLayer = document.createElement("div");
|
|
@@ -662,7 +672,8 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
662
672
|
const addPageBtn = createButton("addPage");
|
|
663
673
|
const pageInfo = document.createElement("span");
|
|
664
674
|
pageInfo.className = "hyewb-status";
|
|
665
|
-
|
|
675
|
+
fullscreenBtn.style.marginLeft = "auto";
|
|
676
|
+
pageRow.append(prevPageBtn, nextPageBtn, addPageBtn, pageInfo, fullscreenBtn);
|
|
666
677
|
const shell = document.createElement("div");
|
|
667
678
|
shell.className = "hyewb-shell";
|
|
668
679
|
const canvas = document.createElement("div");
|
|
@@ -802,6 +813,77 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
802
813
|
speedMbps: undefined,
|
|
803
814
|
error: undefined,
|
|
804
815
|
};
|
|
816
|
+
const setButtonIcon = (button, iconName) => {
|
|
817
|
+
button.innerHTML = "";
|
|
818
|
+
button.append(createIconPlaceholder(iconName));
|
|
819
|
+
};
|
|
820
|
+
const getFullscreenElement = () => {
|
|
821
|
+
const webkitDocument = document;
|
|
822
|
+
return (document.fullscreenElement ||
|
|
823
|
+
webkitDocument.webkitFullscreenElement ||
|
|
824
|
+
null);
|
|
825
|
+
};
|
|
826
|
+
const isWorkbenchFullscreen = () => {
|
|
827
|
+
return getFullscreenElement() === root;
|
|
828
|
+
};
|
|
829
|
+
const updateFullscreenButtonState = () => {
|
|
830
|
+
const isFullscreen = isWorkbenchFullscreen();
|
|
831
|
+
setButtonActive(fullscreenBtn, isFullscreen);
|
|
832
|
+
setButtonIcon(fullscreenBtn, isFullscreen ? "fullscreen-exit" : "fullscreen-enter");
|
|
833
|
+
const label = isFullscreen ? "退出全屏" : "全屏";
|
|
834
|
+
fullscreenBtn.title = label;
|
|
835
|
+
fullscreenBtn.setAttribute("aria-label", label);
|
|
836
|
+
};
|
|
837
|
+
const updateShellViewportHeight = () => {
|
|
838
|
+
const viewportHeight = window.innerHeight || document.documentElement.clientHeight;
|
|
839
|
+
const top = root.getBoundingClientRect().top;
|
|
840
|
+
const bottomPadding = isWorkbenchFullscreen() ? 16 : 24;
|
|
841
|
+
const nextHeight = Math.max(320, Math.floor(viewportHeight - top - bottomPadding));
|
|
842
|
+
shell.style.maxHeight = `${nextHeight}px`;
|
|
843
|
+
};
|
|
844
|
+
const requestWorkbenchFullscreen = async () => {
|
|
845
|
+
const target = root;
|
|
846
|
+
if (typeof target.requestFullscreen === "function") {
|
|
847
|
+
await target.requestFullscreen();
|
|
848
|
+
return;
|
|
849
|
+
}
|
|
850
|
+
if (typeof target.webkitRequestFullscreen === "function") {
|
|
851
|
+
target.webkitRequestFullscreen();
|
|
852
|
+
return;
|
|
853
|
+
}
|
|
854
|
+
throw new Error("当前环境不支持全屏");
|
|
855
|
+
};
|
|
856
|
+
const exitWorkbenchFullscreen = async () => {
|
|
857
|
+
const webkitDocument = document;
|
|
858
|
+
if (typeof document.exitFullscreen === "function") {
|
|
859
|
+
await document.exitFullscreen();
|
|
860
|
+
return;
|
|
861
|
+
}
|
|
862
|
+
if (typeof webkitDocument.webkitExitFullscreen === "function") {
|
|
863
|
+
webkitDocument.webkitExitFullscreen();
|
|
864
|
+
return;
|
|
865
|
+
}
|
|
866
|
+
if (typeof webkitDocument.webkitCancelFullScreen === "function") {
|
|
867
|
+
webkitDocument.webkitCancelFullScreen();
|
|
868
|
+
}
|
|
869
|
+
};
|
|
870
|
+
const toggleWorkbenchFullscreen = async () => {
|
|
871
|
+
try {
|
|
872
|
+
if (isWorkbenchFullscreen()) {
|
|
873
|
+
await exitWorkbenchFullscreen();
|
|
874
|
+
}
|
|
875
|
+
else {
|
|
876
|
+
await requestWorkbenchFullscreen();
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
catch {
|
|
880
|
+
status.textContent = "当前浏览器不支持全屏";
|
|
881
|
+
}
|
|
882
|
+
finally {
|
|
883
|
+
updateFullscreenButtonState();
|
|
884
|
+
updateShellViewportHeight();
|
|
885
|
+
}
|
|
886
|
+
};
|
|
805
887
|
const formatUploadProgress = (percent) => {
|
|
806
888
|
const safe = Number.isFinite(percent) ? percent : 0;
|
|
807
889
|
const clamped = Math.max(0, Math.min(100, safe));
|
|
@@ -947,7 +1029,7 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
947
1029
|
const mammothNamespace = await import("mammoth");
|
|
948
1030
|
const mammothModule = resolveMammothModule(mammothNamespace);
|
|
949
1031
|
const arrayBuffer = await file.arrayBuffer();
|
|
950
|
-
const xmlPreferredFlowBlocks = await parseDocxFlowBlocksFromXml(arrayBuffer);
|
|
1032
|
+
const xmlPreferredFlowBlocks = await parseDocxFlowBlocksFromXml(arrayBuffer, resolveDocxImportMaxFlowBlockWidth(state.doc.settings.page, paperWidth));
|
|
951
1033
|
if (xmlPreferredFlowBlocks?.length) {
|
|
952
1034
|
syncEditorToDoc();
|
|
953
1035
|
const nextDoc = clone(state.doc);
|
|
@@ -1220,11 +1302,11 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
1220
1302
|
}
|
|
1221
1303
|
cancelTableToolsHide();
|
|
1222
1304
|
const tableRect = activeTableElement.getBoundingClientRect();
|
|
1223
|
-
tableMoveHandle.style.left = `${Math.round(tableRect.left -
|
|
1224
|
-
tableMoveHandle.style.top = `${Math.round(tableRect.top -
|
|
1305
|
+
tableMoveHandle.style.left = `${Math.round(tableRect.left - 14)}px`;
|
|
1306
|
+
tableMoveHandle.style.top = `${Math.round(tableRect.top - 14)}px`;
|
|
1225
1307
|
tableMoveHandle.classList.add("show");
|
|
1226
|
-
tableScaleHandle.style.left = `${Math.round(tableRect.right -
|
|
1227
|
-
tableScaleHandle.style.top = `${Math.round(tableRect.bottom -
|
|
1308
|
+
tableScaleHandle.style.left = `${Math.round(tableRect.right - 10)}px`;
|
|
1309
|
+
tableScaleHandle.style.top = `${Math.round(tableRect.bottom - 10)}px`;
|
|
1228
1310
|
tableScaleHandle.classList.add("show");
|
|
1229
1311
|
tableColEdgeLayer.style.left = `${Math.round(tableRect.left)}px`;
|
|
1230
1312
|
tableColEdgeLayer.style.top = `${Math.round(tableRect.top - 12)}px`;
|
|
@@ -1240,7 +1322,7 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
1240
1322
|
if (activeTableRowElement) {
|
|
1241
1323
|
const rowRect = activeTableRowElement.getBoundingClientRect();
|
|
1242
1324
|
tableRowDeleteBtn.style.left = `${Math.round(rowRect.right - 2)}px`;
|
|
1243
|
-
tableRowDeleteBtn.style.top = `${Math.round(rowRect.top + rowRect.height / 2 -
|
|
1325
|
+
tableRowDeleteBtn.style.top = `${Math.round(rowRect.top + rowRect.height / 2 - 10)}px`;
|
|
1244
1326
|
tableRowDeleteBtn.classList.add("show");
|
|
1245
1327
|
}
|
|
1246
1328
|
else {
|
|
@@ -1587,8 +1669,8 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
1587
1669
|
return best;
|
|
1588
1670
|
};
|
|
1589
1671
|
const updateGapInsertButton = (hover) => {
|
|
1590
|
-
const rowGapOffset = { x: -
|
|
1591
|
-
const colGapOffset = { x: -
|
|
1672
|
+
const rowGapOffset = { x: -1, y: -9 };
|
|
1673
|
+
const colGapOffset = { x: -9, y: -1 };
|
|
1592
1674
|
tableGapHover = hover;
|
|
1593
1675
|
if (!hover || state.mode !== "editor") {
|
|
1594
1676
|
tableRowGapInsertBtn.classList.remove("show");
|
|
@@ -1847,6 +1929,119 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
1847
1929
|
rememberedParagraphIndex = index;
|
|
1848
1930
|
}
|
|
1849
1931
|
};
|
|
1932
|
+
const normalizeVerticalAlignValue = (value) => {
|
|
1933
|
+
return String(value || "")
|
|
1934
|
+
.trim()
|
|
1935
|
+
.toLowerCase();
|
|
1936
|
+
};
|
|
1937
|
+
const detectScriptMarkFromElement = (element) => {
|
|
1938
|
+
let cursor = element;
|
|
1939
|
+
while (cursor && cursor !== editorArea) {
|
|
1940
|
+
const tagName = cursor.tagName.toLowerCase();
|
|
1941
|
+
if (tagName === "sup") {
|
|
1942
|
+
return "superscript";
|
|
1943
|
+
}
|
|
1944
|
+
if (tagName === "sub") {
|
|
1945
|
+
return "subscript";
|
|
1946
|
+
}
|
|
1947
|
+
const inlineAlign = normalizeVerticalAlignValue(cursor.style?.verticalAlign);
|
|
1948
|
+
if (inlineAlign === "super") {
|
|
1949
|
+
return "superscript";
|
|
1950
|
+
}
|
|
1951
|
+
if (inlineAlign === "sub") {
|
|
1952
|
+
return "subscript";
|
|
1953
|
+
}
|
|
1954
|
+
cursor = cursor.parentElement;
|
|
1955
|
+
}
|
|
1956
|
+
return null;
|
|
1957
|
+
};
|
|
1958
|
+
const doesRangeIntersectNode = (range, node) => {
|
|
1959
|
+
try {
|
|
1960
|
+
return range.intersectsNode(node);
|
|
1961
|
+
}
|
|
1962
|
+
catch {
|
|
1963
|
+
return false;
|
|
1964
|
+
}
|
|
1965
|
+
};
|
|
1966
|
+
const resolveScriptStateFromRange = (range) => {
|
|
1967
|
+
if (!range) {
|
|
1968
|
+
return { superscript: false, subscript: false };
|
|
1969
|
+
}
|
|
1970
|
+
const detectFromContainer = (container) => {
|
|
1971
|
+
const element = container.nodeType === Node.ELEMENT_NODE
|
|
1972
|
+
? container
|
|
1973
|
+
: container.parentElement;
|
|
1974
|
+
return detectScriptMarkFromElement(element);
|
|
1975
|
+
};
|
|
1976
|
+
const fromStart = detectFromContainer(range.startContainer);
|
|
1977
|
+
const fromEnd = detectFromContainer(range.endContainer);
|
|
1978
|
+
const mark = fromStart || fromEnd;
|
|
1979
|
+
return {
|
|
1980
|
+
superscript: mark === "superscript",
|
|
1981
|
+
subscript: mark === "subscript",
|
|
1982
|
+
};
|
|
1983
|
+
};
|
|
1984
|
+
const getActiveEditorRange = () => {
|
|
1985
|
+
const selection = window.getSelection();
|
|
1986
|
+
if (selection &&
|
|
1987
|
+
selection.rangeCount > 0 &&
|
|
1988
|
+
editorArea.contains(selection.getRangeAt(0).startContainer) &&
|
|
1989
|
+
editorArea.contains(selection.getRangeAt(0).endContainer)) {
|
|
1990
|
+
return selection.getRangeAt(0);
|
|
1991
|
+
}
|
|
1992
|
+
return rememberedRange;
|
|
1993
|
+
};
|
|
1994
|
+
const clearScriptMarkInRange = (range, command) => {
|
|
1995
|
+
const selector = command === "superscript"
|
|
1996
|
+
? 'sup,span[style*="vertical-align: super"],span[style*="vertical-align:super"]'
|
|
1997
|
+
: 'sub,span[style*="vertical-align: sub"],span[style*="vertical-align:sub"]';
|
|
1998
|
+
const rootNode = range.commonAncestorContainer.nodeType === Node.ELEMENT_NODE
|
|
1999
|
+
? range.commonAncestorContainer
|
|
2000
|
+
: range.commonAncestorContainer.parentElement;
|
|
2001
|
+
if (!rootNode) {
|
|
2002
|
+
return;
|
|
2003
|
+
}
|
|
2004
|
+
const candidateSet = new Set();
|
|
2005
|
+
const addIfMatches = (element) => {
|
|
2006
|
+
let cursor = element;
|
|
2007
|
+
while (cursor && cursor !== editorArea) {
|
|
2008
|
+
if (cursor.matches(selector) && doesRangeIntersectNode(range, cursor)) {
|
|
2009
|
+
candidateSet.add(cursor);
|
|
2010
|
+
}
|
|
2011
|
+
cursor = cursor.parentElement;
|
|
2012
|
+
}
|
|
2013
|
+
};
|
|
2014
|
+
addIfMatches(range.startContainer.nodeType === Node.ELEMENT_NODE
|
|
2015
|
+
? range.startContainer
|
|
2016
|
+
: range.startContainer.parentElement);
|
|
2017
|
+
addIfMatches(range.endContainer.nodeType === Node.ELEMENT_NODE
|
|
2018
|
+
? range.endContainer
|
|
2019
|
+
: range.endContainer.parentElement);
|
|
2020
|
+
rootNode.querySelectorAll(selector).forEach((node) => {
|
|
2021
|
+
if (doesRangeIntersectNode(range, node)) {
|
|
2022
|
+
candidateSet.add(node);
|
|
2023
|
+
}
|
|
2024
|
+
});
|
|
2025
|
+
Array.from(candidateSet).forEach((element) => {
|
|
2026
|
+
const tagName = element.tagName.toLowerCase();
|
|
2027
|
+
if (tagName === "sup" || tagName === "sub") {
|
|
2028
|
+
const parent = element.parentNode;
|
|
2029
|
+
if (!parent) {
|
|
2030
|
+
return;
|
|
2031
|
+
}
|
|
2032
|
+
while (element.firstChild) {
|
|
2033
|
+
parent.insertBefore(element.firstChild, element);
|
|
2034
|
+
}
|
|
2035
|
+
parent.removeChild(element);
|
|
2036
|
+
return;
|
|
2037
|
+
}
|
|
2038
|
+
element.style.removeProperty("vertical-align");
|
|
2039
|
+
element.style.removeProperty("top");
|
|
2040
|
+
if (!element.getAttribute("style")?.trim()) {
|
|
2041
|
+
element.removeAttribute("style");
|
|
2042
|
+
}
|
|
2043
|
+
});
|
|
2044
|
+
};
|
|
1850
2045
|
const syncToolbarState = () => {
|
|
1851
2046
|
if (!state.features.textToolbar || state.mode !== "editor") {
|
|
1852
2047
|
return;
|
|
@@ -1874,11 +2069,14 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
1874
2069
|
const strikeActive = canReflect
|
|
1875
2070
|
? safeQueryCommandState("strikeThrough")
|
|
1876
2071
|
: false;
|
|
2072
|
+
const scriptState = canReflect
|
|
2073
|
+
? resolveScriptStateFromRange(getActiveEditorRange())
|
|
2074
|
+
: { superscript: false, subscript: false };
|
|
1877
2075
|
const superscriptActive = canReflect
|
|
1878
|
-
? safeQueryCommandState("superscript")
|
|
2076
|
+
? safeQueryCommandState("superscript") || scriptState.superscript
|
|
1879
2077
|
: false;
|
|
1880
2078
|
const subscriptActive = canReflect
|
|
1881
|
-
? safeQueryCommandState("subscript")
|
|
2079
|
+
? safeQueryCommandState("subscript") || scriptState.subscript
|
|
1882
2080
|
: false;
|
|
1883
2081
|
[boldBtn, floatBoldBtn].forEach((btn) => setButtonActive(btn, boldActive));
|
|
1884
2082
|
[italicBtn, floatItalicBtn].forEach((btn) => setButtonActive(btn, italicActive));
|
|
@@ -2071,6 +2269,26 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
2071
2269
|
syncToolbarState();
|
|
2072
2270
|
updateFloatingToolbarBySelection();
|
|
2073
2271
|
};
|
|
2272
|
+
const toggleScriptMark = (command, activeMessage) => {
|
|
2273
|
+
withSelectionCommand(() => {
|
|
2274
|
+
const opposite = command === "superscript" ? "subscript" : "superscript";
|
|
2275
|
+
const activeRange = getActiveEditorRange();
|
|
2276
|
+
const currentScriptState = resolveScriptStateFromRange(activeRange);
|
|
2277
|
+
const wasActive = command === "superscript"
|
|
2278
|
+
? currentScriptState.superscript
|
|
2279
|
+
: currentScriptState.subscript;
|
|
2280
|
+
if (activeRange) {
|
|
2281
|
+
clearScriptMarkInRange(activeRange, opposite);
|
|
2282
|
+
}
|
|
2283
|
+
if (wasActive) {
|
|
2284
|
+
if (activeRange) {
|
|
2285
|
+
clearScriptMarkInRange(activeRange, command);
|
|
2286
|
+
}
|
|
2287
|
+
return;
|
|
2288
|
+
}
|
|
2289
|
+
document.execCommand(command, false);
|
|
2290
|
+
}, activeMessage);
|
|
2291
|
+
};
|
|
2074
2292
|
const applyColorFromPalette = (color) => {
|
|
2075
2293
|
if (!activeColorTarget) {
|
|
2076
2294
|
return;
|
|
@@ -2741,14 +2959,10 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
2741
2959
|
}, "已应用删除线");
|
|
2742
2960
|
});
|
|
2743
2961
|
superscriptBtn.addEventListener("click", () => {
|
|
2744
|
-
|
|
2745
|
-
document.execCommand("superscript", false);
|
|
2746
|
-
}, "已应用上角标");
|
|
2962
|
+
toggleScriptMark("superscript", "已切换上角标");
|
|
2747
2963
|
});
|
|
2748
2964
|
subscriptBtn.addEventListener("click", () => {
|
|
2749
|
-
|
|
2750
|
-
document.execCommand("subscript", false);
|
|
2751
|
-
}, "已应用下角标");
|
|
2965
|
+
toggleScriptMark("subscript", "已切换下角标");
|
|
2752
2966
|
});
|
|
2753
2967
|
headingSelect.addEventListener("change", () => {
|
|
2754
2968
|
const value = headingSelect.value === "h1" ||
|
|
@@ -2823,6 +3037,12 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
2823
3037
|
}, 140);
|
|
2824
3038
|
};
|
|
2825
3039
|
[
|
|
3040
|
+
boldBtn,
|
|
3041
|
+
italicBtn,
|
|
3042
|
+
underlineBtn,
|
|
3043
|
+
strikeBtn,
|
|
3044
|
+
superscriptBtn,
|
|
3045
|
+
subscriptBtn,
|
|
2826
3046
|
floatBoldBtn,
|
|
2827
3047
|
floatItalicBtn,
|
|
2828
3048
|
floatUnderlineBtn,
|
|
@@ -2886,14 +3106,10 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
2886
3106
|
}, "已应用删除线");
|
|
2887
3107
|
});
|
|
2888
3108
|
floatSuperscriptBtn.addEventListener("click", () => {
|
|
2889
|
-
|
|
2890
|
-
document.execCommand("superscript", false);
|
|
2891
|
-
}, "已应用上角标");
|
|
3109
|
+
toggleScriptMark("superscript", "已切换上角标");
|
|
2892
3110
|
});
|
|
2893
3111
|
floatSubscriptBtn.addEventListener("click", () => {
|
|
2894
|
-
|
|
2895
|
-
document.execCommand("subscript", false);
|
|
2896
|
-
}, "已应用下角标");
|
|
3112
|
+
toggleScriptMark("subscript", "已切换下角标");
|
|
2897
3113
|
});
|
|
2898
3114
|
floatFontSizeSelect.addEventListener("change", () => {
|
|
2899
3115
|
applyFontSize(floatFontSizeSelect.value);
|
|
@@ -3537,12 +3753,14 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
3537
3753
|
rememberActiveParagraphIndex();
|
|
3538
3754
|
updateInlineResizeOverlay();
|
|
3539
3755
|
updateFloatingToolbarBySelection();
|
|
3756
|
+
syncToolbarState();
|
|
3540
3757
|
syncFocusedTableControls();
|
|
3541
3758
|
});
|
|
3542
3759
|
editorArea.addEventListener("keyup", () => {
|
|
3543
3760
|
rememberActiveParagraphIndex();
|
|
3544
3761
|
updateInlineResizeOverlay();
|
|
3545
3762
|
updateFloatingToolbarBySelection();
|
|
3763
|
+
syncToolbarState();
|
|
3546
3764
|
syncFocusedTableControls();
|
|
3547
3765
|
});
|
|
3548
3766
|
editorArea.addEventListener("blur", () => {
|
|
@@ -3565,6 +3783,7 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
3565
3783
|
syncFocusedTableControls();
|
|
3566
3784
|
};
|
|
3567
3785
|
const handleWindowResize = () => {
|
|
3786
|
+
updateShellViewportHeight();
|
|
3568
3787
|
updateInlineResizeOverlay();
|
|
3569
3788
|
syncTableToolsPosition();
|
|
3570
3789
|
syncFocusedTableControls();
|
|
@@ -3573,6 +3792,7 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
3573
3792
|
}
|
|
3574
3793
|
};
|
|
3575
3794
|
const handleWindowScroll = () => {
|
|
3795
|
+
updateShellViewportHeight();
|
|
3576
3796
|
updateInlineResizeOverlay();
|
|
3577
3797
|
updateFloatingToolbarBySelection();
|
|
3578
3798
|
syncTableToolsPosition();
|
|
@@ -3592,6 +3812,17 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
3592
3812
|
};
|
|
3593
3813
|
window.addEventListener("resize", handleWindowResize);
|
|
3594
3814
|
window.addEventListener("scroll", handleWindowScroll, true);
|
|
3815
|
+
const handleFullscreenChange = () => {
|
|
3816
|
+
window.requestAnimationFrame(() => {
|
|
3817
|
+
updateFullscreenButtonState();
|
|
3818
|
+
updateShellViewportHeight();
|
|
3819
|
+
updateInlineResizeOverlay();
|
|
3820
|
+
syncTableToolsPosition();
|
|
3821
|
+
syncFocusedTableControls();
|
|
3822
|
+
});
|
|
3823
|
+
};
|
|
3824
|
+
document.addEventListener("fullscreenchange", handleFullscreenChange);
|
|
3825
|
+
document.addEventListener("webkitfullscreenchange", handleFullscreenChange);
|
|
3595
3826
|
document.addEventListener("selectionchange", handleSelectionChange);
|
|
3596
3827
|
const handleDocumentPointerDownForPalette = (event) => {
|
|
3597
3828
|
const clickTarget = event.target;
|
|
@@ -3663,6 +3894,9 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
3663
3894
|
};
|
|
3664
3895
|
document.addEventListener("pointerdown", handleDocumentPointerDownForPalette);
|
|
3665
3896
|
document.addEventListener("keydown", handleDocumentKeyDown);
|
|
3897
|
+
fullscreenBtn.addEventListener("click", () => {
|
|
3898
|
+
void toggleWorkbenchFullscreen();
|
|
3899
|
+
});
|
|
3666
3900
|
tableAddBtn.addEventListener("mousedown", preserveSelectionForInputControl);
|
|
3667
3901
|
videoAddBtn.addEventListener("mousedown", preserveSelectionForInputControl);
|
|
3668
3902
|
videoAddBtn.addEventListener("click", () => {
|
|
@@ -3742,6 +3976,8 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
3742
3976
|
nextPageBtn.addEventListener("click", () => jumpPage(1));
|
|
3743
3977
|
addPageBtn.addEventListener("click", addPage);
|
|
3744
3978
|
render();
|
|
3979
|
+
updateFullscreenButtonState();
|
|
3980
|
+
updateShellViewportHeight();
|
|
3745
3981
|
syncToolbarState();
|
|
3746
3982
|
emitDocumentChange();
|
|
3747
3983
|
return {
|
|
@@ -3755,6 +3991,8 @@ export function mountEditorWorkbench(container, options = {}) {
|
|
|
3755
3991
|
window.removeEventListener("scroll", handleWindowScroll, true);
|
|
3756
3992
|
document.removeEventListener("pointerdown", handleDocumentPointerDownForPalette);
|
|
3757
3993
|
document.removeEventListener("keydown", handleDocumentKeyDown);
|
|
3994
|
+
document.removeEventListener("fullscreenchange", handleFullscreenChange);
|
|
3995
|
+
document.removeEventListener("webkitfullscreenchange", handleFullscreenChange);
|
|
3758
3996
|
container.innerHTML = "";
|
|
3759
3997
|
},
|
|
3760
3998
|
getDocument: () => clone(state.doc),
|
|
@@ -4593,7 +4831,7 @@ function resolveMammothModule(namespace) {
|
|
|
4593
4831
|
const candidate = namespace?.default ?? namespace;
|
|
4594
4832
|
return candidate;
|
|
4595
4833
|
}
|
|
4596
|
-
async function parseDocxFlowBlocksFromXml(arrayBuffer) {
|
|
4834
|
+
async function parseDocxFlowBlocksFromXml(arrayBuffer, maxFlowBlockWidth) {
|
|
4597
4835
|
try {
|
|
4598
4836
|
const archive = await loadDocxArchive(arrayBuffer);
|
|
4599
4837
|
if (!archive) {
|
|
@@ -4609,7 +4847,7 @@ async function parseDocxFlowBlocksFromXml(arrayBuffer) {
|
|
|
4609
4847
|
const themeXml = await archive
|
|
4610
4848
|
.file("word/theme/theme1.xml")
|
|
4611
4849
|
?.async("string");
|
|
4612
|
-
return parseDocxBodyToFlowBlocks(documentXml, stylesXml, themeXml);
|
|
4850
|
+
return parseDocxBodyToFlowBlocks(documentXml, stylesXml, themeXml, maxFlowBlockWidth);
|
|
4613
4851
|
}
|
|
4614
4852
|
catch {
|
|
4615
4853
|
return undefined;
|
|
@@ -4623,7 +4861,7 @@ async function loadDocxArchive(arrayBuffer) {
|
|
|
4623
4861
|
}
|
|
4624
4862
|
return zipRuntime.loadAsync(arrayBuffer);
|
|
4625
4863
|
}
|
|
4626
|
-
function parseDocxBodyToFlowBlocks(documentXml, stylesXml, themeXml) {
|
|
4864
|
+
function parseDocxBodyToFlowBlocks(documentXml, stylesXml, themeXml, maxFlowBlockWidth) {
|
|
4627
4865
|
const parser = new DOMParser();
|
|
4628
4866
|
const documentDoc = parser.parseFromString(documentXml, "application/xml");
|
|
4629
4867
|
const body = findDescendantByLocalName(documentDoc.documentElement, "body");
|
|
@@ -4642,7 +4880,7 @@ function parseDocxBodyToFlowBlocks(documentXml, stylesXml, themeXml) {
|
|
|
4642
4880
|
continue;
|
|
4643
4881
|
}
|
|
4644
4882
|
if (name === "tbl") {
|
|
4645
|
-
blocks.push(parseDocxTableNode(child, index, styleContext));
|
|
4883
|
+
blocks.push(parseDocxTableNode(child, index, styleContext, maxFlowBlockWidth));
|
|
4646
4884
|
index += 1;
|
|
4647
4885
|
}
|
|
4648
4886
|
}
|
|
@@ -4974,11 +5212,11 @@ function mergeTextMarks(...sources) {
|
|
|
4974
5212
|
}
|
|
4975
5213
|
return merged;
|
|
4976
5214
|
}
|
|
4977
|
-
function parseDocxTableNode(tableNode, index, styleContext) {
|
|
5215
|
+
function parseDocxTableNode(tableNode, index, styleContext, maxFlowBlockWidth) {
|
|
4978
5216
|
const tableProps = childXmlNodeByLocalName(tableNode, "tblPr");
|
|
4979
5217
|
const tableStyleId = xmlAttribute(childXmlNodeByLocalName(tableProps, "tblStyle"), "val");
|
|
4980
5218
|
const tableTextStyle = resolveDocxStyle(styleContext, tableStyleId, "table");
|
|
4981
|
-
const
|
|
5219
|
+
const tableStyleInfo = resolveDocxTableBlockStyle(tableProps, styleContext.themeColorMap, maxFlowBlockWidth);
|
|
4982
5220
|
const tableBorders = resolveDocxTableBorderSet(tableProps, styleContext.themeColorMap);
|
|
4983
5221
|
const rowNodes = Array.from(tableNode.children).filter((node) => {
|
|
4984
5222
|
return xmlLocalName(node) === "tr";
|
|
@@ -5070,12 +5308,15 @@ function parseDocxTableNode(tableNode, index, styleContext) {
|
|
|
5070
5308
|
cells,
|
|
5071
5309
|
};
|
|
5072
5310
|
});
|
|
5311
|
+
const tableWidth = tableStyleInfo.widthPx ??
|
|
5312
|
+
resolveFlowBlockWidthWithinBounds(maxFlowBlockWidth, DEFAULT_FLOW_BLOCK_WIDTH) ??
|
|
5313
|
+
DEFAULT_FLOW_BLOCK_WIDTH;
|
|
5073
5314
|
return {
|
|
5074
5315
|
id: `table-${Date.now()}-${index}`,
|
|
5075
5316
|
type: "table",
|
|
5076
|
-
rect: { x: 80, y: 80 + index * 24, width:
|
|
5317
|
+
rect: { x: 80, y: 80 + index * 24, width: tableWidth, height: 120 },
|
|
5077
5318
|
zIndex: index + 1,
|
|
5078
|
-
...(
|
|
5319
|
+
...(tableStyleInfo.style ? { style: tableStyleInfo.style } : {}),
|
|
5079
5320
|
rows: rows.length
|
|
5080
5321
|
? rows
|
|
5081
5322
|
: [
|
|
@@ -5110,9 +5351,9 @@ function resolvePrimaryTextStyleFromParagraphs(paragraphs) {
|
|
|
5110
5351
|
}
|
|
5111
5352
|
return undefined;
|
|
5112
5353
|
}
|
|
5113
|
-
function resolveDocxTableBlockStyle(tableProps, themeColorMap) {
|
|
5354
|
+
function resolveDocxTableBlockStyle(tableProps, themeColorMap, maxFlowBlockWidth) {
|
|
5114
5355
|
const borders = childXmlNodeByLocalName(tableProps, "tblBorders");
|
|
5115
|
-
const tableWidth = resolveDocxTableWidthPx(tableProps);
|
|
5356
|
+
const tableWidth = resolveFlowBlockWidthWithinBounds(maxFlowBlockWidth, resolveDocxTableWidthPx(tableProps));
|
|
5116
5357
|
const styleTokens = ["border-collapse:collapse"];
|
|
5117
5358
|
const borderSides = [
|
|
5118
5359
|
"top",
|
|
@@ -5132,7 +5373,36 @@ function resolveDocxTableBlockStyle(tableProps, themeColorMap) {
|
|
|
5132
5373
|
if (tableWidth !== undefined) {
|
|
5133
5374
|
styleTokens.push(`width:${tableWidth}px`);
|
|
5134
5375
|
}
|
|
5135
|
-
return
|
|
5376
|
+
return {
|
|
5377
|
+
style: styleTokens.join(";"),
|
|
5378
|
+
widthPx: tableWidth,
|
|
5379
|
+
};
|
|
5380
|
+
}
|
|
5381
|
+
function resolveFlowBlockWidthWithinBounds(maxWidth, preferredWidth) {
|
|
5382
|
+
const safeMax = Number.isFinite(maxWidth) && Number(maxWidth) > 0
|
|
5383
|
+
? Math.max(1, Math.round(Number(maxWidth)))
|
|
5384
|
+
: undefined;
|
|
5385
|
+
const safePreferred = Number.isFinite(preferredWidth) && Number(preferredWidth) > 0
|
|
5386
|
+
? Math.max(1, Math.round(Number(preferredWidth)))
|
|
5387
|
+
: undefined;
|
|
5388
|
+
if (safeMax === undefined) {
|
|
5389
|
+
return safePreferred;
|
|
5390
|
+
}
|
|
5391
|
+
if (safePreferred === undefined) {
|
|
5392
|
+
return safeMax;
|
|
5393
|
+
}
|
|
5394
|
+
return Math.min(safePreferred, safeMax);
|
|
5395
|
+
}
|
|
5396
|
+
function resolveDocxImportMaxFlowBlockWidth(page, fallbackPaperWidth) {
|
|
5397
|
+
const pageWidth = resolvePaperWidth(page.width, fallbackPaperWidth);
|
|
5398
|
+
const marginLeft = Number.isFinite(page.marginLeft)
|
|
5399
|
+
? Math.max(0, page.marginLeft)
|
|
5400
|
+
: 0;
|
|
5401
|
+
const marginRight = Number.isFinite(page.marginRight)
|
|
5402
|
+
? Math.max(0, page.marginRight)
|
|
5403
|
+
: 0;
|
|
5404
|
+
const availableWidth = Math.max(240, pageWidth - marginLeft - marginRight);
|
|
5405
|
+
return Math.min(DEFAULT_FLOW_BLOCK_WIDTH, availableWidth);
|
|
5136
5406
|
}
|
|
5137
5407
|
function resolveDocxTableCellStyle(cellProps, themeColorMap, rowHeight, tableBorders, gridPos) {
|
|
5138
5408
|
if (!cellProps) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hyebook/vue3-adapter",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Vue3 adapter for hy-ebook core",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"dist"
|
|
18
18
|
],
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"@hyebook/core": "^0.2.
|
|
20
|
+
"@hyebook/core": "^0.2.1"
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
23
|
"build": "tsc -p tsconfig.json",
|