@hyebook/vue3-adapter 0.2.1 → 0.2.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.
@@ -9,12 +9,22 @@ export interface EditorWorkbenchFeatures {
9
9
  export interface EditorWorkbenchOptions {
10
10
  initialDoc?: EbookDoc;
11
11
  features?: Partial<EditorWorkbenchFeatures>;
12
+ previewAnnotations?: EditorWorkbenchPreviewAnnotationOptions;
12
13
  title?: string;
13
14
  pageWidth?: number;
14
15
  upload?: EditorWorkbenchUploadOptions;
15
16
  importDocx?: EditorWorkbenchDocxImportOptions;
16
17
  onDocumentChange?: (doc: EbookDoc) => void;
17
18
  }
19
+ export interface EditorWorkbenchPreviewAnnotationActions {
20
+ canDelete?: boolean;
21
+ }
22
+ export interface EditorWorkbenchPreviewAnnotationOptions {
23
+ showAnnotationList?: boolean;
24
+ enablePreviewSelectionToolbar?: boolean;
25
+ annotationListDefaultTab?: "highlights" | "notes";
26
+ annotationActions?: EditorWorkbenchPreviewAnnotationActions;
27
+ }
18
28
  export interface EditorWorkbenchDocxImportOptions {
19
29
  maxSizeBytes?: number;
20
30
  }
@@ -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;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"}
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;AA2KxB,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,kBAAkB,CAAC,EAAE,uCAAuC,CAAC;IAC7D,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,uCAAuC;IACtD,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,uCAAuC;IACtD,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,6BAA6B,CAAC,EAAE,OAAO,CAAC;IACxC,wBAAwB,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC;IAClD,iBAAiB,CAAC,EAAE,uCAAuC,CAAC;CAC7D;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;AAoSjC,wBAAgB,8BAA8B,IAAI,QAAQ,CA6GzD;AAED,wBAAgB,oBAAoB,CAClC,SAAS,EAAE,WAAW,EACtB,OAAO,GAAE,sBAA2B,GACnC,qBAAqB,CAs9JvB"}
@@ -23,7 +23,9 @@ const WORKBENCH_CSS = `
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
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
- .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}
26
+ .hyewb-preview-layout{display:grid;grid-template-columns:minmax(0,1fr);gap:12px;align-items:start}
27
+ .hyewb-preview-layout.with-annotation-panel{grid-template-columns:minmax(0,1fr) 300px}
28
+ .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;max-width:100%;box-sizing:border-box}
27
29
  .hyewb-editor{min-height:360px;outline:none;line-height:1.7;font-size:16px;color:#1e293b}
28
30
  .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)}
29
31
  .hyewb-float.show{display:inline-flex}
@@ -139,6 +141,29 @@ const WORKBENCH_CSS = `
139
141
  .hyewb-upload-progress{height:8px;background:#e2e8f0;border-radius:999px;overflow:hidden}
140
142
  .hyewb-upload-progress > span{display:block;height:100%;width:0;background:#0b7285;transition:width .18s ease}
141
143
  .hyewb-upload-error{min-height:18px;font-size:12px;color:#b91c1c;margin:0}
144
+ .hyewb-preview-highlight-mark{background:var(--hyewb-highlight-color,#fff59d);color:inherit;padding:0 .08em;border-radius:.2em}
145
+ .hyewb-preview-note-mark{background:rgba(14,116,144,.14);border-bottom:2px solid #0e7490;color:inherit;padding:0 .04em;border-radius:.2em}
146
+ .hyewb-preview-annotation-panel{display:none;align-content:start;gap:10px;border:1px solid #d8e0ea;border-radius:10px;background:#ffffff;padding:12px;max-height:100%;overflow:auto}
147
+ .hyewb-preview-annotation-title{margin:0;font-size:14px}
148
+ .hyewb-preview-annotation-tabs{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:8px}
149
+ .hyewb-preview-annotation-tab{width:auto;min-width:0;height:32px;padding:0 12px;font-size:13px;border:1px solid #cbd5e1;border-radius:8px;background:#fff;color:#0f172a;cursor:pointer}
150
+ .hyewb-preview-annotation-tab.active{color:#ffffff;background:#0b7285;border-color:#0b7285}
151
+ .hyewb-preview-annotation-list{margin:0;padding:0;list-style:none;display:grid;gap:8px}
152
+ .hyewb-preview-annotation-item{width:100%;text-align:left;display:grid;gap:4px;padding:8px 36px 8px 8px;border-radius:8px;border:1px solid #dce5ef;background:#f8fafc;position:relative;cursor:pointer}
153
+ .hyewb-preview-annotation-item:hover{background:#eef6ff;border-color:#b9d7f4}
154
+ .hyewb-preview-annotation-item-title{font-size:12px;color:#0f766e}
155
+ .hyewb-preview-annotation-item-body{font-size:13px;color:#1e293b;line-height:1.5}
156
+ .hyewb-preview-annotation-delete{position:absolute;right:8px;top:8px;border-radius:8px;border:1px solid #f1b3b3;background:#fff5f5;color:#b42318;width:24px;height:24px;display:inline-flex;align-items:center;justify-content:center;opacity:0;pointer-events:none;transition:opacity .15s ease;cursor:pointer;padding:0}
157
+ .hyewb-preview-annotation-item:hover .hyewb-preview-annotation-delete{opacity:1;pointer-events:auto}
158
+ .hyewb-preview-annotation-delete svg{width:14px;height:14px}
159
+ .hyewb-preview-annotation-empty{margin:0;color:#64748b;font-size:13px}
160
+ .hyewb-preview-selection-toolbar{position:fixed;z-index:10060;display:none;align-items:center;gap:8px;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);transform:translate(-50%,-100%)}
161
+ .hyewb-preview-selection-toolbar.show{display:inline-flex}
162
+ .hyewb-preview-selection-btn{width:32px;height:32px;padding:0;display:inline-flex;align-items:center;justify-content:center;border:1px solid #334155;background:#1e293b;color:#f8fafc;border-radius:8px;cursor:pointer}
163
+ .hyewb-preview-selection-btn:hover{background:#334155}
164
+ .hyewb-preview-selection-btn svg{width:16px;height:16px}
165
+ .hyewb-preview-annotation-flash{animation:hyewb-preview-annotation-pulse .9s ease}
166
+ @keyframes hyewb-preview-annotation-pulse{0%{box-shadow:0 0 0 0 rgba(14,116,144,.4)}100%{box-shadow:0 0 0 12px rgba(14,116,144,0)}}
142
167
  .hyewb-root:fullscreen .hyewb-editor,.hyewb-root:fullscreen .hyewb-preview{min-height:1000px}
143
168
  .hyewb-root:-webkit-full-screen .hyewb-editor,.hyewb-root:-webkit-full-screen .hyewb-preview{min-height:1000px}
144
169
  `;
@@ -161,11 +186,13 @@ const WORKBENCH_ICON_PATHS = {
161
186
  "chevron-right": '<polyline points="9 18 15 12 9 6"/>',
162
187
  "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
188
  "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"/>',
189
+ highlighter: '<path d="M15 2l7 7-8.5 8.5-7-7z"/><path d="M12.5 11.5L2 22l6-1.5 6-6"/><line x1="13" y1="4" x2="20" y2="11"/>',
164
190
  "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"/>',
165
191
  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"/>',
166
192
  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"/>',
167
193
  "indent-increase": '<line x1="4" y1="6" x2="14" y2="6"/><line x1="4" y1="10" x2="10" y2="10"/><line x1="4" y1="14" x2="14" y2="14"/><line x1="4" y1="18" x2="10" y2="18"/><polyline points="15 9 19 12 15 15"/>',
168
194
  move: '<polyline points="8 4 12 1 16 4"/><line x1="12" y1="1" x2="12" y2="23"/><polyline points="8 20 12 23 16 20"/><polyline points="4 8 1 12 4 16"/><line x1="1" y1="12" x2="23" y2="12"/><polyline points="20 8 23 12 20 16"/>',
195
+ "notebook-pen": '<path d="M4 5a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2z"/><line x1="8" y1="7" x2="14" y2="7"/><line x1="8" y1="11" x2="14" y2="11"/><path d="M14.5 16.5l4-4 2 2-4 4-2.5.5z"/>',
169
196
  "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"/>',
170
197
  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"/>',
171
198
  pilcrow: '<path d="M9 4h7v16"/><path d="M12 4v16"/><path d="M9 4a4 4 0 0 0 0 8h3"/>',
@@ -175,6 +202,7 @@ const WORKBENCH_ICON_PATHS = {
175
202
  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
203
  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"/>',
177
204
  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"/>',
205
+ "trash-2": '<polyline points="3 6 5 6 21 6"/><path d="M8 6V4a1 1 0 0 1 1-1h6a1 1 0 0 1 1 1v2"/><path d="M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/>',
178
206
  underline: '<path d="M6 4v6a6 6 0 0 0 12 0V4"/><line x1="4" y1="20" x2="20" y2="20"/>',
179
207
  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"/>',
180
208
  x: '<line x1="6" y1="6" x2="18" y2="18"/><line x1="18" y1="6" x2="6" y2="18"/>',
@@ -274,6 +302,16 @@ const RESIZE_HANDLES = [
274
302
  "w",
275
303
  ];
276
304
  const DEFAULT_FLOW_BLOCK_WIDTH = 620;
305
+ function resolvePreviewAnnotationOptions(options) {
306
+ return {
307
+ showAnnotationList: options?.showAnnotationList ?? true,
308
+ enablePreviewSelectionToolbar: options?.enablePreviewSelectionToolbar ?? true,
309
+ annotationListDefaultTab: options?.annotationListDefaultTab === "notes" ? "notes" : "highlights",
310
+ annotationActions: {
311
+ canDelete: options?.annotationActions?.canDelete ?? true,
312
+ },
313
+ };
314
+ }
277
315
  export function createDefaultWorkbenchDocument() {
278
316
  const now = new Date().toISOString();
279
317
  return {
@@ -394,6 +432,7 @@ export function mountEditorWorkbench(container, options = {}) {
394
432
  doc: editor.getDocument(),
395
433
  features: resolveFeatures(options.features),
396
434
  };
435
+ const previewAnnotationOptions = resolvePreviewAnnotationOptions(options.previewAnnotations);
397
436
  const paperWidth = resolvePaperWidth(options.pageWidth, state.doc.settings.page.width);
398
437
  const root = document.createElement("section");
399
438
  root.className = "hyewb-root";
@@ -674,6 +713,8 @@ export function mountEditorWorkbench(container, options = {}) {
674
713
  pageInfo.className = "hyewb-status";
675
714
  fullscreenBtn.style.marginLeft = "auto";
676
715
  pageRow.append(prevPageBtn, nextPageBtn, addPageBtn, pageInfo, fullscreenBtn);
716
+ const previewLayout = document.createElement("div");
717
+ previewLayout.className = "hyewb-preview-layout";
677
718
  const shell = document.createElement("div");
678
719
  shell.className = "hyewb-shell";
679
720
  const canvas = document.createElement("div");
@@ -698,6 +739,43 @@ export function mountEditorWorkbench(container, options = {}) {
698
739
  mediaList.className = "hyewb-media-list";
699
740
  canvas.append(editorArea, previewArea, mediaStage, inlineResizeOverlay, mediaList);
700
741
  shell.append(canvas);
742
+ const annotationPanel = document.createElement("aside");
743
+ annotationPanel.className = "hyewb-preview-annotation-panel";
744
+ const annotationTitle = document.createElement("h3");
745
+ annotationTitle.className = "hyewb-preview-annotation-title";
746
+ annotationTitle.textContent = "预览标注";
747
+ const annotationTabs = document.createElement("div");
748
+ annotationTabs.className = "hyewb-preview-annotation-tabs";
749
+ const annotationHighlightTab = document.createElement("button");
750
+ annotationHighlightTab.type = "button";
751
+ annotationHighlightTab.className = "hyewb-preview-annotation-tab";
752
+ annotationHighlightTab.textContent = "高亮";
753
+ const annotationNoteTab = document.createElement("button");
754
+ annotationNoteTab.type = "button";
755
+ annotationNoteTab.className = "hyewb-preview-annotation-tab";
756
+ annotationNoteTab.textContent = "笔记";
757
+ annotationTabs.append(annotationHighlightTab, annotationNoteTab);
758
+ const annotationList = document.createElement("ul");
759
+ annotationList.className = "hyewb-preview-annotation-list";
760
+ const annotationEmpty = document.createElement("p");
761
+ annotationEmpty.className = "hyewb-preview-annotation-empty";
762
+ annotationPanel.append(annotationTitle, annotationTabs, annotationList, annotationEmpty);
763
+ previewLayout.append(shell, annotationPanel);
764
+ const previewSelectionToolbar = document.createElement("div");
765
+ previewSelectionToolbar.className = "hyewb-preview-selection-toolbar";
766
+ const previewHighlightBtn = document.createElement("button");
767
+ previewHighlightBtn.type = "button";
768
+ previewHighlightBtn.className = "hyewb-preview-selection-btn";
769
+ previewHighlightBtn.title = "创建高亮";
770
+ previewHighlightBtn.setAttribute("aria-label", "创建高亮");
771
+ previewHighlightBtn.append(createIconPlaceholder("highlighter"));
772
+ const previewNoteBtn = document.createElement("button");
773
+ previewNoteBtn.type = "button";
774
+ previewNoteBtn.className = "hyewb-preview-selection-btn";
775
+ previewNoteBtn.title = "创建笔记";
776
+ previewNoteBtn.setAttribute("aria-label", "创建笔记");
777
+ previewNoteBtn.append(createIconPlaceholder("notebook-pen"));
778
+ previewSelectionToolbar.append(previewHighlightBtn, previewNoteBtn);
701
779
  const floatingToolbar = document.createElement("div");
702
780
  floatingToolbar.className = "hyewb-float";
703
781
  const floatBoldBtn = createButton("bold");
@@ -772,7 +850,7 @@ export function mountEditorWorkbench(container, options = {}) {
772
850
  const colorGrid = document.createElement("div");
773
851
  colorGrid.className = "hyewb-color-grid";
774
852
  colorPalette.append(colorGrid);
775
- root.append(header, toolbar, pageRow, shell, status, colorPalette, tablePicker, tableTools, tableRowDeleteBtn, tableMoveHandle, tableScaleHandle, tableColEdgeLayer, tableRowEdgeLayer, tableRowGapInsertBtn, tableColGapInsertBtn, tableDropIndicator, tableContextMenu, uploadBackdrop, docxInput);
853
+ root.append(header, toolbar, pageRow, previewLayout, status, colorPalette, tablePicker, tableTools, tableRowDeleteBtn, tableMoveHandle, tableScaleHandle, tableColEdgeLayer, tableRowEdgeLayer, tableRowGapInsertBtn, tableColGapInsertBtn, tableDropIndicator, tableContextMenu, uploadBackdrop, docxInput, previewSelectionToolbar);
776
854
  container.innerHTML = "";
777
855
  container.append(root, floatingToolbar);
778
856
  renderWorkbenchIcons();
@@ -798,6 +876,8 @@ export function mountEditorWorkbench(container, options = {}) {
798
876
  let tableContextTarget = null;
799
877
  let selectedTableRowIndex = null;
800
878
  let selectedTableColIndex = null;
879
+ let annotationActiveTab = previewAnnotationOptions.annotationListDefaultTab;
880
+ let previewSelectionDraft = null;
801
881
  const isTableGapInsertTarget = (node) => {
802
882
  if (!node) {
803
883
  return false;
@@ -1132,6 +1212,7 @@ export function mountEditorWorkbench(container, options = {}) {
1132
1212
  syncEditorToDoc();
1133
1213
  state.mode = nextMode;
1134
1214
  hideFloatingToolbar();
1215
+ hidePreviewSelectionToolbar();
1135
1216
  render();
1136
1217
  };
1137
1218
  const loadPreviewAnnotations = () => {
@@ -1144,6 +1225,423 @@ export function mountEditorWorkbench(container, options = {}) {
1144
1225
  updateStateDoc(nextDoc);
1145
1226
  return clone(normalized);
1146
1227
  };
1228
+ const getCurrentPageId = () => {
1229
+ return state.doc.pages[state.pageIndex]?.id || `page-${state.pageIndex}`;
1230
+ };
1231
+ const normalizeOffsetRange = (start, end) => {
1232
+ const safeStart = Math.max(0, Math.floor(start || 0));
1233
+ const safeEnd = Math.max(0, Math.floor(end || 0));
1234
+ if (safeStart === safeEnd) {
1235
+ return null;
1236
+ }
1237
+ return safeStart < safeEnd
1238
+ ? { start: safeStart, end: safeEnd }
1239
+ : { start: safeEnd, end: safeStart };
1240
+ };
1241
+ const getNodeTextLength = (rootNode) => {
1242
+ if (!rootNode) {
1243
+ return 0;
1244
+ }
1245
+ const walker = document.createTreeWalker(rootNode, NodeFilter.SHOW_TEXT);
1246
+ let size = 0;
1247
+ while (walker.nextNode()) {
1248
+ size += walker.currentNode.textContent?.length || 0;
1249
+ }
1250
+ return size;
1251
+ };
1252
+ const getRangeTextLength = (range) => {
1253
+ if (!range) {
1254
+ return 0;
1255
+ }
1256
+ return getNodeTextLength(range.cloneContents());
1257
+ };
1258
+ const getSelectionOffsets = (containerNode, selection) => {
1259
+ if (!selection.rangeCount) {
1260
+ return null;
1261
+ }
1262
+ const range = selection.getRangeAt(0);
1263
+ if (!containerNode.contains(range.startContainer) ||
1264
+ !containerNode.contains(range.endContainer)) {
1265
+ return null;
1266
+ }
1267
+ const beforeStart = range.cloneRange();
1268
+ beforeStart.selectNodeContents(containerNode);
1269
+ beforeStart.setEnd(range.startContainer, range.startOffset);
1270
+ const beforeEnd = range.cloneRange();
1271
+ beforeEnd.selectNodeContents(containerNode);
1272
+ beforeEnd.setEnd(range.endContainer, range.endOffset);
1273
+ return normalizeOffsetRange(getRangeTextLength(beforeStart), getRangeTextLength(beforeEnd));
1274
+ };
1275
+ const createRangeFromOffsets = (containerNode, start, end) => {
1276
+ const normalized = normalizeOffsetRange(start, end);
1277
+ if (!normalized) {
1278
+ return null;
1279
+ }
1280
+ const range = document.createRange();
1281
+ const walker = document.createTreeWalker(containerNode, NodeFilter.SHOW_TEXT);
1282
+ let cursor = 0;
1283
+ let startNode = null;
1284
+ let endNode = null;
1285
+ let startOffset = 0;
1286
+ let endOffset = 0;
1287
+ let lastTextNode = null;
1288
+ while (walker.nextNode()) {
1289
+ const node = walker.currentNode;
1290
+ const length = node.textContent?.length || 0;
1291
+ lastTextNode = node;
1292
+ const nextCursor = cursor + length;
1293
+ if (!startNode &&
1294
+ normalized.start >= cursor &&
1295
+ normalized.start < nextCursor) {
1296
+ startNode = node;
1297
+ startOffset = normalized.start - cursor;
1298
+ }
1299
+ if (!endNode && normalized.end > cursor && normalized.end <= nextCursor) {
1300
+ endNode = node;
1301
+ endOffset = normalized.end - cursor;
1302
+ break;
1303
+ }
1304
+ cursor = nextCursor;
1305
+ }
1306
+ if (!startNode && lastTextNode && normalized.start === cursor) {
1307
+ startNode = lastTextNode;
1308
+ startOffset = lastTextNode.textContent?.length || 0;
1309
+ }
1310
+ if (!endNode && lastTextNode && normalized.end === cursor) {
1311
+ endNode = lastTextNode;
1312
+ endOffset = lastTextNode.textContent?.length || 0;
1313
+ }
1314
+ if (!startNode || !endNode) {
1315
+ return null;
1316
+ }
1317
+ range.setStart(startNode, startOffset);
1318
+ range.setEnd(endNode, endOffset);
1319
+ return range;
1320
+ };
1321
+ const unwrapPreviewMarks = (containerNode, kinds) => {
1322
+ const selector = kinds
1323
+ .map((kind) => `mark[data-preview-annotation='${kind}']`)
1324
+ .join(",");
1325
+ if (!selector) {
1326
+ return;
1327
+ }
1328
+ const marks = Array.from(containerNode.querySelectorAll(selector));
1329
+ marks.forEach((mark) => {
1330
+ const parent = mark.parentNode;
1331
+ if (!parent) {
1332
+ return;
1333
+ }
1334
+ while (mark.firstChild) {
1335
+ parent.insertBefore(mark.firstChild, mark);
1336
+ }
1337
+ parent.removeChild(mark);
1338
+ });
1339
+ };
1340
+ const applyHighlightMarks = (containerNode, highlights) => {
1341
+ unwrapPreviewMarks(containerNode, ["highlight"]);
1342
+ [...highlights]
1343
+ .filter((item) => Number.isFinite(item.start) && Number.isFinite(item.end))
1344
+ .sort((a, b) => b.start - a.start)
1345
+ .forEach((item) => {
1346
+ const range = createRangeFromOffsets(containerNode, item.start, item.end);
1347
+ if (!range || range.collapsed) {
1348
+ return;
1349
+ }
1350
+ const mark = document.createElement("mark");
1351
+ mark.dataset.previewAnnotation = "highlight";
1352
+ mark.className = "hyewb-preview-highlight-mark";
1353
+ mark.style.setProperty("--hyewb-highlight-color", item.color || "#fff59d");
1354
+ try {
1355
+ range.surroundContents(mark);
1356
+ }
1357
+ catch {
1358
+ const fragment = range.extractContents();
1359
+ mark.append(fragment);
1360
+ range.insertNode(mark);
1361
+ }
1362
+ });
1363
+ };
1364
+ const applyNoteMarks = (containerNode, notes) => {
1365
+ unwrapPreviewMarks(containerNode, ["note"]);
1366
+ [...notes]
1367
+ .filter((item) => Number.isFinite(item.start) && Number.isFinite(item.end))
1368
+ .sort((a, b) => b.start - a.start)
1369
+ .forEach((item) => {
1370
+ const range = createRangeFromOffsets(containerNode, item.start, item.end);
1371
+ if (!range || range.collapsed) {
1372
+ return;
1373
+ }
1374
+ const mark = document.createElement("mark");
1375
+ mark.dataset.previewAnnotation = "note";
1376
+ mark.dataset.previewNoteId = item.id || "";
1377
+ mark.className = "hyewb-preview-note-mark";
1378
+ try {
1379
+ range.surroundContents(mark);
1380
+ }
1381
+ catch {
1382
+ const fragment = range.extractContents();
1383
+ mark.append(fragment);
1384
+ range.insertNode(mark);
1385
+ }
1386
+ });
1387
+ };
1388
+ const mergeHighlightRecords = (records, draft) => {
1389
+ const normalized = normalizeOffsetRange(draft.start, draft.end);
1390
+ if (!normalized || !draft.pageId || !draft.blockId) {
1391
+ return records;
1392
+ }
1393
+ const targetColor = draft.color || "#fff59d";
1394
+ const sameBucket = [];
1395
+ const rest = [];
1396
+ records.forEach((item) => {
1397
+ if (item.pageId === draft.pageId &&
1398
+ item.blockId === draft.blockId &&
1399
+ (item.color || "#fff59d") === targetColor) {
1400
+ sameBucket.push(item);
1401
+ }
1402
+ else {
1403
+ rest.push(item);
1404
+ }
1405
+ });
1406
+ let mergedStart = normalized.start;
1407
+ let mergedEnd = normalized.end;
1408
+ const kept = [];
1409
+ sameBucket.forEach((item) => {
1410
+ const overlap = !(item.end < mergedStart || item.start > mergedEnd);
1411
+ if (overlap) {
1412
+ mergedStart = Math.min(mergedStart, item.start);
1413
+ mergedEnd = Math.max(mergedEnd, item.end);
1414
+ }
1415
+ else {
1416
+ kept.push(item);
1417
+ }
1418
+ });
1419
+ return [
1420
+ ...rest,
1421
+ ...kept,
1422
+ {
1423
+ ...draft,
1424
+ start: mergedStart,
1425
+ end: mergedEnd,
1426
+ },
1427
+ ];
1428
+ };
1429
+ const mergeNoteRecords = (records, draft) => {
1430
+ const index = records.findIndex((item) => {
1431
+ return (item.pageId === draft.pageId &&
1432
+ item.start === draft.start &&
1433
+ item.end === draft.end);
1434
+ });
1435
+ if (index === -1) {
1436
+ return [...records, draft];
1437
+ }
1438
+ const next = [...records];
1439
+ const existing = next[index];
1440
+ if (!existing) {
1441
+ return [...records, draft];
1442
+ }
1443
+ next[index] = {
1444
+ ...existing,
1445
+ ...draft,
1446
+ id: existing.id || draft.id,
1447
+ updatedAt: new Date().toISOString(),
1448
+ };
1449
+ return next;
1450
+ };
1451
+ const summarizePreviewText = (text, fallback, maxLength = 52) => {
1452
+ const raw = String(text || "")
1453
+ .replace(/\s+/g, " ")
1454
+ .trim();
1455
+ if (!raw) {
1456
+ return fallback;
1457
+ }
1458
+ return raw.length > maxLength ? `${raw.slice(0, maxLength)}...` : raw;
1459
+ };
1460
+ const flashPreviewAnnotationTarget = (node) => {
1461
+ if (!node || !node.classList) {
1462
+ return;
1463
+ }
1464
+ node.classList.remove("hyewb-preview-annotation-flash");
1465
+ void node.offsetWidth;
1466
+ node.classList.add("hyewb-preview-annotation-flash");
1467
+ window.setTimeout(() => {
1468
+ node.classList.remove("hyewb-preview-annotation-flash");
1469
+ }, 900);
1470
+ };
1471
+ const focusPreviewAnnotationRecord = (record, kind) => {
1472
+ let target = null;
1473
+ if (kind === "note" && "id" in record && record.id) {
1474
+ const noteId = String(record.id);
1475
+ target = previewArea.querySelector(`mark[data-preview-annotation='note'][data-preview-note-id='${noteId.replace(/["\\]/g, "\\$&")}']`);
1476
+ }
1477
+ if (!target) {
1478
+ const range = createRangeFromOffsets(previewArea, record.start, record.end);
1479
+ if (range && !range.collapsed) {
1480
+ const node = range.startContainer;
1481
+ target =
1482
+ node.nodeType === Node.ELEMENT_NODE
1483
+ ? node
1484
+ : node.parentElement;
1485
+ }
1486
+ }
1487
+ if (!target ||
1488
+ typeof target.scrollIntoView !== "function") {
1489
+ return;
1490
+ }
1491
+ target.scrollIntoView({
1492
+ behavior: "smooth",
1493
+ block: "center",
1494
+ inline: "nearest",
1495
+ });
1496
+ flashPreviewAnnotationTarget(target);
1497
+ };
1498
+ const getPreviewAnnotationsByPage = () => {
1499
+ const pageId = getCurrentPageId();
1500
+ const annotations = normalizePreviewAnnotations(state.doc.meta.previewAnnotations);
1501
+ return {
1502
+ annotations,
1503
+ pageId,
1504
+ highlights: annotations.highlights.filter((item) => item.pageId === pageId),
1505
+ notes: annotations.notes.filter((item) => item.pageId === pageId),
1506
+ };
1507
+ };
1508
+ const renderAnnotationPanel = () => {
1509
+ const shouldShowPanel = state.mode === "preview" &&
1510
+ state.features.preview &&
1511
+ previewAnnotationOptions.showAnnotationList;
1512
+ annotationPanel.style.display = shouldShowPanel ? "grid" : "none";
1513
+ previewLayout.classList.toggle("with-annotation-panel", shouldShowPanel);
1514
+ if (!shouldShowPanel) {
1515
+ return;
1516
+ }
1517
+ const { highlights, notes } = getPreviewAnnotationsByPage();
1518
+ annotationHighlightTab.classList.toggle("active", annotationActiveTab === "highlights");
1519
+ annotationNoteTab.classList.toggle("active", annotationActiveTab === "notes");
1520
+ const activeList = annotationActiveTab === "highlights" ? highlights : notes;
1521
+ annotationList.innerHTML = "";
1522
+ if (!activeList.length) {
1523
+ annotationEmpty.style.display = "block";
1524
+ annotationEmpty.textContent =
1525
+ annotationActiveTab === "highlights"
1526
+ ? "当前页暂无高亮"
1527
+ : "当前页暂无笔记";
1528
+ return;
1529
+ }
1530
+ annotationEmpty.style.display = "none";
1531
+ activeList.forEach((record, index) => {
1532
+ const item = document.createElement("li");
1533
+ const button = document.createElement("button");
1534
+ button.type = "button";
1535
+ button.className = "hyewb-preview-annotation-item";
1536
+ const heading = document.createElement("span");
1537
+ heading.className = "hyewb-preview-annotation-item-title";
1538
+ heading.textContent =
1539
+ annotationActiveTab === "highlights"
1540
+ ? `高亮 ${index + 1}`
1541
+ : `笔记 ${index + 1}`;
1542
+ const body = document.createElement("span");
1543
+ body.className = "hyewb-preview-annotation-item-body";
1544
+ const fallbackRange = `[${record.start}, ${record.end}]`;
1545
+ body.textContent =
1546
+ annotationActiveTab === "highlights"
1547
+ ? summarizePreviewText(record.selectedText, fallbackRange)
1548
+ : summarizePreviewText(record.text, "未命名笔记");
1549
+ button.append(heading, body);
1550
+ button.addEventListener("click", () => {
1551
+ focusPreviewAnnotationRecord(record, annotationActiveTab === "highlights" ? "highlight" : "note");
1552
+ });
1553
+ if (previewAnnotationOptions.annotationActions.canDelete) {
1554
+ const deleteButton = document.createElement("button");
1555
+ deleteButton.type = "button";
1556
+ deleteButton.className = "hyewb-preview-annotation-delete";
1557
+ deleteButton.title = "删除标注";
1558
+ deleteButton.setAttribute("aria-label", "删除标注");
1559
+ deleteButton.append(createIconPlaceholder("trash-2"));
1560
+ deleteButton.addEventListener("click", (event) => {
1561
+ event.preventDefault();
1562
+ event.stopPropagation();
1563
+ if (!window.confirm("确定删除这条标注吗?")) {
1564
+ return;
1565
+ }
1566
+ const current = normalizePreviewAnnotations(state.doc.meta.previewAnnotations);
1567
+ if (annotationActiveTab === "highlights") {
1568
+ current.highlights = current.highlights.filter((item) => {
1569
+ if ("id" in record && record.id && item.id) {
1570
+ return String(item.id) !== String(record.id);
1571
+ }
1572
+ return !(item.pageId === record.pageId &&
1573
+ item.start === record.start &&
1574
+ item.end === record.end);
1575
+ });
1576
+ }
1577
+ else {
1578
+ current.notes = current.notes.filter((item) => {
1579
+ if ("id" in record && record.id && item.id) {
1580
+ return String(item.id) !== String(record.id);
1581
+ }
1582
+ return !(item.pageId === record.pageId &&
1583
+ item.start === record.start &&
1584
+ item.end === record.end);
1585
+ });
1586
+ }
1587
+ savePreviewAnnotations(current);
1588
+ });
1589
+ button.append(deleteButton);
1590
+ }
1591
+ item.append(button);
1592
+ annotationList.append(item);
1593
+ });
1594
+ };
1595
+ const applyPreviewAnnotationsToView = () => {
1596
+ if (state.mode !== "preview") {
1597
+ previewSelectionToolbar.classList.remove("show");
1598
+ return;
1599
+ }
1600
+ const { highlights, notes } = getPreviewAnnotationsByPage();
1601
+ applyHighlightMarks(previewArea, highlights);
1602
+ applyNoteMarks(previewArea, notes);
1603
+ };
1604
+ const hidePreviewSelectionToolbar = () => {
1605
+ previewSelectionToolbar.classList.remove("show");
1606
+ previewSelectionDraft = null;
1607
+ };
1608
+ const syncPreviewSelectionToolbar = () => {
1609
+ if (!previewAnnotationOptions.enablePreviewSelectionToolbar ||
1610
+ state.mode !== "preview") {
1611
+ hidePreviewSelectionToolbar();
1612
+ return;
1613
+ }
1614
+ const selection = window.getSelection();
1615
+ if (!selection || selection.rangeCount === 0 || selection.isCollapsed) {
1616
+ hidePreviewSelectionToolbar();
1617
+ return;
1618
+ }
1619
+ const range = selection.getRangeAt(0);
1620
+ if (!previewArea.contains(range.startContainer) ||
1621
+ !previewArea.contains(range.endContainer)) {
1622
+ hidePreviewSelectionToolbar();
1623
+ return;
1624
+ }
1625
+ const offsets = getSelectionOffsets(previewArea, selection);
1626
+ if (!offsets) {
1627
+ hidePreviewSelectionToolbar();
1628
+ return;
1629
+ }
1630
+ const rect = range.getBoundingClientRect();
1631
+ if (!rect.width && !rect.height) {
1632
+ hidePreviewSelectionToolbar();
1633
+ return;
1634
+ }
1635
+ previewSelectionDraft = {
1636
+ start: offsets.start,
1637
+ end: offsets.end,
1638
+ pageId: getCurrentPageId(),
1639
+ text: selection.toString().trim(),
1640
+ };
1641
+ previewSelectionToolbar.style.left = `${Math.round(rect.left + rect.width / 2)}px`;
1642
+ previewSelectionToolbar.style.top = `${Math.round(rect.top - 8)}px`;
1643
+ previewSelectionToolbar.classList.add("show");
1644
+ };
1147
1645
  const hideFloatingToolbar = () => {
1148
1646
  floatingToolbar.classList.remove("show");
1149
1647
  lastSelection = null;
@@ -2844,7 +3342,14 @@ export function mountEditorWorkbench(container, options = {}) {
2844
3342
  selectInlineImage(null);
2845
3343
  rememberedParagraphIndex = null;
2846
3344
  }
2847
- canvas.style.width = `${paperWidth}px`;
3345
+ if (state.mode === "preview") {
3346
+ canvas.style.width = "100%";
3347
+ canvas.style.maxWidth = `${paperWidth}px`;
3348
+ }
3349
+ else {
3350
+ canvas.style.width = `${paperWidth}px`;
3351
+ canvas.style.maxWidth = "100%";
3352
+ }
2848
3353
  previewArea.innerHTML = html;
2849
3354
  previewArea.classList.toggle("show", state.mode === "preview");
2850
3355
  editorArea.style.display = state.mode === "editor" ? "block" : "none";
@@ -2937,6 +3442,9 @@ export function mountEditorWorkbench(container, options = {}) {
2937
3442
  });
2938
3443
  updateInlineResizeOverlay();
2939
3444
  syncToolbarState();
3445
+ applyPreviewAnnotationsToView();
3446
+ renderAnnotationPanel();
3447
+ syncPreviewSelectionToolbar();
2940
3448
  };
2941
3449
  boldBtn.addEventListener("click", () => {
2942
3450
  withSelectionCommand(() => {
@@ -3127,6 +3635,59 @@ export function mountEditorWorkbench(container, options = {}) {
3127
3635
  floatBgColorInput.addEventListener("click", () => {
3128
3636
  openColorPalette(floatBgColorInput, "background");
3129
3637
  });
3638
+ annotationHighlightTab.addEventListener("click", () => {
3639
+ annotationActiveTab = "highlights";
3640
+ renderAnnotationPanel();
3641
+ });
3642
+ annotationNoteTab.addEventListener("click", () => {
3643
+ annotationActiveTab = "notes";
3644
+ renderAnnotationPanel();
3645
+ });
3646
+ previewHighlightBtn.addEventListener("click", () => {
3647
+ if (!previewSelectionDraft) {
3648
+ return;
3649
+ }
3650
+ const current = normalizePreviewAnnotations(state.doc.meta.previewAnnotations);
3651
+ current.highlights = mergeHighlightRecords(current.highlights, {
3652
+ id: `hl-${Date.now()}-${Math.round(Math.random() * 10000)}`,
3653
+ pageId: previewSelectionDraft.pageId,
3654
+ blockId: "preview-flow-text",
3655
+ start: previewSelectionDraft.start,
3656
+ end: previewSelectionDraft.end,
3657
+ color: "#fff59d",
3658
+ selectedText: previewSelectionDraft.text,
3659
+ createdAt: new Date().toISOString(),
3660
+ });
3661
+ annotationActiveTab = "highlights";
3662
+ savePreviewAnnotations(current);
3663
+ window.getSelection()?.removeAllRanges();
3664
+ hidePreviewSelectionToolbar();
3665
+ });
3666
+ previewNoteBtn.addEventListener("click", () => {
3667
+ if (!previewSelectionDraft) {
3668
+ return;
3669
+ }
3670
+ const text = window.prompt("请输入笔记内容", previewSelectionDraft.text || "") || "";
3671
+ const noteText = text.trim();
3672
+ if (!noteText) {
3673
+ return;
3674
+ }
3675
+ const current = normalizePreviewAnnotations(state.doc.meta.previewAnnotations);
3676
+ current.notes = mergeNoteRecords(current.notes, {
3677
+ id: `note-${Date.now()}-${Math.round(Math.random() * 10000)}`,
3678
+ pageId: previewSelectionDraft.pageId,
3679
+ start: previewSelectionDraft.start,
3680
+ end: previewSelectionDraft.end,
3681
+ text: noteText,
3682
+ selectedText: previewSelectionDraft.text,
3683
+ color: "#0e7490",
3684
+ createdAt: new Date().toISOString(),
3685
+ });
3686
+ annotationActiveTab = "notes";
3687
+ savePreviewAnnotations(current);
3688
+ window.getSelection()?.removeAllRanges();
3689
+ hidePreviewSelectionToolbar();
3690
+ });
3130
3691
  floatLeftBtn.addEventListener("click", () => updateAlign("left"));
3131
3692
  floatCenterBtn.addEventListener("click", () => updateAlign("center"));
3132
3693
  floatRightBtn.addEventListener("click", () => updateAlign("right"));
@@ -3781,12 +4342,14 @@ export function mountEditorWorkbench(container, options = {}) {
3781
4342
  updateInlineResizeOverlay();
3782
4343
  syncToolbarState();
3783
4344
  syncFocusedTableControls();
4345
+ syncPreviewSelectionToolbar();
3784
4346
  };
3785
4347
  const handleWindowResize = () => {
3786
4348
  updateShellViewportHeight();
3787
4349
  updateInlineResizeOverlay();
3788
4350
  syncTableToolsPosition();
3789
4351
  syncFocusedTableControls();
4352
+ syncPreviewSelectionToolbar();
3790
4353
  if (tablePicker.classList.contains("show")) {
3791
4354
  showTablePicker();
3792
4355
  }
@@ -3797,6 +4360,7 @@ export function mountEditorWorkbench(container, options = {}) {
3797
4360
  updateFloatingToolbarBySelection();
3798
4361
  syncTableToolsPosition();
3799
4362
  syncFocusedTableControls();
4363
+ syncPreviewSelectionToolbar();
3800
4364
  if (tablePicker.classList.contains("show")) {
3801
4365
  showTablePicker();
3802
4366
  }
@@ -3819,6 +4383,7 @@ export function mountEditorWorkbench(container, options = {}) {
3819
4383
  updateInlineResizeOverlay();
3820
4384
  syncTableToolsPosition();
3821
4385
  syncFocusedTableControls();
4386
+ syncPreviewSelectionToolbar();
3822
4387
  });
3823
4388
  };
3824
4389
  document.addEventListener("fullscreenchange", handleFullscreenChange);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hyebook/vue3-adapter",
3
- "version": "0.2.1",
3
+ "version": "0.2.2",
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.1"
20
+ "@hyebook/core": "^0.2.2"
21
21
  },
22
22
  "scripts": {
23
23
  "build": "tsc -p tsconfig.json",