superdoc 1.12.0-next.11 → 1.12.0-next.13
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/chunks/{PdfViewer-1H_e-blH.cjs → PdfViewer-BM8GbrHb.cjs} +2 -2
- package/dist/chunks/{PdfViewer-2GmHPcuP.es.js → PdfViewer-D9duMPBd.es.js} +2 -2
- package/dist/chunks/{SuperConverter-DKC3eAnw.cjs → SuperConverter-BMjvGr5r.cjs} +14 -3
- package/dist/chunks/{SuperConverter-Cyd0kGmJ.es.js → SuperConverter-Dx95dNlr.es.js} +14 -3
- package/dist/chunks/{index-BKXPlsQF.cjs → index-BF7DfWLs.cjs} +756 -390
- package/dist/chunks/{index-BlzZBR33.es.js → index-BTrpAvox.es.js} +4 -4
- package/dist/chunks/{index-C22k0MUW.es.js → index-C-t9SDCr.es.js} +756 -390
- package/dist/chunks/{index-CpgpR-lf.cjs → index-DcUDN9u9.cjs} +4 -4
- package/dist/style.css +39 -29
- package/dist/super-editor/converter.cjs +1 -1
- package/dist/super-editor/converter.es.js +1 -1
- package/dist/super-editor/core/Editor.d.ts.map +1 -1
- package/dist/super-editor/core/presentation-editor/PresentationEditor.d.ts.map +1 -1
- package/dist/super-editor/core/super-converter/v3/handlers/w/sdt/helpers/handle-structured-content-node.d.ts.map +1 -1
- package/dist/super-editor/extensions/structured-content/StructuredContentBlockView.d.ts.map +1 -1
- package/dist/super-editor/extensions/structured-content/StructuredContentInlineView.d.ts.map +1 -1
- package/dist/super-editor/extensions/structured-content/StructuredContentViewBase.d.ts +3 -0
- package/dist/super-editor/extensions/structured-content/StructuredContentViewBase.d.ts.map +1 -1
- package/dist/super-editor/extensions/structured-content/structured-content-block.d.ts.map +1 -1
- package/dist/super-editor/extensions/structured-content/structured-content-lock-plugin.d.ts +5 -0
- package/dist/super-editor/extensions/structured-content/structured-content-lock-plugin.d.ts.map +1 -0
- package/dist/super-editor/extensions/structured-content/structured-content-select-plugin.d.ts +14 -0
- package/dist/super-editor/extensions/structured-content/structured-content-select-plugin.d.ts.map +1 -0
- package/dist/super-editor/extensions/structured-content/structured-content.d.ts.map +1 -1
- package/dist/super-editor/extensions/types/node-attributes.d.ts +4 -0
- package/dist/super-editor/extensions/types/node-attributes.d.ts.map +1 -1
- package/dist/super-editor.cjs +2 -2
- package/dist/super-editor.es.js +3 -3
- package/dist/superdoc.cjs +3 -3
- package/dist/superdoc.es.js +3 -3
- package/dist/superdoc.umd.js +770 -393
- package/dist/superdoc.umd.js.map +1 -1
- package/package.json +1 -1
package/dist/superdoc.umd.js
CHANGED
|
@@ -13908,6 +13908,10 @@
|
|
|
13908
13908
|
const id = sdtPr?.elements?.find((el) => el.name === "w:id");
|
|
13909
13909
|
const tag = sdtPr?.elements?.find((el) => el.name === "w:tag");
|
|
13910
13910
|
const alias = sdtPr?.elements?.find((el) => el.name === "w:alias");
|
|
13911
|
+
const lockTag = sdtPr?.elements?.find((el) => el.name === "w:lock");
|
|
13912
|
+
const lockValue = lockTag?.attributes?.["w:val"];
|
|
13913
|
+
const validModes = ["unlocked", "sdtLocked", "contentLocked", "sdtContentLocked"];
|
|
13914
|
+
const lockMode = validModes.includes(lockValue) ? lockValue : "unlocked";
|
|
13911
13915
|
if (!sdtContent) {
|
|
13912
13916
|
return null;
|
|
13913
13917
|
}
|
|
@@ -13929,6 +13933,7 @@
|
|
|
13929
13933
|
id: id?.attributes?.["w:val"] || null,
|
|
13930
13934
|
tag: tag?.attributes?.["w:val"] || null,
|
|
13931
13935
|
alias: alias?.attributes?.["w:val"] || null,
|
|
13936
|
+
lockMode,
|
|
13932
13937
|
sdtPr
|
|
13933
13938
|
}
|
|
13934
13939
|
};
|
|
@@ -30649,13 +30654,19 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
30649
30654
|
type: "element",
|
|
30650
30655
|
attributes: { "w:val": attrs.tag }
|
|
30651
30656
|
};
|
|
30657
|
+
const lock = {
|
|
30658
|
+
name: "w:lock",
|
|
30659
|
+
type: "element",
|
|
30660
|
+
attributes: { "w:val": attrs.lockMode }
|
|
30661
|
+
};
|
|
30652
30662
|
const resultElements = [];
|
|
30653
30663
|
if (attrs.id) resultElements.push(id);
|
|
30654
30664
|
if (attrs.alias) resultElements.push(alias);
|
|
30655
30665
|
if (attrs.tag) resultElements.push(tag);
|
|
30666
|
+
if (attrs.lockMode && attrs.lockMode !== "unlocked") resultElements.push(lock);
|
|
30656
30667
|
if (attrs.sdtPr) {
|
|
30657
30668
|
const elements = attrs.sdtPr.elements || [];
|
|
30658
|
-
const elementsToExclude = ["w:id", "w:alias", "w:tag"];
|
|
30669
|
+
const elementsToExclude = ["w:id", "w:alias", "w:tag", "w:lock"];
|
|
30659
30670
|
const restElements = elements.filter((el) => !elementsToExclude.includes(el.name));
|
|
30660
30671
|
const result2 = {
|
|
30661
30672
|
name: "w:sdtPr",
|
|
@@ -34367,7 +34378,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
34367
34378
|
const COMMUNITY_LICENSE_KEY = "community-and-eval-agplv3";
|
|
34368
34379
|
function getSuperdocVersion() {
|
|
34369
34380
|
try {
|
|
34370
|
-
return true ? "1.12.0-next.
|
|
34381
|
+
return true ? "1.12.0-next.13" : "unknown";
|
|
34371
34382
|
} catch {
|
|
34372
34383
|
return "unknown";
|
|
34373
34384
|
}
|
|
@@ -36643,7 +36654,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
36643
36654
|
}
|
|
36644
36655
|
#replaceSpecialCharacters(text2) {
|
|
36645
36656
|
if (text2 === void 0 || text2 === null) return text2;
|
|
36646
|
-
return String(text2).replace(
|
|
36657
|
+
return String(text2).replace(/&(?!#\d+;|#x[0-9a-fA-F]+;|(?:amp|lt|gt|quot|apos);)/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
36647
36658
|
}
|
|
36648
36659
|
/**
|
|
36649
36660
|
* Recursively generates XML string representation from a JSON node structure.
|
|
@@ -37639,7 +37650,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
37639
37650
|
static getStoredSuperdocVersion(docx) {
|
|
37640
37651
|
return SuperConverter.getStoredCustomProperty(docx, "SuperdocVersion");
|
|
37641
37652
|
}
|
|
37642
|
-
static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.12.0-next.
|
|
37653
|
+
static setStoredSuperdocVersion(docx = this.convertedXml, version2 = "1.12.0-next.13") {
|
|
37643
37654
|
return SuperConverter.setStoredCustomProperty(docx, "SuperdocVersion", version2, false);
|
|
37644
37655
|
}
|
|
37645
37656
|
/**
|
|
@@ -65116,7 +65127,7 @@ ${err.toString()}`);
|
|
|
65116
65127
|
return false;
|
|
65117
65128
|
}
|
|
65118
65129
|
};
|
|
65119
|
-
const summaryVersion = "1.12.0-next.
|
|
65130
|
+
const summaryVersion = "1.12.0-next.13";
|
|
65120
65131
|
const nodeKeys = ["group", "content", "marks", "inline", "atom", "defining", "code", "tableRole", "summary"];
|
|
65121
65132
|
const markKeys = ["group", "inclusive", "excludes", "spanning", "code"];
|
|
65122
65133
|
function mapAttributes(attrs) {
|
|
@@ -67531,8 +67542,7 @@ ${err.toString()}`);
|
|
|
67531
67542
|
"docProps/custom.xml": String(customXml),
|
|
67532
67543
|
"word/_rels/document.xml.rels": String(rels),
|
|
67533
67544
|
"word/numbering.xml": String(numbering),
|
|
67534
|
-
|
|
67535
|
-
"word/styles.xml": String(styles).replace(/&/gi, "&"),
|
|
67545
|
+
"word/styles.xml": String(styles),
|
|
67536
67546
|
...updatedHeadersFooters,
|
|
67537
67547
|
...coreXml ? { "docProps/core.xml": String(coreXml) } : {}
|
|
67538
67548
|
};
|
|
@@ -67922,7 +67932,7 @@ ${err.toString()}`);
|
|
|
67922
67932
|
* Process collaboration migrations
|
|
67923
67933
|
*/
|
|
67924
67934
|
processCollaborationMigrations() {
|
|
67925
|
-
console.debug("[checkVersionMigrations] Current editor version", "1.12.0-next.
|
|
67935
|
+
console.debug("[checkVersionMigrations] Current editor version", "1.12.0-next.13");
|
|
67926
67936
|
if (!this.options.ydoc) return;
|
|
67927
67937
|
const metaMap = this.options.ydoc.getMap("meta");
|
|
67928
67938
|
let docVersion = metaMap.get("version");
|
|
@@ -68100,6 +68110,300 @@ ${err.toString()}`);
|
|
|
68100
68110
|
this.#renderer?.initDevTools?.(this);
|
|
68101
68111
|
}
|
|
68102
68112
|
}
|
|
68113
|
+
function getEditorSurfaceElement(editor) {
|
|
68114
|
+
if (!editor) return null;
|
|
68115
|
+
if (typeof editor.hitTest === "function" && editor.element instanceof HTMLElement) {
|
|
68116
|
+
return editor.element;
|
|
68117
|
+
}
|
|
68118
|
+
return editor.presentationEditor?.element ?? editor.view?.dom ?? editor.options?.element ?? null;
|
|
68119
|
+
}
|
|
68120
|
+
function getSurfaceRelativePoint(editor, eventLocation = {}) {
|
|
68121
|
+
const surface = getEditorSurfaceElement(editor);
|
|
68122
|
+
if (!surface) return null;
|
|
68123
|
+
const rect = surface.getBoundingClientRect();
|
|
68124
|
+
let left2;
|
|
68125
|
+
let top2;
|
|
68126
|
+
if (typeof eventLocation.clientX === "number" && typeof eventLocation.clientY === "number") {
|
|
68127
|
+
left2 = eventLocation.clientX - rect.left;
|
|
68128
|
+
top2 = eventLocation.clientY - rect.top;
|
|
68129
|
+
} else if (editor?.state?.selection) {
|
|
68130
|
+
const selectionFrom = editor.state.selection.from;
|
|
68131
|
+
const coords = editor.coordsAtPos?.(selectionFrom);
|
|
68132
|
+
if (coords) {
|
|
68133
|
+
left2 = coords.left - rect.left;
|
|
68134
|
+
top2 = coords.top - rect.top;
|
|
68135
|
+
}
|
|
68136
|
+
}
|
|
68137
|
+
if (!Number.isFinite(left2) || !Number.isFinite(top2)) {
|
|
68138
|
+
return null;
|
|
68139
|
+
}
|
|
68140
|
+
return { left: left2, top: top2 };
|
|
68141
|
+
}
|
|
68142
|
+
function findContainingBlockAncestor(element2) {
|
|
68143
|
+
if (!element2) return null;
|
|
68144
|
+
let current = element2.parentElement;
|
|
68145
|
+
while (current && current !== document.body && current !== document.documentElement) {
|
|
68146
|
+
try {
|
|
68147
|
+
const style2 = window.getComputedStyle(current);
|
|
68148
|
+
const transform = style2.transform;
|
|
68149
|
+
const filter = style2.filter;
|
|
68150
|
+
const backdropFilter = style2.backdropFilter || style2.webkitBackdropFilter;
|
|
68151
|
+
const perspective = style2.perspective;
|
|
68152
|
+
const willChange = style2.willChange;
|
|
68153
|
+
const contain = style2.contain;
|
|
68154
|
+
if (transform && transform !== "none") {
|
|
68155
|
+
return current;
|
|
68156
|
+
}
|
|
68157
|
+
if (filter && filter !== "none") {
|
|
68158
|
+
return current;
|
|
68159
|
+
}
|
|
68160
|
+
if (backdropFilter && backdropFilter !== "none") {
|
|
68161
|
+
return current;
|
|
68162
|
+
}
|
|
68163
|
+
if (perspective && perspective !== "none") {
|
|
68164
|
+
return current;
|
|
68165
|
+
}
|
|
68166
|
+
if (willChange && willChange !== "auto") {
|
|
68167
|
+
const values = willChange.split(",").map((v2) => v2.trim());
|
|
68168
|
+
if (values.includes("transform") || values.includes("perspective")) {
|
|
68169
|
+
return current;
|
|
68170
|
+
}
|
|
68171
|
+
}
|
|
68172
|
+
if (contain && /paint|layout|strict|content/.test(contain)) {
|
|
68173
|
+
return current;
|
|
68174
|
+
}
|
|
68175
|
+
} catch (error) {
|
|
68176
|
+
console.warn("SlashMenu: Failed to get computed style for element", current, error);
|
|
68177
|
+
}
|
|
68178
|
+
current = current.parentElement;
|
|
68179
|
+
}
|
|
68180
|
+
return null;
|
|
68181
|
+
}
|
|
68182
|
+
const SlashMenuPluginKey = new PluginKey("slashMenu");
|
|
68183
|
+
const MENU_OFFSET_X = 100;
|
|
68184
|
+
const MENU_OFFSET_Y = 28;
|
|
68185
|
+
const CONTEXT_MENU_OFFSET_X = 10;
|
|
68186
|
+
const CONTEXT_MENU_OFFSET_Y = 10;
|
|
68187
|
+
const SLASH_COOLDOWN_MS = 5e3;
|
|
68188
|
+
const SlashMenu = Extension.create({
|
|
68189
|
+
name: "slashMenu",
|
|
68190
|
+
/**
|
|
68191
|
+
* Initialize default options for the SlashMenu extension
|
|
68192
|
+
* @returns {SlashMenuOptions} Empty options object (configuration is inherited from editor options)
|
|
68193
|
+
*/
|
|
68194
|
+
addOptions() {
|
|
68195
|
+
return {};
|
|
68196
|
+
},
|
|
68197
|
+
addPmPlugins() {
|
|
68198
|
+
const editor = this.editor;
|
|
68199
|
+
if (editor.options?.isHeadless) {
|
|
68200
|
+
return [];
|
|
68201
|
+
}
|
|
68202
|
+
let slashCooldown = false;
|
|
68203
|
+
let slashCooldownTimeout = null;
|
|
68204
|
+
const isMenuDisabled = () => Boolean(editor.options?.disableContextMenu);
|
|
68205
|
+
const ensureStateShape = (value = {}) => ({
|
|
68206
|
+
open: false,
|
|
68207
|
+
selected: null,
|
|
68208
|
+
anchorPos: null,
|
|
68209
|
+
menuPosition: null,
|
|
68210
|
+
disabled: isMenuDisabled(),
|
|
68211
|
+
...value
|
|
68212
|
+
});
|
|
68213
|
+
const slashMenuPlugin = new Plugin({
|
|
68214
|
+
key: SlashMenuPluginKey,
|
|
68215
|
+
state: {
|
|
68216
|
+
init: () => ensureStateShape(),
|
|
68217
|
+
/**
|
|
68218
|
+
* Apply transaction to update plugin state
|
|
68219
|
+
* Handles state transitions based on transaction metadata:
|
|
68220
|
+
* - 'open': Opens menu at specified position or cursor location
|
|
68221
|
+
* - 'select': Updates the selected menu item
|
|
68222
|
+
* - 'close': Closes the menu and clears anchor position
|
|
68223
|
+
* - 'updatePosition': Triggers menu position recalculation (no-op in apply)
|
|
68224
|
+
*
|
|
68225
|
+
* @param {import('prosemirror-state').Transaction} tr - The transaction
|
|
68226
|
+
* @param {SlashMenuState} value - Previous plugin state
|
|
68227
|
+
* @returns {SlashMenuState} New plugin state
|
|
68228
|
+
*/
|
|
68229
|
+
apply(tr, value) {
|
|
68230
|
+
const meta2 = tr.getMeta(SlashMenuPluginKey);
|
|
68231
|
+
const disabled = isMenuDisabled();
|
|
68232
|
+
if (disabled) {
|
|
68233
|
+
if (value.open) {
|
|
68234
|
+
editor.emit("slashMenu:close");
|
|
68235
|
+
}
|
|
68236
|
+
return ensureStateShape({ disabled: true });
|
|
68237
|
+
}
|
|
68238
|
+
if (!meta2) {
|
|
68239
|
+
if (value.disabled !== disabled) {
|
|
68240
|
+
return ensureStateShape({ ...value, disabled });
|
|
68241
|
+
}
|
|
68242
|
+
return value;
|
|
68243
|
+
}
|
|
68244
|
+
switch (meta2.type) {
|
|
68245
|
+
case "open": {
|
|
68246
|
+
if (typeof meta2.pos !== "number" || meta2.pos < 0 || meta2.pos > tr.doc.content.size) {
|
|
68247
|
+
console.warn("SlashMenu: Invalid position", meta2.pos);
|
|
68248
|
+
return ensureStateShape(value);
|
|
68249
|
+
}
|
|
68250
|
+
let left2 = 0;
|
|
68251
|
+
let top2 = 0;
|
|
68252
|
+
let isContextMenu = false;
|
|
68253
|
+
if (typeof meta2.clientX === "number" && typeof meta2.clientY === "number") {
|
|
68254
|
+
left2 = meta2.clientX;
|
|
68255
|
+
top2 = meta2.clientY;
|
|
68256
|
+
isContextMenu = true;
|
|
68257
|
+
} else {
|
|
68258
|
+
const relativePoint = getSurfaceRelativePoint(editor, meta2);
|
|
68259
|
+
if (relativePoint) {
|
|
68260
|
+
const surface = editor.presentationEditor?.element ?? editor.view?.dom ?? editor.options?.element;
|
|
68261
|
+
if (surface) {
|
|
68262
|
+
try {
|
|
68263
|
+
const rect = surface.getBoundingClientRect();
|
|
68264
|
+
left2 = rect.left + relativePoint.left;
|
|
68265
|
+
top2 = rect.top + relativePoint.top;
|
|
68266
|
+
} catch (error) {
|
|
68267
|
+
console.warn("SlashMenu: Failed to get surface bounds", error);
|
|
68268
|
+
return ensureStateShape(value);
|
|
68269
|
+
}
|
|
68270
|
+
}
|
|
68271
|
+
}
|
|
68272
|
+
}
|
|
68273
|
+
const menuSurface = editor.presentationEditor?.element ?? editor.view?.dom ?? editor.options?.element;
|
|
68274
|
+
const containingBlock = findContainingBlockAncestor(menuSurface);
|
|
68275
|
+
if (containingBlock) {
|
|
68276
|
+
try {
|
|
68277
|
+
const cbRect = containingBlock.getBoundingClientRect();
|
|
68278
|
+
left2 -= cbRect.left;
|
|
68279
|
+
top2 -= cbRect.top;
|
|
68280
|
+
left2 += containingBlock.scrollLeft || 0;
|
|
68281
|
+
top2 += containingBlock.scrollTop || 0;
|
|
68282
|
+
} catch (error) {
|
|
68283
|
+
console.warn("SlashMenu: Failed to adjust for containing block", error);
|
|
68284
|
+
}
|
|
68285
|
+
}
|
|
68286
|
+
const offsetX = isContextMenu ? CONTEXT_MENU_OFFSET_X : MENU_OFFSET_X;
|
|
68287
|
+
const offsetY = isContextMenu ? CONTEXT_MENU_OFFSET_Y : MENU_OFFSET_Y;
|
|
68288
|
+
const menuPosition = {
|
|
68289
|
+
left: `${left2 + offsetX}px`,
|
|
68290
|
+
top: `${top2 + offsetY}px`
|
|
68291
|
+
};
|
|
68292
|
+
const newState = {
|
|
68293
|
+
...value,
|
|
68294
|
+
open: true,
|
|
68295
|
+
anchorPos: meta2.pos,
|
|
68296
|
+
menuPosition
|
|
68297
|
+
};
|
|
68298
|
+
editor.emit("slashMenu:open", { menuPosition });
|
|
68299
|
+
return ensureStateShape(newState);
|
|
68300
|
+
}
|
|
68301
|
+
case "select": {
|
|
68302
|
+
return ensureStateShape({ ...value, selected: meta2.id });
|
|
68303
|
+
}
|
|
68304
|
+
case "close": {
|
|
68305
|
+
editor.emit("slashMenu:close");
|
|
68306
|
+
return ensureStateShape({ ...value, open: false, anchorPos: null });
|
|
68307
|
+
}
|
|
68308
|
+
default:
|
|
68309
|
+
return ensureStateShape({ ...value, disabled });
|
|
68310
|
+
}
|
|
68311
|
+
}
|
|
68312
|
+
},
|
|
68313
|
+
/**
|
|
68314
|
+
* Create view plugin to handle window event listeners
|
|
68315
|
+
* @param {import('prosemirror-view').EditorView} editorView - The ProseMirror editor view
|
|
68316
|
+
* @returns {Object} View plugin with destroy method
|
|
68317
|
+
*/
|
|
68318
|
+
view(editorView) {
|
|
68319
|
+
const updatePosition2 = () => {
|
|
68320
|
+
if (isMenuDisabled()) return;
|
|
68321
|
+
const state = SlashMenuPluginKey.getState(editorView.state);
|
|
68322
|
+
if (state.open) {
|
|
68323
|
+
editorView.dispatch(
|
|
68324
|
+
editorView.state.tr.setMeta(SlashMenuPluginKey, {
|
|
68325
|
+
type: "updatePosition"
|
|
68326
|
+
})
|
|
68327
|
+
);
|
|
68328
|
+
}
|
|
68329
|
+
};
|
|
68330
|
+
window.addEventListener("scroll", updatePosition2, true);
|
|
68331
|
+
window.addEventListener("resize", updatePosition2);
|
|
68332
|
+
return {
|
|
68333
|
+
destroy() {
|
|
68334
|
+
window.removeEventListener("scroll", updatePosition2, true);
|
|
68335
|
+
window.removeEventListener("resize", updatePosition2);
|
|
68336
|
+
if (slashCooldownTimeout) {
|
|
68337
|
+
clearTimeout(slashCooldownTimeout);
|
|
68338
|
+
slashCooldownTimeout = null;
|
|
68339
|
+
}
|
|
68340
|
+
}
|
|
68341
|
+
};
|
|
68342
|
+
},
|
|
68343
|
+
props: {
|
|
68344
|
+
/**
|
|
68345
|
+
* Handle keyboard events to open/close the slash menu
|
|
68346
|
+
* - '/': Opens menu at cursor if conditions are met (in paragraph, after space/start)
|
|
68347
|
+
* - 'Escape' or 'ArrowLeft': Closes menu and restores cursor position
|
|
68348
|
+
*
|
|
68349
|
+
* @param {import('prosemirror-view').EditorView} view - The ProseMirror editor view
|
|
68350
|
+
* @param {KeyboardEvent} event - The keyboard event
|
|
68351
|
+
* @returns {boolean} True if the event was handled, false otherwise
|
|
68352
|
+
*/
|
|
68353
|
+
handleKeyDown(view, event) {
|
|
68354
|
+
if (isMenuDisabled()) {
|
|
68355
|
+
return false;
|
|
68356
|
+
}
|
|
68357
|
+
const pluginState = this.getState(view.state);
|
|
68358
|
+
if (event.key === "/" && slashCooldown) {
|
|
68359
|
+
return false;
|
|
68360
|
+
}
|
|
68361
|
+
if (event.key === "/" && !pluginState.open) {
|
|
68362
|
+
const { $cursor } = view.state.selection;
|
|
68363
|
+
if (!$cursor) return false;
|
|
68364
|
+
const isParagraph = $cursor.parent.type.name === "paragraph";
|
|
68365
|
+
if (!isParagraph) return false;
|
|
68366
|
+
const textBefore = $cursor.parent.textContent.slice(0, $cursor.parentOffset);
|
|
68367
|
+
const isEmptyOrAfterSpace = !textBefore || textBefore.endsWith(" ");
|
|
68368
|
+
if (!isEmptyOrAfterSpace) return false;
|
|
68369
|
+
event.preventDefault();
|
|
68370
|
+
slashCooldown = true;
|
|
68371
|
+
if (slashCooldownTimeout) clearTimeout(slashCooldownTimeout);
|
|
68372
|
+
slashCooldownTimeout = setTimeout(() => {
|
|
68373
|
+
slashCooldown = false;
|
|
68374
|
+
slashCooldownTimeout = null;
|
|
68375
|
+
}, SLASH_COOLDOWN_MS);
|
|
68376
|
+
view.dispatch(
|
|
68377
|
+
view.state.tr.setMeta(SlashMenuPluginKey, {
|
|
68378
|
+
type: "open",
|
|
68379
|
+
pos: $cursor.pos
|
|
68380
|
+
})
|
|
68381
|
+
);
|
|
68382
|
+
return true;
|
|
68383
|
+
}
|
|
68384
|
+
if (pluginState.open && (event.key === "Escape" || event.key === "ArrowLeft")) {
|
|
68385
|
+
const { anchorPos } = pluginState;
|
|
68386
|
+
view.dispatch(
|
|
68387
|
+
view.state.tr.setMeta(SlashMenuPluginKey, {
|
|
68388
|
+
type: "close"
|
|
68389
|
+
})
|
|
68390
|
+
);
|
|
68391
|
+
if (anchorPos !== null) {
|
|
68392
|
+
const tr = view.state.tr.setSelection(
|
|
68393
|
+
view.state.selection.constructor.near(view.state.doc.resolve(anchorPos))
|
|
68394
|
+
);
|
|
68395
|
+
view.dispatch(tr);
|
|
68396
|
+
view.focus();
|
|
68397
|
+
}
|
|
68398
|
+
return true;
|
|
68399
|
+
}
|
|
68400
|
+
return false;
|
|
68401
|
+
}
|
|
68402
|
+
}
|
|
68403
|
+
});
|
|
68404
|
+
return [slashMenuPlugin];
|
|
68405
|
+
}
|
|
68406
|
+
});
|
|
68103
68407
|
let readFromCache;
|
|
68104
68408
|
let addToCache;
|
|
68105
68409
|
if (typeof WeakMap != "undefined") {
|
|
@@ -73133,21 +73437,21 @@ ${o}
|
|
|
73133
73437
|
|
|
73134
73438
|
/* Structured content drag handle/label - positioned above */
|
|
73135
73439
|
.superdoc-structured-content__label {
|
|
73136
|
-
font-size:
|
|
73440
|
+
font-size: 11px;
|
|
73137
73441
|
align-items: center;
|
|
73138
73442
|
justify-content: center;
|
|
73139
73443
|
position: absolute;
|
|
73140
73444
|
left: 2px;
|
|
73141
73445
|
top: -19px;
|
|
73142
73446
|
width: calc(100% - 4px);
|
|
73143
|
-
max-width:
|
|
73447
|
+
max-width: 130px;
|
|
73144
73448
|
min-width: 0;
|
|
73145
73449
|
height: 18px;
|
|
73146
73450
|
padding: 0 4px;
|
|
73147
73451
|
border: 1px solid #629be7;
|
|
73148
73452
|
border-bottom: none;
|
|
73149
73453
|
border-radius: 6px 6px 0 0;
|
|
73150
|
-
background-color: #
|
|
73454
|
+
background-color: #629be7ee;
|
|
73151
73455
|
box-sizing: border-box;
|
|
73152
73456
|
z-index: 10;
|
|
73153
73457
|
display: none;
|
|
@@ -73161,7 +73465,9 @@ ${o}
|
|
|
73161
73465
|
text-overflow: ellipsis;
|
|
73162
73466
|
}
|
|
73163
73467
|
|
|
73164
|
-
|
|
73468
|
+
/* Hover effect for block structured content (via event delegation class).
|
|
73469
|
+
* Shows label on hover — border reveal is handled by the lock-mode hover rule below. */
|
|
73470
|
+
.superdoc-structured-content-block.sdt-hover .superdoc-structured-content__label {
|
|
73165
73471
|
display: inline-flex;
|
|
73166
73472
|
}
|
|
73167
73473
|
|
|
@@ -73190,6 +73496,13 @@ ${o}
|
|
|
73190
73496
|
border-bottom: none;
|
|
73191
73497
|
}
|
|
73192
73498
|
|
|
73499
|
+
/* Collapse double borders between adjacent SDT blocks */
|
|
73500
|
+
.superdoc-structured-content-block + .superdoc-structured-content-block {
|
|
73501
|
+
border-top: none;
|
|
73502
|
+
border-top-left-radius: 0;
|
|
73503
|
+
border-top-right-radius: 0;
|
|
73504
|
+
}
|
|
73505
|
+
|
|
73193
73506
|
/* Structured Content Inline - Inline wrapper with blue border */
|
|
73194
73507
|
.superdoc-structured-content-inline {
|
|
73195
73508
|
padding: 1px;
|
|
@@ -73201,21 +73514,15 @@ ${o}
|
|
|
73201
73514
|
z-index: 10;
|
|
73202
73515
|
}
|
|
73203
73516
|
|
|
73204
|
-
/* Hover effect for inline structured content */
|
|
73205
|
-
.superdoc-structured-content-inline:hover {
|
|
73206
|
-
background-color: rgba(98, 155, 231, 0.15);
|
|
73207
|
-
border-color: #4a8ad9;
|
|
73208
|
-
}
|
|
73209
|
-
|
|
73210
73517
|
/* Inline structured content label - shown on hover */
|
|
73211
73518
|
.superdoc-structured-content-inline__label {
|
|
73212
73519
|
position: absolute;
|
|
73213
73520
|
bottom: calc(100% + 2px);
|
|
73214
73521
|
left: 50%;
|
|
73215
73522
|
transform: translateX(-50%);
|
|
73216
|
-
font-size:
|
|
73217
|
-
padding:
|
|
73218
|
-
background-color: #
|
|
73523
|
+
font-size: 11px;
|
|
73524
|
+
padding: 0 4px;
|
|
73525
|
+
background-color: #629be7ee;
|
|
73219
73526
|
color: white;
|
|
73220
73527
|
border-radius: 4px;
|
|
73221
73528
|
white-space: nowrap;
|
|
@@ -73228,6 +73535,17 @@ ${o}
|
|
|
73228
73535
|
display: block;
|
|
73229
73536
|
}
|
|
73230
73537
|
|
|
73538
|
+
/* Hover highlight for SDT containers.
|
|
73539
|
+
* Blue border is always visible (set in base rules above).
|
|
73540
|
+
* Hover adds background highlight and z-index boost.
|
|
73541
|
+
* Block SDTs use .sdt-hover class (event delegation for multi-fragment coordination).
|
|
73542
|
+
* Inline SDTs use :hover (single element, no coordination needed). */
|
|
73543
|
+
.superdoc-structured-content-block[data-lock-mode].sdt-hover,
|
|
73544
|
+
.superdoc-structured-content-inline[data-lock-mode]:hover {
|
|
73545
|
+
background-color: rgba(98, 155, 231, 0.08);
|
|
73546
|
+
z-index: 9999999;
|
|
73547
|
+
}
|
|
73548
|
+
|
|
73231
73549
|
/* Viewing mode: remove structured content affordances */
|
|
73232
73550
|
.presentation-editor--viewing .superdoc-structured-content-block,
|
|
73233
73551
|
.presentation-editor--viewing .superdoc-structured-content-inline {
|
|
@@ -73273,7 +73591,7 @@ ${o}
|
|
|
73273
73591
|
.superdoc-layout .annotation *::selection {
|
|
73274
73592
|
background: transparent;
|
|
73275
73593
|
}
|
|
73276
|
-
|
|
73594
|
+
|
|
73277
73595
|
.superdoc-layout .annotation::-moz-selection,
|
|
73278
73596
|
.superdoc-layout .annotation *::-moz-selection {
|
|
73279
73597
|
background: transparent;
|
|
@@ -73425,7 +73743,16 @@ ${o}
|
|
|
73425
73743
|
* within this wrapper should be used for character-level positioning, not the
|
|
73426
73744
|
* wrapper itself.
|
|
73427
73745
|
*/
|
|
73428
|
-
INLINE_SDT_WRAPPER: "superdoc-structured-content-inline"
|
|
73746
|
+
INLINE_SDT_WRAPPER: "superdoc-structured-content-inline",
|
|
73747
|
+
/**
|
|
73748
|
+
* Class name for block-level structured content containers.
|
|
73749
|
+
*/
|
|
73750
|
+
BLOCK_SDT: "superdoc-structured-content-block",
|
|
73751
|
+
/**
|
|
73752
|
+
* Class name added to block SDT fragments on hover via event delegation.
|
|
73753
|
+
* Applied/removed by SdtGroupedHover to highlight all fragments of the same SDT.
|
|
73754
|
+
*/
|
|
73755
|
+
SDT_HOVER: "sdt-hover"
|
|
73429
73756
|
};
|
|
73430
73757
|
var define_process_default$8 = { env: {} };
|
|
73431
73758
|
const DEFAULT_ALLOWED_PROTOCOLS = ["http", "https", "mailto", "tel", "sms"];
|
|
@@ -73831,6 +74158,11 @@ ${o}
|
|
|
73831
74158
|
container.dataset.sdtContainerStart = String(isStart);
|
|
73832
74159
|
container.dataset.sdtContainerEnd = String(isEnd);
|
|
73833
74160
|
container.style.overflow = "visible";
|
|
74161
|
+
if (isStructuredContentMetadata(sdt)) {
|
|
74162
|
+
container.dataset.lockMode = sdt.lockMode || "unlocked";
|
|
74163
|
+
} else if (isStructuredContentMetadata(containerSdt)) {
|
|
74164
|
+
container.dataset.lockMode = containerSdt.lockMode || "unlocked";
|
|
74165
|
+
}
|
|
73834
74166
|
if (boundaryOptions?.widthOverride != null) {
|
|
73835
74167
|
container.style.width = `${boundaryOptions.widthOverride}px`;
|
|
73836
74168
|
}
|
|
@@ -73843,6 +74175,19 @@ ${o}
|
|
|
73843
74175
|
container.appendChild(labelEl);
|
|
73844
74176
|
}
|
|
73845
74177
|
}
|
|
74178
|
+
function shouldRebuildForSdtBoundary(element2, boundary) {
|
|
74179
|
+
if (!boundary) {
|
|
74180
|
+
return element2.dataset.sdtContainerStart !== void 0;
|
|
74181
|
+
}
|
|
74182
|
+
const startAttr = element2.dataset.sdtContainerStart;
|
|
74183
|
+
const endAttr = element2.dataset.sdtContainerEnd;
|
|
74184
|
+
const expectedStart = String(boundary.isStart ?? true);
|
|
74185
|
+
const expectedEnd = String(boundary.isEnd ?? true);
|
|
74186
|
+
if (startAttr === void 0 || endAttr === void 0) {
|
|
74187
|
+
return true;
|
|
74188
|
+
}
|
|
74189
|
+
return startAttr !== expectedStart || endAttr !== expectedEnd;
|
|
74190
|
+
}
|
|
73846
74191
|
const TWIPS_PER_INCH$4 = 1440;
|
|
73847
74192
|
const PX_PER_INCH$3 = 96;
|
|
73848
74193
|
const PX_PER_PT = 96 / 72;
|
|
@@ -75322,6 +75667,65 @@ ${o}
|
|
|
75322
75667
|
const hasPmEnd = fragment.pmEnd != null;
|
|
75323
75668
|
globalValidationStats.record(hasPmStart, hasPmEnd);
|
|
75324
75669
|
}
|
|
75670
|
+
const SDT_BLOCK_SELECTOR = `.${DOM_CLASS_NAMES.BLOCK_SDT}[data-sdt-id]`;
|
|
75671
|
+
const HOVER_CLASS = DOM_CLASS_NAMES.SDT_HOVER;
|
|
75672
|
+
function sdtElementsById(root2, sdtId) {
|
|
75673
|
+
return root2.querySelectorAll(`.${DOM_CLASS_NAMES.BLOCK_SDT}[data-sdt-id="${sdtId}"]`);
|
|
75674
|
+
}
|
|
75675
|
+
class SdtGroupedHover {
|
|
75676
|
+
constructor() {
|
|
75677
|
+
this.hoveredSdtId = null;
|
|
75678
|
+
this.mount = null;
|
|
75679
|
+
this.onMouseOver = null;
|
|
75680
|
+
this.onMouseLeave = null;
|
|
75681
|
+
}
|
|
75682
|
+
/** Attach hover listeners to the mount element. Safe to call again on remount. */
|
|
75683
|
+
bind(mount2) {
|
|
75684
|
+
this.destroy();
|
|
75685
|
+
this.mount = mount2;
|
|
75686
|
+
this.onMouseOver = (e) => {
|
|
75687
|
+
const target = e.target.closest?.(SDT_BLOCK_SELECTOR);
|
|
75688
|
+
const sdtId = target?.dataset.sdtId ?? null;
|
|
75689
|
+
if (sdtId === this.hoveredSdtId) return;
|
|
75690
|
+
if (this.hoveredSdtId) {
|
|
75691
|
+
sdtElementsById(mount2, this.hoveredSdtId).forEach((el) => el.classList.remove(HOVER_CLASS));
|
|
75692
|
+
}
|
|
75693
|
+
this.hoveredSdtId = sdtId;
|
|
75694
|
+
if (sdtId) {
|
|
75695
|
+
sdtElementsById(mount2, sdtId).forEach((el) => el.classList.add(HOVER_CLASS));
|
|
75696
|
+
}
|
|
75697
|
+
};
|
|
75698
|
+
this.onMouseLeave = () => {
|
|
75699
|
+
if (this.hoveredSdtId) {
|
|
75700
|
+
sdtElementsById(mount2, this.hoveredSdtId).forEach((el) => el.classList.remove(HOVER_CLASS));
|
|
75701
|
+
this.hoveredSdtId = null;
|
|
75702
|
+
}
|
|
75703
|
+
};
|
|
75704
|
+
mount2.addEventListener("mouseover", this.onMouseOver);
|
|
75705
|
+
mount2.addEventListener("mouseleave", this.onMouseLeave);
|
|
75706
|
+
}
|
|
75707
|
+
/** Re-apply hover class after render. New/rebuilt elements lose the class. */
|
|
75708
|
+
reapply() {
|
|
75709
|
+
if (this.hoveredSdtId && this.mount) {
|
|
75710
|
+
sdtElementsById(this.mount, this.hoveredSdtId).forEach((el) => el.classList.add(HOVER_CLASS));
|
|
75711
|
+
}
|
|
75712
|
+
}
|
|
75713
|
+
/** Remove listeners and reset state. */
|
|
75714
|
+
destroy() {
|
|
75715
|
+
if (this.mount) {
|
|
75716
|
+
if (this.onMouseOver) {
|
|
75717
|
+
this.mount.removeEventListener("mouseover", this.onMouseOver);
|
|
75718
|
+
}
|
|
75719
|
+
if (this.onMouseLeave) {
|
|
75720
|
+
this.mount.removeEventListener("mouseleave", this.onMouseLeave);
|
|
75721
|
+
}
|
|
75722
|
+
}
|
|
75723
|
+
this.mount = null;
|
|
75724
|
+
this.onMouseOver = null;
|
|
75725
|
+
this.onMouseLeave = null;
|
|
75726
|
+
this.hoveredSdtId = null;
|
|
75727
|
+
}
|
|
75728
|
+
}
|
|
75325
75729
|
const DEFAULT_PPI = 96;
|
|
75326
75730
|
const DEFAULT_RULER_HEIGHT = 25;
|
|
75327
75731
|
const TICK_SPACING_PX = DEFAULT_PPI / 8;
|
|
@@ -76030,6 +76434,7 @@ ${o}
|
|
|
76030
76434
|
this.onScrollHandler = null;
|
|
76031
76435
|
this.onWindowScrollHandler = null;
|
|
76032
76436
|
this.onResizeHandler = null;
|
|
76437
|
+
this.sdtHover = new SdtGroupedHover();
|
|
76033
76438
|
this.activeCommentId = null;
|
|
76034
76439
|
this.options = options;
|
|
76035
76440
|
this.layoutMode = options.layoutMode ?? "vertical";
|
|
@@ -76295,6 +76700,7 @@ ${o}
|
|
|
76295
76700
|
};
|
|
76296
76701
|
win.addEventListener("resize", this.onResizeHandler);
|
|
76297
76702
|
}
|
|
76703
|
+
this.sdtHover.bind(mount2);
|
|
76298
76704
|
}
|
|
76299
76705
|
computeVirtualMetrics() {
|
|
76300
76706
|
if (!this.currentLayout) return;
|
|
@@ -76437,6 +76843,7 @@ ${o}
|
|
|
76437
76843
|
}
|
|
76438
76844
|
this.changedBlocks.clear();
|
|
76439
76845
|
this.processedLayoutVersion = this.layoutVersion;
|
|
76846
|
+
this.sdtHover.reapply();
|
|
76440
76847
|
}
|
|
76441
76848
|
updateSpacers(start2, end2) {
|
|
76442
76849
|
if (!this.topSpacerEl || !this.bottomSpacerEl) return;
|
|
@@ -76721,6 +77128,7 @@ ${o}
|
|
|
76721
77128
|
this.onScrollHandler = null;
|
|
76722
77129
|
this.onWindowScrollHandler = null;
|
|
76723
77130
|
this.onResizeHandler = null;
|
|
77131
|
+
this.sdtHover.destroy();
|
|
76724
77132
|
this.layoutVersion = 0;
|
|
76725
77133
|
this.processedLayoutVersion = -1;
|
|
76726
77134
|
}
|
|
@@ -76782,7 +77190,9 @@ ${o}
|
|
|
76782
77190
|
if (current) {
|
|
76783
77191
|
existing.delete(key2);
|
|
76784
77192
|
const sdtBoundaryMismatch = shouldRebuildForSdtBoundary(current.element, sdtBoundary);
|
|
76785
|
-
const
|
|
77193
|
+
const newPmStart = fragment.pmStart;
|
|
77194
|
+
const mappingUnreliable = this.currentMapping != null && newPmStart != null && current.element.dataset.pmStart != null && this.currentMapping.map(Number(current.element.dataset.pmStart)) !== newPmStart;
|
|
77195
|
+
const needsRebuild = this.changedBlocks.has(fragment.blockId) || current.signature !== fragmentSignature(fragment, this.blockLookup) || sdtBoundaryMismatch || mappingUnreliable;
|
|
76786
77196
|
if (needsRebuild) {
|
|
76787
77197
|
const replacement = this.renderFragment(fragment, contextBase, sdtBoundary);
|
|
76788
77198
|
pageEl.replaceChild(replacement, current.element);
|
|
@@ -78868,6 +79278,43 @@ ${o}
|
|
|
78868
79278
|
}
|
|
78869
79279
|
return void 0;
|
|
78870
79280
|
};
|
|
79281
|
+
let geoSdtWrapper = null;
|
|
79282
|
+
let geoSdtId = null;
|
|
79283
|
+
let geoSdtWrapperLeft = 0;
|
|
79284
|
+
let geoSdtMaxRight = 0;
|
|
79285
|
+
const closeGeoSdtWrapper = () => {
|
|
79286
|
+
if (geoSdtWrapper) {
|
|
79287
|
+
geoSdtWrapper.style.width = `${geoSdtMaxRight - geoSdtWrapperLeft}px`;
|
|
79288
|
+
el.appendChild(geoSdtWrapper);
|
|
79289
|
+
geoSdtWrapper = null;
|
|
79290
|
+
geoSdtId = null;
|
|
79291
|
+
}
|
|
79292
|
+
};
|
|
79293
|
+
const appendToLineGeo = (elem, runForSdt, elemLeftPx, elemWidthPx) => {
|
|
79294
|
+
const resolved = this.resolveRunSdtId(runForSdt);
|
|
79295
|
+
const thisRunSdtId = resolved?.sdtId ?? null;
|
|
79296
|
+
if (thisRunSdtId !== geoSdtId) {
|
|
79297
|
+
closeGeoSdtWrapper();
|
|
79298
|
+
}
|
|
79299
|
+
if (resolved && this.doc) {
|
|
79300
|
+
if (!geoSdtWrapper) {
|
|
79301
|
+
geoSdtWrapper = this.createInlineSdtWrapper(resolved.sdt);
|
|
79302
|
+
geoSdtId = thisRunSdtId;
|
|
79303
|
+
geoSdtWrapperLeft = elemLeftPx;
|
|
79304
|
+
geoSdtMaxRight = elemLeftPx;
|
|
79305
|
+
geoSdtWrapper.style.position = "absolute";
|
|
79306
|
+
geoSdtWrapper.style.left = `${elemLeftPx}px`;
|
|
79307
|
+
geoSdtWrapper.style.top = "0px";
|
|
79308
|
+
geoSdtWrapper.style.height = `${line.lineHeight}px`;
|
|
79309
|
+
}
|
|
79310
|
+
elem.style.left = `${elemLeftPx - geoSdtWrapperLeft}px`;
|
|
79311
|
+
geoSdtMaxRight = Math.max(geoSdtMaxRight, elemLeftPx + elemWidthPx);
|
|
79312
|
+
this.expandSdtWrapperPmRange(geoSdtWrapper, runForSdt.pmStart, runForSdt.pmEnd);
|
|
79313
|
+
geoSdtWrapper.appendChild(elem);
|
|
79314
|
+
} else {
|
|
79315
|
+
el.appendChild(elem);
|
|
79316
|
+
}
|
|
79317
|
+
};
|
|
78871
79318
|
for (let runIndex = line.fromRun; runIndex <= line.toRun; runIndex += 1) {
|
|
78872
79319
|
const baseRun = block.runs[runIndex];
|
|
78873
79320
|
if (!baseRun) continue;
|
|
@@ -78899,7 +79346,7 @@ ${o}
|
|
|
78899
79346
|
if (baseRun.pmStart != null) tabEl.dataset.pmStart = String(baseRun.pmStart);
|
|
78900
79347
|
if (baseRun.pmEnd != null) tabEl.dataset.pmEnd = String(baseRun.pmEnd);
|
|
78901
79348
|
tabEl.dataset.layoutEpoch = String(this.layoutEpoch);
|
|
78902
|
-
|
|
79349
|
+
appendToLineGeo(tabEl, baseRun, tabStartX + indentOffset, actualTabWidth);
|
|
78903
79350
|
cumulativeX = tabEndX;
|
|
78904
79351
|
continue;
|
|
78905
79352
|
}
|
|
@@ -78915,7 +79362,7 @@ ${o}
|
|
|
78915
79362
|
const segWidth = (runSegments2 && runSegments2[0]?.width !== void 0 ? runSegments2[0].width : elem.offsetWidth) ?? 0;
|
|
78916
79363
|
elem.style.position = "absolute";
|
|
78917
79364
|
elem.style.left = `${segX}px`;
|
|
78918
|
-
|
|
79365
|
+
appendToLineGeo(elem, baseRun, segX, segWidth);
|
|
78919
79366
|
cumulativeX = baseSegX + segWidth;
|
|
78920
79367
|
}
|
|
78921
79368
|
continue;
|
|
@@ -78938,7 +79385,7 @@ ${o}
|
|
|
78938
79385
|
const segWidth = (runSegments2 && runSegments2[0]?.width !== void 0 ? runSegments2[0].width : 0) ?? 0;
|
|
78939
79386
|
elem.style.position = "absolute";
|
|
78940
79387
|
elem.style.left = `${segX}px`;
|
|
78941
|
-
|
|
79388
|
+
appendToLineGeo(elem, baseRun, segX, segWidth);
|
|
78942
79389
|
cumulativeX = baseSegX + segWidth;
|
|
78943
79390
|
}
|
|
78944
79391
|
continue;
|
|
@@ -78973,7 +79420,7 @@ ${o}
|
|
|
78973
79420
|
const xPos = baseX + indentOffset;
|
|
78974
79421
|
elem.style.position = "absolute";
|
|
78975
79422
|
elem.style.left = `${xPos}px`;
|
|
78976
|
-
|
|
79423
|
+
appendToLineGeo(elem, segmentRun, xPos, segment.width ?? 0);
|
|
78977
79424
|
let width = segment.width ?? 0;
|
|
78978
79425
|
if (width <= 0 && this.doc) {
|
|
78979
79426
|
const measureEl = elem.cloneNode(true);
|
|
@@ -78985,9 +79432,13 @@ ${o}
|
|
|
78985
79432
|
this.doc.body.removeChild(measureEl);
|
|
78986
79433
|
}
|
|
78987
79434
|
cumulativeX = baseX + width;
|
|
79435
|
+
if (geoSdtWrapper) {
|
|
79436
|
+
geoSdtMaxRight = Math.max(geoSdtMaxRight, xPos + width);
|
|
79437
|
+
}
|
|
78988
79438
|
}
|
|
78989
79439
|
});
|
|
78990
79440
|
}
|
|
79441
|
+
closeGeoSdtWrapper();
|
|
78991
79442
|
} else {
|
|
78992
79443
|
let currentInlineSdtWrapper = null;
|
|
78993
79444
|
let currentInlineSdtId = null;
|
|
@@ -78999,12 +79450,12 @@ ${o}
|
|
|
78999
79450
|
}
|
|
79000
79451
|
};
|
|
79001
79452
|
runsForLine.forEach((run2) => {
|
|
79002
|
-
const
|
|
79003
|
-
const
|
|
79004
|
-
const runSdtId = isInlineSdt && runSdt?.id ? String(runSdt.id) : null;
|
|
79453
|
+
const resolved = this.resolveRunSdtId(run2);
|
|
79454
|
+
const runSdtId = resolved?.sdtId ?? null;
|
|
79005
79455
|
if (runSdtId !== currentInlineSdtId) {
|
|
79006
79456
|
closeCurrentWrapper();
|
|
79007
79457
|
}
|
|
79458
|
+
let elem = null;
|
|
79008
79459
|
if (run2.kind === "tab") {
|
|
79009
79460
|
const tabEl = this.doc.createElement("span");
|
|
79010
79461
|
tabEl.classList.add("superdoc-tab");
|
|
@@ -79025,39 +79476,20 @@ ${o}
|
|
|
79025
79476
|
if (run2.pmStart != null) tabEl.dataset.pmStart = String(run2.pmStart);
|
|
79026
79477
|
if (run2.pmEnd != null) tabEl.dataset.pmEnd = String(run2.pmEnd);
|
|
79027
79478
|
tabEl.dataset.layoutEpoch = String(this.layoutEpoch);
|
|
79028
|
-
|
|
79029
|
-
|
|
79479
|
+
elem = tabEl;
|
|
79480
|
+
} else {
|
|
79481
|
+
elem = this.renderRun(run2, context, trackedConfig);
|
|
79030
79482
|
}
|
|
79031
|
-
const elem = this.renderRun(run2, context, trackedConfig);
|
|
79032
79483
|
if (elem) {
|
|
79033
79484
|
if (styleId) {
|
|
79034
79485
|
elem.setAttribute("styleid", styleId);
|
|
79035
79486
|
}
|
|
79036
|
-
if (
|
|
79487
|
+
if (resolved && this.doc) {
|
|
79037
79488
|
if (!currentInlineSdtWrapper) {
|
|
79038
|
-
currentInlineSdtWrapper = this.
|
|
79039
|
-
currentInlineSdtWrapper.className = DOM_CLASS_NAMES.INLINE_SDT_WRAPPER;
|
|
79040
|
-
currentInlineSdtWrapper.dataset.layoutEpoch = String(this.layoutEpoch);
|
|
79489
|
+
currentInlineSdtWrapper = this.createInlineSdtWrapper(resolved.sdt);
|
|
79041
79490
|
currentInlineSdtId = runSdtId;
|
|
79042
|
-
this.applySdtDataset(currentInlineSdtWrapper, runSdt);
|
|
79043
|
-
const alias = runSdt?.alias || "Inline content";
|
|
79044
|
-
const labelEl = this.doc.createElement("span");
|
|
79045
|
-
labelEl.className = `${DOM_CLASS_NAMES.INLINE_SDT_WRAPPER}__label`;
|
|
79046
|
-
labelEl.textContent = alias;
|
|
79047
|
-
currentInlineSdtWrapper.appendChild(labelEl);
|
|
79048
|
-
}
|
|
79049
|
-
const wrapperPmStart = currentInlineSdtWrapper.dataset.pmStart;
|
|
79050
|
-
const wrapperPmEnd = currentInlineSdtWrapper.dataset.pmEnd;
|
|
79051
|
-
if (run2.pmStart != null) {
|
|
79052
|
-
if (!wrapperPmStart || run2.pmStart < parseInt(wrapperPmStart, 10)) {
|
|
79053
|
-
currentInlineSdtWrapper.dataset.pmStart = String(run2.pmStart);
|
|
79054
|
-
}
|
|
79055
|
-
}
|
|
79056
|
-
if (run2.pmEnd != null) {
|
|
79057
|
-
if (!wrapperPmEnd || run2.pmEnd > parseInt(wrapperPmEnd, 10)) {
|
|
79058
|
-
currentInlineSdtWrapper.dataset.pmEnd = String(run2.pmEnd);
|
|
79059
|
-
}
|
|
79060
79491
|
}
|
|
79492
|
+
this.expandSdtWrapperPmRange(currentInlineSdtWrapper, run2.pmStart, run2.pmEnd);
|
|
79061
79493
|
currentInlineSdtWrapper.appendChild(elem);
|
|
79062
79494
|
} else {
|
|
79063
79495
|
el.appendChild(elem);
|
|
@@ -79234,6 +79666,7 @@ ${o}
|
|
|
79234
79666
|
"sdtScope",
|
|
79235
79667
|
"sdtTag",
|
|
79236
79668
|
"sdtAlias",
|
|
79669
|
+
"lockMode",
|
|
79237
79670
|
"sdtSectionTitle",
|
|
79238
79671
|
"sdtSectionType",
|
|
79239
79672
|
"sdtSectionLocked",
|
|
@@ -79258,6 +79691,49 @@ ${o}
|
|
|
79258
79691
|
el.dataset[key2] = String(value);
|
|
79259
79692
|
}
|
|
79260
79693
|
}
|
|
79694
|
+
/**
|
|
79695
|
+
* Resolve the inline SDT id from a run, or null if the run is not inside an inline SDT.
|
|
79696
|
+
*/
|
|
79697
|
+
resolveRunSdtId(run2) {
|
|
79698
|
+
const sdt = run2.sdt;
|
|
79699
|
+
if (sdt?.type === "structuredContent" && sdt?.scope === "inline" && sdt?.id) {
|
|
79700
|
+
return { sdtId: String(sdt.id), sdt };
|
|
79701
|
+
}
|
|
79702
|
+
return null;
|
|
79703
|
+
}
|
|
79704
|
+
/**
|
|
79705
|
+
* Create an inline SDT wrapper `<span>` with className, layoutEpoch, dataset, and label.
|
|
79706
|
+
* Shared by both the geometry and run-based rendering paths.
|
|
79707
|
+
*/
|
|
79708
|
+
createInlineSdtWrapper(sdt) {
|
|
79709
|
+
const wrapper = this.doc.createElement("span");
|
|
79710
|
+
wrapper.className = DOM_CLASS_NAMES.INLINE_SDT_WRAPPER;
|
|
79711
|
+
wrapper.dataset.layoutEpoch = String(this.layoutEpoch);
|
|
79712
|
+
this.applySdtDataset(wrapper, sdt);
|
|
79713
|
+
const alias = sdt?.alias || "Inline content";
|
|
79714
|
+
const labelEl = this.doc.createElement("span");
|
|
79715
|
+
labelEl.className = `${DOM_CLASS_NAMES.INLINE_SDT_WRAPPER}__label`;
|
|
79716
|
+
labelEl.textContent = alias;
|
|
79717
|
+
wrapper.appendChild(labelEl);
|
|
79718
|
+
return wrapper;
|
|
79719
|
+
}
|
|
79720
|
+
/**
|
|
79721
|
+
* Expand the PM position range tracked on an SDT wrapper to include a new run's range.
|
|
79722
|
+
*/
|
|
79723
|
+
expandSdtWrapperPmRange(wrapper, pmStart, pmEnd) {
|
|
79724
|
+
if (pmStart != null) {
|
|
79725
|
+
const cur = wrapper.dataset.pmStart;
|
|
79726
|
+
if (!cur || pmStart < parseInt(cur, 10)) {
|
|
79727
|
+
wrapper.dataset.pmStart = String(pmStart);
|
|
79728
|
+
}
|
|
79729
|
+
}
|
|
79730
|
+
if (pmEnd != null) {
|
|
79731
|
+
const cur = wrapper.dataset.pmEnd;
|
|
79732
|
+
if (!cur || pmEnd > parseInt(cur, 10)) {
|
|
79733
|
+
wrapper.dataset.pmEnd = String(pmEnd);
|
|
79734
|
+
}
|
|
79735
|
+
}
|
|
79736
|
+
}
|
|
79261
79737
|
/**
|
|
79262
79738
|
* Applies SDT (Structured Document Tag) metadata to an element's dataset as data-sdt-* attributes.
|
|
79263
79739
|
* Supports field annotations, structured content, document sections, and doc parts.
|
|
@@ -79285,6 +79761,7 @@ ${o}
|
|
|
79285
79761
|
this.setDatasetString(el, "sdtScope", metadata.scope);
|
|
79286
79762
|
this.setDatasetString(el, "sdtTag", metadata.tag);
|
|
79287
79763
|
this.setDatasetString(el, "sdtAlias", metadata.alias);
|
|
79764
|
+
this.setDatasetString(el, "lockMode", metadata.lockMode || "unlocked");
|
|
79288
79765
|
} else if (metadata.type === "documentSection") {
|
|
79289
79766
|
this.setDatasetString(el, "sdtSectionTitle", metadata.title);
|
|
79290
79767
|
this.setDatasetString(el, "sdtSectionType", metadata.sectionType);
|
|
@@ -79373,17 +79850,6 @@ ${o}
|
|
|
79373
79850
|
}
|
|
79374
79851
|
return boundaries;
|
|
79375
79852
|
};
|
|
79376
|
-
const shouldRebuildForSdtBoundary = (element2, boundary) => {
|
|
79377
|
-
if (!boundary) return false;
|
|
79378
|
-
const startAttr = element2.dataset.sdtContainerStart;
|
|
79379
|
-
const endAttr = element2.dataset.sdtContainerEnd;
|
|
79380
|
-
const expectedStart = String(boundary.isStart ?? true);
|
|
79381
|
-
const expectedEnd = String(boundary.isEnd ?? true);
|
|
79382
|
-
if (startAttr === void 0 || endAttr === void 0) {
|
|
79383
|
-
return true;
|
|
79384
|
-
}
|
|
79385
|
-
return startAttr !== expectedStart || endAttr !== expectedEnd;
|
|
79386
|
-
};
|
|
79387
79853
|
const fragmentKey = (fragment) => {
|
|
79388
79854
|
if (fragment.kind === "para") {
|
|
79389
79855
|
return `para:${fragment.blockId}:${fragment.fromLine}:${fragment.toLine}`;
|
|
@@ -88779,6 +89245,7 @@ ${o}
|
|
|
88779
89245
|
id: toNullableString(attrs.id),
|
|
88780
89246
|
tag: toOptionalString(attrs.tag),
|
|
88781
89247
|
alias: toOptionalString(attrs.alias),
|
|
89248
|
+
lockMode: attrs.lockMode,
|
|
88782
89249
|
sdtPr: attrs.sdtPr
|
|
88783
89250
|
};
|
|
88784
89251
|
}
|
|
@@ -89603,7 +90070,8 @@ ${o}
|
|
|
89603
90070
|
positions,
|
|
89604
90071
|
tabOrdinal,
|
|
89605
90072
|
paragraphAttrs,
|
|
89606
|
-
inheritedMarks
|
|
90073
|
+
inheritedMarks,
|
|
90074
|
+
sdtMetadata
|
|
89607
90075
|
}) {
|
|
89608
90076
|
const pos = positions.get(node2);
|
|
89609
90077
|
if (!pos) return null;
|
|
@@ -89619,6 +90087,9 @@ ${o}
|
|
|
89619
90087
|
indent: indent2,
|
|
89620
90088
|
leader: node2.attrs?.leader ?? null
|
|
89621
90089
|
};
|
|
90090
|
+
if (sdtMetadata) {
|
|
90091
|
+
run2.sdt = sdtMetadata;
|
|
90092
|
+
}
|
|
89622
90093
|
const marks = [...node2.marks ?? [], ...inheritedMarks ?? []];
|
|
89623
90094
|
if (marks.length > 0) {
|
|
89624
90095
|
applyMarksToRun(run2, marks);
|
|
@@ -112184,7 +112655,8 @@ ${o}
|
|
|
112184
112655
|
}
|
|
112185
112656
|
const activeEditor = this.getActiveEditor();
|
|
112186
112657
|
const hasFocus = activeEditor?.view?.hasFocus?.() ?? false;
|
|
112187
|
-
|
|
112658
|
+
const slashMenuOpen = activeEditor?.state ? !!SlashMenuPluginKey.getState(activeEditor.state)?.open : false;
|
|
112659
|
+
if (!hasFocus && !slashMenuOpen) {
|
|
112188
112660
|
try {
|
|
112189
112661
|
this.#clearSelectedFieldAnnotationClass();
|
|
112190
112662
|
this.#localSelectionLayer.innerHTML = "";
|
|
@@ -114406,300 +114878,6 @@ ${o}
|
|
|
114406
114878
|
});
|
|
114407
114879
|
return { decorations };
|
|
114408
114880
|
};
|
|
114409
|
-
function getEditorSurfaceElement(editor) {
|
|
114410
|
-
if (!editor) return null;
|
|
114411
|
-
if (typeof editor.hitTest === "function" && editor.element instanceof HTMLElement) {
|
|
114412
|
-
return editor.element;
|
|
114413
|
-
}
|
|
114414
|
-
return editor.presentationEditor?.element ?? editor.view?.dom ?? editor.options?.element ?? null;
|
|
114415
|
-
}
|
|
114416
|
-
function getSurfaceRelativePoint(editor, eventLocation = {}) {
|
|
114417
|
-
const surface = getEditorSurfaceElement(editor);
|
|
114418
|
-
if (!surface) return null;
|
|
114419
|
-
const rect = surface.getBoundingClientRect();
|
|
114420
|
-
let left2;
|
|
114421
|
-
let top2;
|
|
114422
|
-
if (typeof eventLocation.clientX === "number" && typeof eventLocation.clientY === "number") {
|
|
114423
|
-
left2 = eventLocation.clientX - rect.left;
|
|
114424
|
-
top2 = eventLocation.clientY - rect.top;
|
|
114425
|
-
} else if (editor?.state?.selection) {
|
|
114426
|
-
const selectionFrom = editor.state.selection.from;
|
|
114427
|
-
const coords = editor.coordsAtPos?.(selectionFrom);
|
|
114428
|
-
if (coords) {
|
|
114429
|
-
left2 = coords.left - rect.left;
|
|
114430
|
-
top2 = coords.top - rect.top;
|
|
114431
|
-
}
|
|
114432
|
-
}
|
|
114433
|
-
if (!Number.isFinite(left2) || !Number.isFinite(top2)) {
|
|
114434
|
-
return null;
|
|
114435
|
-
}
|
|
114436
|
-
return { left: left2, top: top2 };
|
|
114437
|
-
}
|
|
114438
|
-
function findContainingBlockAncestor(element2) {
|
|
114439
|
-
if (!element2) return null;
|
|
114440
|
-
let current = element2.parentElement;
|
|
114441
|
-
while (current && current !== document.body && current !== document.documentElement) {
|
|
114442
|
-
try {
|
|
114443
|
-
const style2 = window.getComputedStyle(current);
|
|
114444
|
-
const transform = style2.transform;
|
|
114445
|
-
const filter = style2.filter;
|
|
114446
|
-
const backdropFilter = style2.backdropFilter || style2.webkitBackdropFilter;
|
|
114447
|
-
const perspective = style2.perspective;
|
|
114448
|
-
const willChange = style2.willChange;
|
|
114449
|
-
const contain = style2.contain;
|
|
114450
|
-
if (transform && transform !== "none") {
|
|
114451
|
-
return current;
|
|
114452
|
-
}
|
|
114453
|
-
if (filter && filter !== "none") {
|
|
114454
|
-
return current;
|
|
114455
|
-
}
|
|
114456
|
-
if (backdropFilter && backdropFilter !== "none") {
|
|
114457
|
-
return current;
|
|
114458
|
-
}
|
|
114459
|
-
if (perspective && perspective !== "none") {
|
|
114460
|
-
return current;
|
|
114461
|
-
}
|
|
114462
|
-
if (willChange && willChange !== "auto") {
|
|
114463
|
-
const values = willChange.split(",").map((v2) => v2.trim());
|
|
114464
|
-
if (values.includes("transform") || values.includes("perspective")) {
|
|
114465
|
-
return current;
|
|
114466
|
-
}
|
|
114467
|
-
}
|
|
114468
|
-
if (contain && /paint|layout|strict|content/.test(contain)) {
|
|
114469
|
-
return current;
|
|
114470
|
-
}
|
|
114471
|
-
} catch (error) {
|
|
114472
|
-
console.warn("SlashMenu: Failed to get computed style for element", current, error);
|
|
114473
|
-
}
|
|
114474
|
-
current = current.parentElement;
|
|
114475
|
-
}
|
|
114476
|
-
return null;
|
|
114477
|
-
}
|
|
114478
|
-
const SlashMenuPluginKey = new PluginKey("slashMenu");
|
|
114479
|
-
const MENU_OFFSET_X = 100;
|
|
114480
|
-
const MENU_OFFSET_Y = 28;
|
|
114481
|
-
const CONTEXT_MENU_OFFSET_X = 10;
|
|
114482
|
-
const CONTEXT_MENU_OFFSET_Y = 10;
|
|
114483
|
-
const SLASH_COOLDOWN_MS = 5e3;
|
|
114484
|
-
const SlashMenu = Extension.create({
|
|
114485
|
-
name: "slashMenu",
|
|
114486
|
-
/**
|
|
114487
|
-
* Initialize default options for the SlashMenu extension
|
|
114488
|
-
* @returns {SlashMenuOptions} Empty options object (configuration is inherited from editor options)
|
|
114489
|
-
*/
|
|
114490
|
-
addOptions() {
|
|
114491
|
-
return {};
|
|
114492
|
-
},
|
|
114493
|
-
addPmPlugins() {
|
|
114494
|
-
const editor = this.editor;
|
|
114495
|
-
if (editor.options?.isHeadless) {
|
|
114496
|
-
return [];
|
|
114497
|
-
}
|
|
114498
|
-
let slashCooldown = false;
|
|
114499
|
-
let slashCooldownTimeout = null;
|
|
114500
|
-
const isMenuDisabled = () => Boolean(editor.options?.disableContextMenu);
|
|
114501
|
-
const ensureStateShape = (value = {}) => ({
|
|
114502
|
-
open: false,
|
|
114503
|
-
selected: null,
|
|
114504
|
-
anchorPos: null,
|
|
114505
|
-
menuPosition: null,
|
|
114506
|
-
disabled: isMenuDisabled(),
|
|
114507
|
-
...value
|
|
114508
|
-
});
|
|
114509
|
-
const slashMenuPlugin = new Plugin({
|
|
114510
|
-
key: SlashMenuPluginKey,
|
|
114511
|
-
state: {
|
|
114512
|
-
init: () => ensureStateShape(),
|
|
114513
|
-
/**
|
|
114514
|
-
* Apply transaction to update plugin state
|
|
114515
|
-
* Handles state transitions based on transaction metadata:
|
|
114516
|
-
* - 'open': Opens menu at specified position or cursor location
|
|
114517
|
-
* - 'select': Updates the selected menu item
|
|
114518
|
-
* - 'close': Closes the menu and clears anchor position
|
|
114519
|
-
* - 'updatePosition': Triggers menu position recalculation (no-op in apply)
|
|
114520
|
-
*
|
|
114521
|
-
* @param {import('prosemirror-state').Transaction} tr - The transaction
|
|
114522
|
-
* @param {SlashMenuState} value - Previous plugin state
|
|
114523
|
-
* @returns {SlashMenuState} New plugin state
|
|
114524
|
-
*/
|
|
114525
|
-
apply(tr, value) {
|
|
114526
|
-
const meta2 = tr.getMeta(SlashMenuPluginKey);
|
|
114527
|
-
const disabled = isMenuDisabled();
|
|
114528
|
-
if (disabled) {
|
|
114529
|
-
if (value.open) {
|
|
114530
|
-
editor.emit("slashMenu:close");
|
|
114531
|
-
}
|
|
114532
|
-
return ensureStateShape({ disabled: true });
|
|
114533
|
-
}
|
|
114534
|
-
if (!meta2) {
|
|
114535
|
-
if (value.disabled !== disabled) {
|
|
114536
|
-
return ensureStateShape({ ...value, disabled });
|
|
114537
|
-
}
|
|
114538
|
-
return value;
|
|
114539
|
-
}
|
|
114540
|
-
switch (meta2.type) {
|
|
114541
|
-
case "open": {
|
|
114542
|
-
if (typeof meta2.pos !== "number" || meta2.pos < 0 || meta2.pos > tr.doc.content.size) {
|
|
114543
|
-
console.warn("SlashMenu: Invalid position", meta2.pos);
|
|
114544
|
-
return ensureStateShape(value);
|
|
114545
|
-
}
|
|
114546
|
-
let left2 = 0;
|
|
114547
|
-
let top2 = 0;
|
|
114548
|
-
let isContextMenu = false;
|
|
114549
|
-
if (typeof meta2.clientX === "number" && typeof meta2.clientY === "number") {
|
|
114550
|
-
left2 = meta2.clientX;
|
|
114551
|
-
top2 = meta2.clientY;
|
|
114552
|
-
isContextMenu = true;
|
|
114553
|
-
} else {
|
|
114554
|
-
const relativePoint = getSurfaceRelativePoint(editor, meta2);
|
|
114555
|
-
if (relativePoint) {
|
|
114556
|
-
const surface = editor.presentationEditor?.element ?? editor.view?.dom ?? editor.options?.element;
|
|
114557
|
-
if (surface) {
|
|
114558
|
-
try {
|
|
114559
|
-
const rect = surface.getBoundingClientRect();
|
|
114560
|
-
left2 = rect.left + relativePoint.left;
|
|
114561
|
-
top2 = rect.top + relativePoint.top;
|
|
114562
|
-
} catch (error) {
|
|
114563
|
-
console.warn("SlashMenu: Failed to get surface bounds", error);
|
|
114564
|
-
return ensureStateShape(value);
|
|
114565
|
-
}
|
|
114566
|
-
}
|
|
114567
|
-
}
|
|
114568
|
-
}
|
|
114569
|
-
const menuSurface = editor.presentationEditor?.element ?? editor.view?.dom ?? editor.options?.element;
|
|
114570
|
-
const containingBlock = findContainingBlockAncestor(menuSurface);
|
|
114571
|
-
if (containingBlock) {
|
|
114572
|
-
try {
|
|
114573
|
-
const cbRect = containingBlock.getBoundingClientRect();
|
|
114574
|
-
left2 -= cbRect.left;
|
|
114575
|
-
top2 -= cbRect.top;
|
|
114576
|
-
left2 += containingBlock.scrollLeft || 0;
|
|
114577
|
-
top2 += containingBlock.scrollTop || 0;
|
|
114578
|
-
} catch (error) {
|
|
114579
|
-
console.warn("SlashMenu: Failed to adjust for containing block", error);
|
|
114580
|
-
}
|
|
114581
|
-
}
|
|
114582
|
-
const offsetX = isContextMenu ? CONTEXT_MENU_OFFSET_X : MENU_OFFSET_X;
|
|
114583
|
-
const offsetY = isContextMenu ? CONTEXT_MENU_OFFSET_Y : MENU_OFFSET_Y;
|
|
114584
|
-
const menuPosition = {
|
|
114585
|
-
left: `${left2 + offsetX}px`,
|
|
114586
|
-
top: `${top2 + offsetY}px`
|
|
114587
|
-
};
|
|
114588
|
-
const newState = {
|
|
114589
|
-
...value,
|
|
114590
|
-
open: true,
|
|
114591
|
-
anchorPos: meta2.pos,
|
|
114592
|
-
menuPosition
|
|
114593
|
-
};
|
|
114594
|
-
editor.emit("slashMenu:open", { menuPosition });
|
|
114595
|
-
return ensureStateShape(newState);
|
|
114596
|
-
}
|
|
114597
|
-
case "select": {
|
|
114598
|
-
return ensureStateShape({ ...value, selected: meta2.id });
|
|
114599
|
-
}
|
|
114600
|
-
case "close": {
|
|
114601
|
-
editor.emit("slashMenu:close");
|
|
114602
|
-
return ensureStateShape({ ...value, open: false, anchorPos: null });
|
|
114603
|
-
}
|
|
114604
|
-
default:
|
|
114605
|
-
return ensureStateShape({ ...value, disabled });
|
|
114606
|
-
}
|
|
114607
|
-
}
|
|
114608
|
-
},
|
|
114609
|
-
/**
|
|
114610
|
-
* Create view plugin to handle window event listeners
|
|
114611
|
-
* @param {import('prosemirror-view').EditorView} editorView - The ProseMirror editor view
|
|
114612
|
-
* @returns {Object} View plugin with destroy method
|
|
114613
|
-
*/
|
|
114614
|
-
view(editorView) {
|
|
114615
|
-
const updatePosition2 = () => {
|
|
114616
|
-
if (isMenuDisabled()) return;
|
|
114617
|
-
const state = SlashMenuPluginKey.getState(editorView.state);
|
|
114618
|
-
if (state.open) {
|
|
114619
|
-
editorView.dispatch(
|
|
114620
|
-
editorView.state.tr.setMeta(SlashMenuPluginKey, {
|
|
114621
|
-
type: "updatePosition"
|
|
114622
|
-
})
|
|
114623
|
-
);
|
|
114624
|
-
}
|
|
114625
|
-
};
|
|
114626
|
-
window.addEventListener("scroll", updatePosition2, true);
|
|
114627
|
-
window.addEventListener("resize", updatePosition2);
|
|
114628
|
-
return {
|
|
114629
|
-
destroy() {
|
|
114630
|
-
window.removeEventListener("scroll", updatePosition2, true);
|
|
114631
|
-
window.removeEventListener("resize", updatePosition2);
|
|
114632
|
-
if (slashCooldownTimeout) {
|
|
114633
|
-
clearTimeout(slashCooldownTimeout);
|
|
114634
|
-
slashCooldownTimeout = null;
|
|
114635
|
-
}
|
|
114636
|
-
}
|
|
114637
|
-
};
|
|
114638
|
-
},
|
|
114639
|
-
props: {
|
|
114640
|
-
/**
|
|
114641
|
-
* Handle keyboard events to open/close the slash menu
|
|
114642
|
-
* - '/': Opens menu at cursor if conditions are met (in paragraph, after space/start)
|
|
114643
|
-
* - 'Escape' or 'ArrowLeft': Closes menu and restores cursor position
|
|
114644
|
-
*
|
|
114645
|
-
* @param {import('prosemirror-view').EditorView} view - The ProseMirror editor view
|
|
114646
|
-
* @param {KeyboardEvent} event - The keyboard event
|
|
114647
|
-
* @returns {boolean} True if the event was handled, false otherwise
|
|
114648
|
-
*/
|
|
114649
|
-
handleKeyDown(view, event) {
|
|
114650
|
-
if (isMenuDisabled()) {
|
|
114651
|
-
return false;
|
|
114652
|
-
}
|
|
114653
|
-
const pluginState = this.getState(view.state);
|
|
114654
|
-
if (event.key === "/" && slashCooldown) {
|
|
114655
|
-
return false;
|
|
114656
|
-
}
|
|
114657
|
-
if (event.key === "/" && !pluginState.open) {
|
|
114658
|
-
const { $cursor } = view.state.selection;
|
|
114659
|
-
if (!$cursor) return false;
|
|
114660
|
-
const isParagraph = $cursor.parent.type.name === "paragraph";
|
|
114661
|
-
if (!isParagraph) return false;
|
|
114662
|
-
const textBefore = $cursor.parent.textContent.slice(0, $cursor.parentOffset);
|
|
114663
|
-
const isEmptyOrAfterSpace = !textBefore || textBefore.endsWith(" ");
|
|
114664
|
-
if (!isEmptyOrAfterSpace) return false;
|
|
114665
|
-
event.preventDefault();
|
|
114666
|
-
slashCooldown = true;
|
|
114667
|
-
if (slashCooldownTimeout) clearTimeout(slashCooldownTimeout);
|
|
114668
|
-
slashCooldownTimeout = setTimeout(() => {
|
|
114669
|
-
slashCooldown = false;
|
|
114670
|
-
slashCooldownTimeout = null;
|
|
114671
|
-
}, SLASH_COOLDOWN_MS);
|
|
114672
|
-
view.dispatch(
|
|
114673
|
-
view.state.tr.setMeta(SlashMenuPluginKey, {
|
|
114674
|
-
type: "open",
|
|
114675
|
-
pos: $cursor.pos
|
|
114676
|
-
})
|
|
114677
|
-
);
|
|
114678
|
-
return true;
|
|
114679
|
-
}
|
|
114680
|
-
if (pluginState.open && (event.key === "Escape" || event.key === "ArrowLeft")) {
|
|
114681
|
-
const { anchorPos } = pluginState;
|
|
114682
|
-
view.dispatch(
|
|
114683
|
-
view.state.tr.setMeta(SlashMenuPluginKey, {
|
|
114684
|
-
type: "close"
|
|
114685
|
-
})
|
|
114686
|
-
);
|
|
114687
|
-
if (anchorPos !== null) {
|
|
114688
|
-
const tr = view.state.tr.setSelection(
|
|
114689
|
-
view.state.selection.constructor.near(view.state.doc.resolve(anchorPos))
|
|
114690
|
-
);
|
|
114691
|
-
view.dispatch(tr);
|
|
114692
|
-
view.focus();
|
|
114693
|
-
}
|
|
114694
|
-
return true;
|
|
114695
|
-
}
|
|
114696
|
-
return false;
|
|
114697
|
-
}
|
|
114698
|
-
}
|
|
114699
|
-
});
|
|
114700
|
-
return [slashMenuPlugin];
|
|
114701
|
-
}
|
|
114702
|
-
});
|
|
114703
114881
|
class StructuredContentViewBase {
|
|
114704
114882
|
node;
|
|
114705
114883
|
view;
|
|
@@ -114839,6 +115017,20 @@ ${o}
|
|
|
114839
115017
|
dragHandle.append(textElement);
|
|
114840
115018
|
return dragHandle;
|
|
114841
115019
|
}
|
|
115020
|
+
isContentLocked() {
|
|
115021
|
+
const lockMode = this.node.attrs.lockMode;
|
|
115022
|
+
return lockMode === "contentLocked" || lockMode === "sdtContentLocked";
|
|
115023
|
+
}
|
|
115024
|
+
isSdtLocked() {
|
|
115025
|
+
const lockMode = this.node.attrs.lockMode;
|
|
115026
|
+
return lockMode === "sdtLocked" || lockMode === "sdtContentLocked";
|
|
115027
|
+
}
|
|
115028
|
+
updateContentEditability() {
|
|
115029
|
+
if (this.dom) {
|
|
115030
|
+
this.dom.classList.toggle("sd-structured-content--content-locked", this.isContentLocked());
|
|
115031
|
+
this.dom.classList.toggle("sd-structured-content--sdt-locked", this.isSdtLocked());
|
|
115032
|
+
}
|
|
115033
|
+
}
|
|
114842
115034
|
onDragStart(event) {
|
|
114843
115035
|
const { view } = this.editor;
|
|
114844
115036
|
const target = event.target;
|
|
@@ -114894,10 +115086,12 @@ ${o}
|
|
|
114894
115086
|
element2.prepend(dragHandle);
|
|
114895
115087
|
element2.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
114896
115088
|
this.root = element2;
|
|
115089
|
+
this.updateContentEditability();
|
|
114897
115090
|
}
|
|
114898
115091
|
updateView() {
|
|
114899
115092
|
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
114900
115093
|
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
115094
|
+
this.updateContentEditability();
|
|
114901
115095
|
}
|
|
114902
115096
|
update(node2, decorations, innerDecorations) {
|
|
114903
115097
|
const result = super.update(node2, decorations, innerDecorations);
|
|
@@ -114906,6 +115100,157 @@ ${o}
|
|
|
114906
115100
|
return true;
|
|
114907
115101
|
}
|
|
114908
115102
|
}
|
|
115103
|
+
const STRUCTURED_CONTENT_LOCK_KEY = new PluginKey("structuredContentLock");
|
|
115104
|
+
function collectSDTNodes(doc2) {
|
|
115105
|
+
const sdtNodes = [];
|
|
115106
|
+
doc2.descendants((node2, pos) => {
|
|
115107
|
+
if (node2.type.name === "structuredContent" || node2.type.name === "structuredContentBlock") {
|
|
115108
|
+
sdtNodes.push({
|
|
115109
|
+
type: node2.type.name,
|
|
115110
|
+
lockMode: node2.attrs.lockMode,
|
|
115111
|
+
pos,
|
|
115112
|
+
end: pos + node2.nodeSize
|
|
115113
|
+
});
|
|
115114
|
+
}
|
|
115115
|
+
});
|
|
115116
|
+
return sdtNodes;
|
|
115117
|
+
}
|
|
115118
|
+
function checkLockViolation(sdtNodes, from2, to) {
|
|
115119
|
+
for (const sdt of sdtNodes) {
|
|
115120
|
+
const overlaps = from2 < sdt.end && to > sdt.pos;
|
|
115121
|
+
if (!overlaps) continue;
|
|
115122
|
+
const containsSDT = from2 <= sdt.pos && to >= sdt.end;
|
|
115123
|
+
const insideSDT = from2 >= sdt.pos && to <= sdt.end;
|
|
115124
|
+
const crossesStart = from2 < sdt.pos && to > sdt.pos && to < sdt.end;
|
|
115125
|
+
const crossesEnd = from2 > sdt.pos && from2 < sdt.end && to > sdt.end;
|
|
115126
|
+
const wouldDamageWrapper = containsSDT || crossesStart || crossesEnd;
|
|
115127
|
+
const wouldModifyContent = insideSDT && !containsSDT;
|
|
115128
|
+
const isSdtLocked = sdt.lockMode === "sdtLocked" || sdt.lockMode === "sdtContentLocked";
|
|
115129
|
+
const isContentLocked = sdt.lockMode === "contentLocked" || sdt.lockMode === "sdtContentLocked";
|
|
115130
|
+
if (isSdtLocked && wouldDamageWrapper) {
|
|
115131
|
+
return { blocked: true, reason: `Cannot delete SDT wrapper (${sdt.lockMode})` };
|
|
115132
|
+
}
|
|
115133
|
+
if (isContentLocked && wouldModifyContent) {
|
|
115134
|
+
return { blocked: true, reason: `Cannot modify content (${sdt.lockMode})` };
|
|
115135
|
+
}
|
|
115136
|
+
}
|
|
115137
|
+
return { blocked: false };
|
|
115138
|
+
}
|
|
115139
|
+
function createStructuredContentLockPlugin() {
|
|
115140
|
+
return new Plugin({
|
|
115141
|
+
key: STRUCTURED_CONTENT_LOCK_KEY,
|
|
115142
|
+
state: {
|
|
115143
|
+
init(_2, editorState) {
|
|
115144
|
+
return collectSDTNodes(editorState.doc);
|
|
115145
|
+
},
|
|
115146
|
+
apply(tr, cachedSDTNodes, _oldState, newState) {
|
|
115147
|
+
if (!tr.docChanged) return cachedSDTNodes;
|
|
115148
|
+
return collectSDTNodes(newState.doc);
|
|
115149
|
+
}
|
|
115150
|
+
},
|
|
115151
|
+
props: {
|
|
115152
|
+
/**
|
|
115153
|
+
* Intercept key events BEFORE any transaction is created.
|
|
115154
|
+
* This prevents the browser selection from getting out of sync.
|
|
115155
|
+
*/
|
|
115156
|
+
handleKeyDown(view, event) {
|
|
115157
|
+
const { state } = view;
|
|
115158
|
+
const { selection } = state;
|
|
115159
|
+
const { from: from2, to } = selection;
|
|
115160
|
+
const isDelete = event.key === "Delete";
|
|
115161
|
+
const isBackspace = event.key === "Backspace";
|
|
115162
|
+
const isCut = (event.metaKey || event.ctrlKey) && event.key === "x";
|
|
115163
|
+
if (!isDelete && !isBackspace && !isCut) {
|
|
115164
|
+
return false;
|
|
115165
|
+
}
|
|
115166
|
+
const sdtNodes = STRUCTURED_CONTENT_LOCK_KEY.getState(state);
|
|
115167
|
+
if (sdtNodes.length === 0) {
|
|
115168
|
+
return false;
|
|
115169
|
+
}
|
|
115170
|
+
let affectedFrom = from2;
|
|
115171
|
+
let affectedTo = to;
|
|
115172
|
+
if (from2 === to) {
|
|
115173
|
+
if (isBackspace && from2 > 0) {
|
|
115174
|
+
affectedFrom = from2 - 1;
|
|
115175
|
+
} else if (isDelete && to < state.doc.content.size) {
|
|
115176
|
+
affectedTo = to + 1;
|
|
115177
|
+
}
|
|
115178
|
+
}
|
|
115179
|
+
const result = checkLockViolation(sdtNodes, affectedFrom, affectedTo);
|
|
115180
|
+
if (result.blocked) {
|
|
115181
|
+
event.preventDefault();
|
|
115182
|
+
return true;
|
|
115183
|
+
}
|
|
115184
|
+
return false;
|
|
115185
|
+
},
|
|
115186
|
+
/**
|
|
115187
|
+
* Handle text input (typing) for content-locked nodes
|
|
115188
|
+
*/
|
|
115189
|
+
handleTextInput(view, from2, to, _text) {
|
|
115190
|
+
const sdtNodes = STRUCTURED_CONTENT_LOCK_KEY.getState(view.state);
|
|
115191
|
+
if (sdtNodes.length === 0) {
|
|
115192
|
+
return false;
|
|
115193
|
+
}
|
|
115194
|
+
const result = checkLockViolation(sdtNodes, from2, to);
|
|
115195
|
+
if (result.blocked) {
|
|
115196
|
+
return true;
|
|
115197
|
+
}
|
|
115198
|
+
return false;
|
|
115199
|
+
}
|
|
115200
|
+
},
|
|
115201
|
+
/**
|
|
115202
|
+
* Safety net: filter transactions that slip through
|
|
115203
|
+
* (e.g., programmatic changes, paste, drag-drop)
|
|
115204
|
+
*/
|
|
115205
|
+
filterTransaction(tr, state) {
|
|
115206
|
+
if (!tr.docChanged) {
|
|
115207
|
+
return true;
|
|
115208
|
+
}
|
|
115209
|
+
const sdtNodes = STRUCTURED_CONTENT_LOCK_KEY.getState(state);
|
|
115210
|
+
if (sdtNodes.length === 0) {
|
|
115211
|
+
return true;
|
|
115212
|
+
}
|
|
115213
|
+
for (const step of tr.steps) {
|
|
115214
|
+
if (step.from === void 0 || step.to === void 0) {
|
|
115215
|
+
continue;
|
|
115216
|
+
}
|
|
115217
|
+
const result = checkLockViolation(sdtNodes, step.from, step.to);
|
|
115218
|
+
if (result.blocked) {
|
|
115219
|
+
return false;
|
|
115220
|
+
}
|
|
115221
|
+
}
|
|
115222
|
+
return true;
|
|
115223
|
+
}
|
|
115224
|
+
});
|
|
115225
|
+
}
|
|
115226
|
+
function createStructuredContentSelectPlugin() {
|
|
115227
|
+
return new Plugin({
|
|
115228
|
+
appendTransaction(transactions, oldState, newState) {
|
|
115229
|
+
const { selection } = newState;
|
|
115230
|
+
if (!selection.empty) return null;
|
|
115231
|
+
if (oldState.selection.eq(newState.selection)) return null;
|
|
115232
|
+
if (transactions.some((tr) => tr.docChanged)) return null;
|
|
115233
|
+
const $pos = selection.$from;
|
|
115234
|
+
for (let d2 = $pos.depth; d2 > 0; d2--) {
|
|
115235
|
+
const node2 = $pos.node(d2);
|
|
115236
|
+
if (node2.type.name === "structuredContent") {
|
|
115237
|
+
const sdtStart = $pos.before(d2);
|
|
115238
|
+
const contentFrom = $pos.start(d2);
|
|
115239
|
+
const contentTo = $pos.end(d2);
|
|
115240
|
+
if (contentFrom === contentTo) return null;
|
|
115241
|
+
const old$pos = oldState.selection.$from;
|
|
115242
|
+
for (let od = old$pos.depth; od > 0; od--) {
|
|
115243
|
+
if (old$pos.node(od).type.name === "structuredContent" && old$pos.before(od) === sdtStart) {
|
|
115244
|
+
return null;
|
|
115245
|
+
}
|
|
115246
|
+
}
|
|
115247
|
+
return newState.tr.setSelection(TextSelection$1.create(newState.doc, contentFrom, contentTo));
|
|
115248
|
+
}
|
|
115249
|
+
}
|
|
115250
|
+
return null;
|
|
115251
|
+
}
|
|
115252
|
+
});
|
|
115253
|
+
}
|
|
114909
115254
|
const structuredContentClass = "sd-structured-content";
|
|
114910
115255
|
const structuredContentInnerClass = "sd-structured-content__content";
|
|
114911
115256
|
const StructuredContent = Node$3.create({
|
|
@@ -114951,6 +115296,14 @@ ${o}
|
|
|
114951
115296
|
return { "data-alias": attrs.alias };
|
|
114952
115297
|
}
|
|
114953
115298
|
},
|
|
115299
|
+
lockMode: {
|
|
115300
|
+
default: "unlocked",
|
|
115301
|
+
parseDOM: (elem) => elem.getAttribute("data-lock-mode") || "unlocked",
|
|
115302
|
+
renderDOM: (attrs) => {
|
|
115303
|
+
if (!attrs.lockMode || attrs.lockMode === "unlocked") return {};
|
|
115304
|
+
return { "data-lock-mode": attrs.lockMode };
|
|
115305
|
+
}
|
|
115306
|
+
},
|
|
114954
115307
|
sdtPr: {
|
|
114955
115308
|
rendered: false
|
|
114956
115309
|
}
|
|
@@ -114968,6 +115321,9 @@ ${o}
|
|
|
114968
115321
|
0
|
|
114969
115322
|
];
|
|
114970
115323
|
},
|
|
115324
|
+
addPmPlugins() {
|
|
115325
|
+
return [createStructuredContentLockPlugin(), createStructuredContentSelectPlugin()];
|
|
115326
|
+
},
|
|
114971
115327
|
addNodeView() {
|
|
114972
115328
|
return (props) => {
|
|
114973
115329
|
return new StructuredContentInlineView({ ...props });
|
|
@@ -115002,10 +115358,12 @@ ${o}
|
|
|
115002
115358
|
element2.prepend(dragHandle);
|
|
115003
115359
|
element2.addEventListener("dragstart", (e) => this.onDragStart(e));
|
|
115004
115360
|
this.root = element2;
|
|
115361
|
+
this.updateContentEditability();
|
|
115005
115362
|
}
|
|
115006
115363
|
updateView() {
|
|
115007
115364
|
const domAttrs = Attribute.mergeAttributes(this.htmlAttributes);
|
|
115008
115365
|
updateDOMAttributes(this.dom, { ...domAttrs });
|
|
115366
|
+
this.updateContentEditability();
|
|
115009
115367
|
}
|
|
115010
115368
|
update(node2, decorations, innerDecorations) {
|
|
115011
115369
|
const result = super.update(node2, decorations, innerDecorations);
|
|
@@ -115058,6 +115416,14 @@ ${o}
|
|
|
115058
115416
|
return { "data-alias": attrs.alias };
|
|
115059
115417
|
}
|
|
115060
115418
|
},
|
|
115419
|
+
lockMode: {
|
|
115420
|
+
default: "unlocked",
|
|
115421
|
+
parseDOM: (elem) => elem.getAttribute("data-lock-mode") || "unlocked",
|
|
115422
|
+
renderDOM: (attrs) => {
|
|
115423
|
+
if (!attrs.lockMode || attrs.lockMode === "unlocked") return {};
|
|
115424
|
+
return { "data-lock-mode": attrs.lockMode };
|
|
115425
|
+
}
|
|
115426
|
+
},
|
|
115061
115427
|
sdtPr: {
|
|
115062
115428
|
rendered: false
|
|
115063
115429
|
}
|
|
@@ -134384,18 +134750,25 @@ ${o}
|
|
|
134384
134750
|
};
|
|
134385
134751
|
const _hoisted_4$9 = {
|
|
134386
134752
|
key: 3,
|
|
134387
|
-
class: "link-
|
|
134753
|
+
class: "link-title"
|
|
134388
134754
|
};
|
|
134389
|
-
const _hoisted_5$5 = {
|
|
134390
|
-
const _hoisted_6$3 = ["onKeydown"];
|
|
134391
|
-
const _hoisted_7$3 = { class: "input-row url-input-row" };
|
|
134392
|
-
const _hoisted_8$3 = ["innerHTML"];
|
|
134393
|
-
const _hoisted_9$2 = ["onKeydown"];
|
|
134394
|
-
const _hoisted_10$1 = ["innerHTML"];
|
|
134395
|
-
const _hoisted_11$1 = { class: "input-row link-buttons" };
|
|
134396
|
-
const _hoisted_12$1 = ["innerHTML"];
|
|
134397
|
-
const _hoisted_13$1 = {
|
|
134755
|
+
const _hoisted_5$5 = {
|
|
134398
134756
|
key: 4,
|
|
134757
|
+
class: "link-input-wrapper"
|
|
134758
|
+
};
|
|
134759
|
+
const _hoisted_6$3 = { class: "input-row text-input-row" };
|
|
134760
|
+
const _hoisted_7$3 = ["readonly"];
|
|
134761
|
+
const _hoisted_8$3 = { class: "input-row url-input-row" };
|
|
134762
|
+
const _hoisted_9$2 = ["innerHTML"];
|
|
134763
|
+
const _hoisted_10$1 = ["readonly", "onKeydown"];
|
|
134764
|
+
const _hoisted_11$1 = ["innerHTML"];
|
|
134765
|
+
const _hoisted_12$1 = {
|
|
134766
|
+
key: 0,
|
|
134767
|
+
class: "input-row link-buttons"
|
|
134768
|
+
};
|
|
134769
|
+
const _hoisted_13$1 = ["innerHTML"];
|
|
134770
|
+
const _hoisted_14$1 = {
|
|
134771
|
+
key: 5,
|
|
134399
134772
|
class: "input-row go-to-anchor clickable"
|
|
134400
134773
|
};
|
|
134401
134774
|
const _sfc_main$D = {
|
|
@@ -134489,6 +134862,7 @@ ${o}
|
|
|
134489
134862
|
});
|
|
134490
134863
|
const isEditing = computed(() => !isAnchor.value && !!getLinkHrefAtSelection());
|
|
134491
134864
|
const isDisabled2 = computed(() => !validUrl.value);
|
|
134865
|
+
const isViewingMode = computed(() => props.editor?.options?.documentMode === "viewing");
|
|
134492
134866
|
const openLink = () => {
|
|
134493
134867
|
window.open(url.value, "_blank");
|
|
134494
134868
|
};
|
|
@@ -134514,6 +134888,7 @@ ${o}
|
|
|
134514
134888
|
if (props.showInput) focusInput();
|
|
134515
134889
|
});
|
|
134516
134890
|
const handleSubmit = () => {
|
|
134891
|
+
if (isViewingMode.value) return;
|
|
134517
134892
|
const editor = props.editor;
|
|
134518
134893
|
if (!editor) return;
|
|
134519
134894
|
if (!rawUrl.value) {
|
|
@@ -134544,36 +134919,38 @@ ${o}
|
|
|
134544
134919
|
return openBlock(), createElementBlock("div", {
|
|
134545
134920
|
class: normalizeClass(["link-input-ctn", { "high-contrast": unref(isHighContrastMode2) }])
|
|
134546
134921
|
}, [
|
|
134547
|
-
isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_1$y, "Page anchor")) :
|
|
134548
|
-
__props.showInput && !isAnchor.value ? (openBlock(), createElementBlock("div",
|
|
134549
|
-
createBaseVNode("div",
|
|
134550
|
-
_cache[
|
|
134922
|
+
isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_1$y, "Page anchor")) : isViewingMode.value ? (openBlock(), createElementBlock("div", _hoisted_2$l, "Link details")) : isEditing.value ? (openBlock(), createElementBlock("div", _hoisted_3$g, "Edit link")) : (openBlock(), createElementBlock("div", _hoisted_4$9, "Add link")),
|
|
134923
|
+
__props.showInput && !isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_5$5, [
|
|
134924
|
+
createBaseVNode("div", _hoisted_6$3, [
|
|
134925
|
+
_cache[5] || (_cache[5] = createBaseVNode("div", { class: "input-icon text-input-icon" }, "T", -1)),
|
|
134551
134926
|
withDirectives(createBaseVNode("input", {
|
|
134552
134927
|
type: "text",
|
|
134553
134928
|
name: "text",
|
|
134554
134929
|
placeholder: "Text",
|
|
134555
134930
|
"onUpdate:modelValue": _cache[0] || (_cache[0] = ($event) => text2.value = $event),
|
|
134556
|
-
|
|
134557
|
-
|
|
134931
|
+
readonly: isViewingMode.value,
|
|
134932
|
+
onKeydown: _cache[1] || (_cache[1] = withKeys(withModifiers(($event) => !isViewingMode.value && handleSubmit, ["stop", "prevent"]), ["enter"]))
|
|
134933
|
+
}, null, 40, _hoisted_7$3), [
|
|
134558
134934
|
[vModelText, text2.value]
|
|
134559
134935
|
])
|
|
134560
134936
|
]),
|
|
134561
|
-
createBaseVNode("div",
|
|
134937
|
+
createBaseVNode("div", _hoisted_8$3, [
|
|
134562
134938
|
createBaseVNode("div", {
|
|
134563
134939
|
class: "input-icon",
|
|
134564
134940
|
innerHTML: unref(toolbarIcons).linkInput
|
|
134565
|
-
}, null, 8,
|
|
134941
|
+
}, null, 8, _hoisted_9$2),
|
|
134566
134942
|
withDirectives(createBaseVNode("input", {
|
|
134567
134943
|
type: "text",
|
|
134568
134944
|
name: "link",
|
|
134569
134945
|
placeholder: "Type or paste a link",
|
|
134570
134946
|
class: normalizeClass({ error: urlError.value }),
|
|
134571
|
-
"onUpdate:modelValue": _cache[
|
|
134947
|
+
"onUpdate:modelValue": _cache[2] || (_cache[2] = ($event) => rawUrl.value = $event),
|
|
134948
|
+
readonly: isViewingMode.value,
|
|
134572
134949
|
onKeydown: [
|
|
134573
134950
|
withKeys(withModifiers(handleSubmit, ["stop", "prevent"]), ["enter"]),
|
|
134574
|
-
_cache[
|
|
134951
|
+
_cache[3] || (_cache[3] = ($event) => urlError.value = false)
|
|
134575
134952
|
]
|
|
134576
|
-
}, null, 42,
|
|
134953
|
+
}, null, 42, _hoisted_10$1), [
|
|
134577
134954
|
[vModelText, rawUrl.value]
|
|
134578
134955
|
]),
|
|
134579
134956
|
createBaseVNode("div", {
|
|
@@ -134581,9 +134958,9 @@ ${o}
|
|
|
134581
134958
|
innerHTML: unref(toolbarIcons).openLink,
|
|
134582
134959
|
onClick: openLink,
|
|
134583
134960
|
"data-item": "btn-link-open"
|
|
134584
|
-
}, null, 10,
|
|
134961
|
+
}, null, 10, _hoisted_11$1)
|
|
134585
134962
|
]),
|
|
134586
|
-
|
|
134963
|
+
!isViewingMode.value ? (openBlock(), createElementBlock("div", _hoisted_12$1, [
|
|
134587
134964
|
isEditing.value ? (openBlock(), createElementBlock("button", {
|
|
134588
134965
|
key: 0,
|
|
134589
134966
|
class: "remove-btn",
|
|
@@ -134593,25 +134970,25 @@ ${o}
|
|
|
134593
134970
|
createBaseVNode("div", {
|
|
134594
134971
|
class: "remove-btn__icon",
|
|
134595
134972
|
innerHTML: unref(toolbarIcons).removeLink
|
|
134596
|
-
}, null, 8,
|
|
134597
|
-
_cache[
|
|
134973
|
+
}, null, 8, _hoisted_13$1),
|
|
134974
|
+
_cache[6] || (_cache[6] = createTextVNode(" Remove ", -1))
|
|
134598
134975
|
])) : createCommentVNode("", true),
|
|
134599
134976
|
createBaseVNode("button", {
|
|
134600
134977
|
class: normalizeClass(["submit-btn", { "disable-btn": isDisabled2.value }]),
|
|
134601
134978
|
onClick: handleSubmit,
|
|
134602
134979
|
"data-item": "btn-link-apply"
|
|
134603
134980
|
}, " Apply ", 2)
|
|
134604
|
-
])
|
|
134605
|
-
])) : isAnchor.value ? (openBlock(), createElementBlock("div",
|
|
134981
|
+
])) : createCommentVNode("", true)
|
|
134982
|
+
])) : isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_14$1, [
|
|
134606
134983
|
createBaseVNode("a", {
|
|
134607
|
-
onClick: _cache[
|
|
134984
|
+
onClick: _cache[4] || (_cache[4] = withModifiers((...args) => __props.goToAnchor && __props.goToAnchor(...args), ["stop", "prevent"]))
|
|
134608
134985
|
}, "Go to " + toDisplayString(rawUrl.value.startsWith("#_") ? rawUrl.value.substring(2) : rawUrl.value), 1)
|
|
134609
134986
|
])) : createCommentVNode("", true)
|
|
134610
134987
|
], 2);
|
|
134611
134988
|
};
|
|
134612
134989
|
}
|
|
134613
134990
|
};
|
|
134614
|
-
const LinkInput = /* @__PURE__ */ _export_sfc(_sfc_main$D, [["__scopeId", "data-v-
|
|
134991
|
+
const LinkInput = /* @__PURE__ */ _export_sfc(_sfc_main$D, [["__scopeId", "data-v-198fc596"]]);
|
|
134615
134992
|
const _hoisted_1$x = ["aria-label", "onClick", "onKeydown"];
|
|
134616
134993
|
const _hoisted_2$k = ["innerHTML"];
|
|
134617
134994
|
const _hoisted_3$f = ["innerHTML"];
|
|
@@ -171448,7 +171825,7 @@ js: import "konva/skia-backend";
|
|
|
171448
171825
|
this.config.colors = shuffleArray(this.config.colors);
|
|
171449
171826
|
this.userColorMap = /* @__PURE__ */ new Map();
|
|
171450
171827
|
this.colorIndex = 0;
|
|
171451
|
-
this.version = "1.12.0-next.
|
|
171828
|
+
this.version = "1.12.0-next.13";
|
|
171452
171829
|
this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
|
|
171453
171830
|
this.superdocId = config2.superdocId || v4();
|
|
171454
171831
|
this.colors = this.config.colors;
|