superdoc 2.23.0-next.8 → 2.23.0

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.
Files changed (30) hide show
  1. package/dist/chunks/{create-super-doc-ui-CbiiPcgr.cjs → create-super-doc-ui-1uZB3O_w.cjs} +1 -0
  2. package/dist/chunks/{create-super-doc-ui-DHW9Toxn.es.js → create-super-doc-ui-B8N_IUG2.es.js} +1 -0
  3. package/dist/collaboration-upgrade-engine.cjs +1 -1
  4. package/dist/collaboration-upgrade-engine.es.js +1 -1
  5. package/dist/document-api/src/contract/operation-registry.d.ts +19 -2
  6. package/dist/document-api/src/delete/delete.d.ts +2 -2
  7. package/dist/document-api/src/index.d.ts +8 -4
  8. package/dist/document-api/src/insert/insert.d.ts +5 -2
  9. package/dist/document-api/src/replace/replace.d.ts +2 -2
  10. package/dist/document-api/src/selection-mutation.d.ts +2 -2
  11. package/dist/document-api/src/types/clipboard.d.ts +28 -0
  12. package/dist/document-api/src/types/sd-contract.d.ts +1 -1
  13. package/dist/document-api/src/write/write.d.ts +12 -2
  14. package/dist/public/ui-react.cjs +1 -1
  15. package/dist/public/ui-react.es.js +1 -1
  16. package/dist/public/ui-vue.cjs +1 -1
  17. package/dist/public/ui-vue.es.js +1 -1
  18. package/dist/public/ui.cjs +1 -1
  19. package/dist/public/ui.es.js +1 -1
  20. package/dist/style.css +53 -53
  21. package/dist/style.layered.css +53 -53
  22. package/dist/superdoc/src/internal/toolbar/built-in/AIWriter.vue.d.ts +2 -2
  23. package/dist/superdoc/src/internal/toolbar/built-in/LinkInput.vue.d.ts +2 -0
  24. package/dist/superdoc/src/public/browser-document-api.d.ts +12 -2
  25. package/dist/superdoc.cjs +72 -36
  26. package/dist/superdoc.es.js +72 -36
  27. package/dist-cdn/style.layered.css +1 -1
  28. package/dist-cdn/superdoc.min.css +1 -1
  29. package/dist-cdn/superdoc.min.js +19 -19
  30. package/package.json +2 -2
@@ -1,4 +1,4 @@
1
- import { DocumentApi } from '../../../document-api/src/index.js';
1
+ import { DocumentApi, DynamicInvokeRequest, InvokeRequest, InvokeResult, OperationId, OperationCancellation, PlainTextInsertInput, TextReplaceInput, TrackedTextMutationOptions } from '../../../document-api/src/index.js';
2
2
  type MaybePromise<T> = T | Promise<T>;
3
3
  type BrowserDocumentApiObject<T> = {
4
4
  [K in keyof T]: BrowserDocumentApiValue<T[K]>;
@@ -11,7 +11,17 @@ type BrowserDocumentApiValue<T> = T extends (...args: infer Args) => infer Retur
11
11
  * worker-backed runtime. SDK/headless callers should continue using the
12
12
  * synchronous `@superdoc/document-api` surface directly.
13
13
  */
14
- export type BrowserDocumentApi = BrowserDocumentApiObject<DocumentApi>;
14
+ export type BrowserDocumentApi = Omit<BrowserDocumentApiObject<DocumentApi>, 'invoke'> & {
15
+ invoke<T extends OperationId>(request: InvokeRequest<T>): MaybePromise<Awaited<InvokeResult<T>>>;
16
+ invoke(request: DynamicInvokeRequest): unknown;
17
+ insert(input: PlainTextInsertInput, options: TrackedTextMutationOptions & OperationCancellation): MaybePromise<Awaited<ReturnType<DocumentApi['insert']>>>;
18
+ replace(input: Exclude<TextReplaceInput, {
19
+ target: {
20
+ kind: 'story';
21
+ storyType: 'body';
22
+ };
23
+ }>, options: TrackedTextMutationOptions): MaybePromise<Awaited<ReturnType<DocumentApi['replace']>>>;
24
+ };
15
25
  /**
16
26
  * Every operation optional, at any depth.
17
27
  *
package/dist/superdoc.cjs CHANGED
@@ -1,7 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_rolldown_runtime = require("./chunks/rolldown-runtime-74VwNCz7.cjs");
3
3
  const require_blank_docx = require("./chunks/blank-docx-BuFAbRjs.cjs");
4
- const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-CbiiPcgr.cjs");
4
+ const require_create_super_doc_ui = require("./chunks/create-super-doc-ui-1uZB3O_w.cjs");
5
5
  const require_eventemitter3 = require("./chunks/eventemitter3-C_TAnXOl.cjs");
6
6
  const require_uuid = require("./chunks/uuid-BhG0ngwk.cjs");
7
7
  const require__plugin_vue_export_helper = require("./chunks/_plugin-vue_export-helper-CYxINHh_.cjs");
@@ -304,7 +304,7 @@ var awarenessStatesToArray = (context, states) => {
304
304
  var DEFAULT_ENDPOINT = "https://ingest.superdoc.dev/v1/collect";
305
305
  function getSuperdocVersion() {
306
306
  try {
307
- return "2.23.0-next.8";
307
+ return "2.23.0";
308
308
  } catch {
309
309
  return "unknown";
310
310
  }
@@ -13205,12 +13205,12 @@ var _hoisted_14$2 = {
13205
13205
  key: 0,
13206
13206
  class: "tracked-change-text"
13207
13207
  };
13208
- var _hoisted_15$1 = {
13208
+ var _hoisted_15$2 = {
13209
13209
  key: 1,
13210
13210
  class: "change-type"
13211
13211
  };
13212
- var _hoisted_16$1 = { class: "change-type" };
13213
- var _hoisted_17$1 = { key: 1 };
13212
+ var _hoisted_16$2 = { class: "change-type" };
13213
+ var _hoisted_17$2 = { key: 1 };
13214
13214
  var _hoisted_18$1 = { class: "tracked-change-text is-inserted" };
13215
13215
  var _hoisted_19$1 = { key: 2 };
13216
13216
  var _hoisted_20$1 = { class: "tracked-change-text is-inserted" };
@@ -14275,10 +14275,10 @@ var _sfc_main$34 = {
14275
14275
  class: "tracked-change-detail-line"
14276
14276
  }, [
14277
14277
  line.excerpt ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("span", _hoisted_14$2, "\"" + require__plugin_vue_export_helper.toDisplayString(line.excerpt) + "\"", 1)) : require__plugin_vue_export_helper.createCommentVNode("", true),
14278
- line.excerpt ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("span", _hoisted_15$1, " — ")) : require__plugin_vue_export_helper.createCommentVNode("", true),
14279
- require__plugin_vue_export_helper.createElementVNode("span", _hoisted_16$1, require__plugin_vue_export_helper.toDisplayString(line.label), 1)
14278
+ line.excerpt ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("span", _hoisted_15$2, " — ")) : require__plugin_vue_export_helper.createCommentVNode("", true),
14279
+ require__plugin_vue_export_helper.createElementVNode("span", _hoisted_16$2, require__plugin_vue_export_helper.toDisplayString(line.label), 1)
14280
14280
  ]);
14281
- }), 128))])) : require__plugin_vue_export_helper.createCommentVNode("", true)])) : comment.trackedChangeDisplayType === "hyperlinkAdded" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_17$1, [_cache[2] || (_cache[2] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Added hyperlink ", -1)), require__plugin_vue_export_helper.createElementVNode("span", _hoisted_18$1, "\"" + require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeText) + "\"", 1)])) : comment.trackedChangeDisplayType === "hyperlinkModified" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_19$1, [_cache[3] || (_cache[3] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Changed hyperlink to ", -1)), require__plugin_vue_export_helper.createElementVNode("span", _hoisted_20$1, "\"" + require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeText) + "\"", 1)])) : comment.trackedChangeDisplayType === "paragraphSplit" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_21$1, [..._cache[4] || (_cache[4] = [require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Added new line", -1)])])) : comment.trackedChangeDisplayType === "tableInsert" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_22$1, [..._cache[5] || (_cache[5] = [require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Added table", -1)])])) : comment.trackedChangeDisplayType === "tableDelete" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_23$1, [..._cache[6] || (_cache[6] = [require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Deleted table", -1)])])) : comment.trackedChangeType === "trackFormat" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_24, [_cache[7] || (_cache[7] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Format: ", -1)), require__plugin_vue_export_helper.createElementVNode("span", _hoisted_25, require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeText), 1)])) : comment.trackedChangeType === "both" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_26, [
14281
+ }), 128))])) : require__plugin_vue_export_helper.createCommentVNode("", true)])) : comment.trackedChangeDisplayType === "hyperlinkAdded" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_17$2, [_cache[2] || (_cache[2] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Added hyperlink ", -1)), require__plugin_vue_export_helper.createElementVNode("span", _hoisted_18$1, "\"" + require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeText) + "\"", 1)])) : comment.trackedChangeDisplayType === "hyperlinkModified" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_19$1, [_cache[3] || (_cache[3] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Changed hyperlink to ", -1)), require__plugin_vue_export_helper.createElementVNode("span", _hoisted_20$1, "\"" + require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeText) + "\"", 1)])) : comment.trackedChangeDisplayType === "paragraphSplit" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_21$1, [..._cache[4] || (_cache[4] = [require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Added new line", -1)])])) : comment.trackedChangeDisplayType === "tableInsert" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_22$1, [..._cache[5] || (_cache[5] = [require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Added table", -1)])])) : comment.trackedChangeDisplayType === "tableDelete" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_23$1, [..._cache[6] || (_cache[6] = [require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Deleted table", -1)])])) : comment.trackedChangeType === "trackFormat" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_24, [_cache[7] || (_cache[7] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Format: ", -1)), require__plugin_vue_export_helper.createElementVNode("span", _hoisted_25, require__plugin_vue_export_helper.toDisplayString(comment.trackedChangeText), 1)])) : comment.trackedChangeType === "both" ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_26, [
14282
14282
  _cache[8] || (_cache[8] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, "Replaced ", -1)),
14283
14283
  require__plugin_vue_export_helper.createElementVNode("span", _hoisted_27, "\"" + require__plugin_vue_export_helper.toDisplayString(comment.deletedText) + "\"", 1),
14284
14284
  _cache[9] || (_cache[9] = require__plugin_vue_export_helper.createElementVNode("span", { class: "change-type" }, " with ", -1)),
@@ -18904,8 +18904,15 @@ var _hoisted_12$1 = {
18904
18904
  key: 0,
18905
18905
  class: "input-row link-buttons"
18906
18906
  };
18907
- var _hoisted_13$1 = ["innerHTML"];
18908
- var _hoisted_14$1 = {
18907
+ var _hoisted_13$1 = ["disabled"];
18908
+ var _hoisted_14$1 = ["innerHTML"];
18909
+ var _hoisted_15$1 = ["disabled"];
18910
+ var _hoisted_16$1 = {
18911
+ key: 1,
18912
+ role: "alert",
18913
+ class: "sd-error"
18914
+ };
18915
+ var _hoisted_17$1 = {
18909
18916
  key: 5,
18910
18917
  class: "input-row go-to-anchor clickable"
18911
18918
  };
@@ -18986,6 +18993,10 @@ var _sfc_main$26 = {
18986
18993
  type: Object,
18987
18994
  default: null
18988
18995
  },
18996
+ selectedText: {
18997
+ type: String,
18998
+ default: null
18999
+ },
18989
19000
  /**
18990
19001
  * Re-applies the toolbar's pre-interaction selection capture before the link
18991
19002
  * command runs. LinkInput executes the command directly (bypassing Toolbar.vue's
@@ -19006,8 +19017,11 @@ var _sfc_main$26 = {
19006
19017
  const props = __props;
19007
19018
  const { isHighContrastMode } = useHighContrastMode();
19008
19019
  const urlError = require__plugin_vue_export_helper.ref(false);
19020
+ const commandError = require__plugin_vue_export_helper.ref("");
19021
+ const isSubmitting = require__plugin_vue_export_helper.ref(false);
19009
19022
  const readSelectedText = () => {
19010
19023
  if (typeof props.hyperlinkText === "string" && props.hyperlinkText) return props.hyperlinkText;
19024
+ if (typeof props.selectedText === "string" && props.selectedText) return props.selectedText;
19011
19025
  const snapshot = props.ui?.selection?.getSnapshot?.();
19012
19026
  if (typeof snapshot?.quotedText === "string" && snapshot.quotedText) return snapshot.quotedText;
19013
19027
  const clickedText = props.clickedElement?.innerText ?? props.clickedElement?.textContent;
@@ -19038,7 +19052,7 @@ var _sfc_main$26 = {
19038
19052
  const validUrl = require__plugin_vue_export_helper.computed(() => sanitizedUrl.value !== null);
19039
19053
  const hadExistingLink = require__plugin_vue_export_helper.ref(false);
19040
19054
  const isEditing = require__plugin_vue_export_helper.computed(() => !isAnchor.value && hadExistingLink.value);
19041
- const isDisabled = require__plugin_vue_export_helper.computed(() => !validUrl.value);
19055
+ const isDisabled = require__plugin_vue_export_helper.computed(() => !validUrl.value || isSubmitting.value);
19042
19056
  const isViewingMode = require__plugin_vue_export_helper.computed(() => readDocumentMode() === "viewing");
19043
19057
  const openLink = () => {
19044
19058
  const href = sanitizedUrl.value?.href;
@@ -19057,20 +19071,36 @@ var _sfc_main$26 = {
19057
19071
  isAnchor.value = rawUrl.value.startsWith("#");
19058
19072
  if (props.showInput && !isViewingMode.value) focusInput();
19059
19073
  });
19060
- const runLinkCommand = (payload) => {
19074
+ const runLinkCommand = async (payload) => {
19061
19075
  const ui = props.ui;
19062
- if (!ui?.commands?.execute) return false;
19076
+ if (!ui?.commands?.executeAsync) return false;
19063
19077
  props.restoreSelection?.();
19064
- return ui.commands.execute("link", payload);
19078
+ return require_create_super_doc_ui.executeFirstPartyCommandAsync(ui, "link", payload);
19065
19079
  };
19066
- const handleSubmit = () => {
19067
- if (isViewingMode.value) return;
19080
+ const applyLinkCommand = async (payload) => {
19081
+ if (isSubmitting.value) return;
19082
+ isSubmitting.value = true;
19083
+ commandError.value = "";
19084
+ try {
19085
+ const result = await runLinkCommand(payload);
19086
+ if (result === false || result == null || typeof result === "object" && (result.success === false || result.status === "rejected")) {
19087
+ commandError.value = "Could not apply link. Check the selection and try again.";
19088
+ return;
19089
+ }
19090
+ props.closePopover();
19091
+ } catch {
19092
+ commandError.value = "Could not apply link. Check the selection and try again.";
19093
+ } finally {
19094
+ isSubmitting.value = false;
19095
+ }
19096
+ };
19097
+ const handleSubmit = async () => {
19098
+ if (isViewingMode.value || isSubmitting.value) return;
19068
19099
  if (!rawUrl.value) {
19069
- runLinkCommand({
19100
+ await applyLinkCommand({
19070
19101
  href: null,
19071
19102
  hyperlinkTarget: props.hyperlinkTarget
19072
19103
  });
19073
- props.closePopover();
19074
19104
  return;
19075
19105
  }
19076
19106
  if (!validUrl.value) {
@@ -19089,23 +19119,22 @@ var _sfc_main$26 = {
19089
19119
  textTarget: props.textTarget
19090
19120
  };
19091
19121
  if (text.value) payload.text = text.value;
19092
- else if (!isEditing.value) payload.text = href;
19093
- runLinkCommand(payload);
19094
- props.closePopover();
19122
+ else if (!isEditing.value && !props.textTarget) payload.text = href;
19123
+ await applyLinkCommand(payload);
19095
19124
  };
19096
- const handleRemove = () => {
19097
- runLinkCommand({
19125
+ const handleRemove = async () => {
19126
+ if (isViewingMode.value || isSubmitting.value) return;
19127
+ await applyLinkCommand({
19098
19128
  href: null,
19099
19129
  hyperlinkTarget: props.hyperlinkTarget
19100
19130
  });
19101
- props.closePopover();
19102
19131
  };
19103
19132
  const navigateToAnchor = (anchorUrl) => {
19104
19133
  if (props.goToAnchor) props.goToAnchor(anchorUrl);
19105
19134
  };
19106
19135
  return (_ctx, _cache) => {
19107
19136
  return require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", { class: require__plugin_vue_export_helper.normalizeClass(["link-input-ctn", { "high-contrast": require__plugin_vue_export_helper.unref(isHighContrastMode) }]) }, [isAnchor.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_1$20, "Page anchor")) : isViewingMode.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_2$16, "Link details")) : isEditing.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_3$13, "Edit link")) : (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_4$8, "Add link")), __props.showInput && !isAnchor.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_5$6, [
19108
- require__plugin_vue_export_helper.createElementVNode("div", _hoisted_6$5, [_cache[4] || (_cache[4] = require__plugin_vue_export_helper.createElementVNode("div", { class: "input-icon text-input-icon" }, "T", -1)), require__plugin_vue_export_helper.withDirectives(require__plugin_vue_export_helper.createElementVNode("input", {
19137
+ require__plugin_vue_export_helper.createElementVNode("div", _hoisted_6$5, [_cache[5] || (_cache[5] = require__plugin_vue_export_helper.createElementVNode("div", { class: "input-icon text-input-icon" }, "T", -1)), require__plugin_vue_export_helper.withDirectives(require__plugin_vue_export_helper.createElementVNode("input", {
19109
19138
  type: "text",
19110
19139
  name: "text",
19111
19140
  placeholder: "Text",
@@ -19125,7 +19154,8 @@ var _sfc_main$26 = {
19125
19154
  class: require__plugin_vue_export_helper.normalizeClass({ "sd-error": urlError.value }),
19126
19155
  "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => rawUrl.value = $event),
19127
19156
  readonly: isViewingMode.value,
19128
- onKeydown: [require__plugin_vue_export_helper.withKeys(require__plugin_vue_export_helper.withModifiers(handleSubmit, ["stop", "prevent"]), ["enter"]), _cache[2] || (_cache[2] = ($event) => urlError.value = false)]
19157
+ onInput: _cache[2] || (_cache[2] = ($event) => commandError.value = ""),
19158
+ onKeydown: [require__plugin_vue_export_helper.withKeys(require__plugin_vue_export_helper.withModifiers(handleSubmit, ["stop", "prevent"]), ["enter"]), _cache[3] || (_cache[3] = ($event) => urlError.value = false)]
19129
19159
  }, null, 42, _hoisted_10$2), [[require__plugin_vue_export_helper.vModelText, rawUrl.value]]),
19130
19160
  require__plugin_vue_export_helper.createElementVNode("div", {
19131
19161
  class: require__plugin_vue_export_helper.normalizeClass(["open-link-icon", { "sd-disabled": !validUrl.value }]),
@@ -19138,20 +19168,23 @@ var _sfc_main$26 = {
19138
19168
  key: 0,
19139
19169
  class: "remove-btn",
19140
19170
  onClick: handleRemove,
19171
+ disabled: isSubmitting.value,
19141
19172
  "data-item": "btn-link-remove"
19142
19173
  }, [require__plugin_vue_export_helper.createElementVNode("div", {
19143
19174
  class: "remove-btn__icon",
19144
19175
  innerHTML: require__plugin_vue_export_helper.unref(toolbarIcons).removeLink
19145
- }, null, 8, _hoisted_13$1), _cache[5] || (_cache[5] = require__plugin_vue_export_helper.createTextVNode(" Remove ", -1))])) : require__plugin_vue_export_helper.createCommentVNode("", true), require__plugin_vue_export_helper.createElementVNode("button", {
19176
+ }, null, 8, _hoisted_14$1), _cache[6] || (_cache[6] = require__plugin_vue_export_helper.createTextVNode(" Remove ", -1))], 8, _hoisted_13$1)) : require__plugin_vue_export_helper.createCommentVNode("", true), require__plugin_vue_export_helper.createElementVNode("button", {
19146
19177
  class: require__plugin_vue_export_helper.normalizeClass(["sd-submit-btn", { "disable-btn": isDisabled.value }]),
19147
19178
  onClick: handleSubmit,
19179
+ disabled: isSubmitting.value,
19148
19180
  "data-item": "btn-link-apply"
19149
- }, " Apply ", 2)])) : require__plugin_vue_export_helper.createCommentVNode("", true)
19150
- ])) : isAnchor.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_14$1, [require__plugin_vue_export_helper.createElementVNode("a", { onClick: _cache[3] || (_cache[3] = require__plugin_vue_export_helper.withModifiers(($event) => navigateToAnchor(rawUrl.value), ["stop", "prevent"])) }, "Go to " + require__plugin_vue_export_helper.toDisplayString(rawUrl.value.startsWith("#_") ? rawUrl.value.substring(2) : rawUrl.value), 1)])) : require__plugin_vue_export_helper.createCommentVNode("", true)], 2);
19181
+ }, " Apply ", 10, _hoisted_15$1)])) : require__plugin_vue_export_helper.createCommentVNode("", true),
19182
+ commandError.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_16$1, require__plugin_vue_export_helper.toDisplayString(commandError.value), 1)) : require__plugin_vue_export_helper.createCommentVNode("", true)
19183
+ ])) : isAnchor.value ? (require__plugin_vue_export_helper.openBlock(), require__plugin_vue_export_helper.createElementBlock("div", _hoisted_17$1, [require__plugin_vue_export_helper.createElementVNode("a", { onClick: _cache[4] || (_cache[4] = require__plugin_vue_export_helper.withModifiers(($event) => navigateToAnchor(rawUrl.value), ["stop", "prevent"])) }, "Go to " + require__plugin_vue_export_helper.toDisplayString(rawUrl.value.startsWith("#_") ? rawUrl.value.substring(2) : rawUrl.value), 1)])) : require__plugin_vue_export_helper.createCommentVNode("", true)], 2);
19151
19184
  };
19152
19185
  }
19153
19186
  };
19154
- var LinkInput_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$26, [["__scopeId", "data-v-3e4bd44e"]]);
19187
+ var LinkInput_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_vue_export_helper_default(_sfc_main$26, [["__scopeId", "data-v-498a6e6e"]]);
19155
19188
  //#endregion
19156
19189
  //#region src/internal/toolbar/built-in/scroll-helpers.js
19157
19190
  function getScrollableParent(element) {
@@ -22247,6 +22280,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
22247
22280
  return () => {
22248
22281
  const linkItem = toolbar.getToolbarItemByName("link");
22249
22282
  if (!linkItem || linkItem.disabled?.value === true) return;
22283
+ toolbar.pendingSelectionCapture = toolbar.ui?.selection?.capture?.() ?? null;
22250
22284
  if (linkItem.expand && typeof linkItem.expand === "object" && "value" in linkItem.expand) linkItem.expand.value = true;
22251
22285
  toolbar.updateToolbarState?.();
22252
22286
  };
@@ -24609,7 +24643,7 @@ var SuperDoc_default = /*#__PURE__*/ require__plugin_vue_export_helper._plugin_v
24609
24643
  ], 38);
24610
24644
  };
24611
24645
  }
24612
- }, [["__scopeId", "data-v-3a8bc935"]]);
24646
+ }, [["__scopeId", "data-v-f53aafe0"]]);
24613
24647
  //#endregion
24614
24648
  //#region src/core/create-app.js
24615
24649
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
@@ -43981,16 +44015,18 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons, toolbarTexts, toolbarFonts
43981
44015
  }
43982
44016
  });
43983
44017
  function renderLinkDropdown(link) {
43984
- const selection = currentSelectionSnapshot(superToolbar);
43985
- const selectionTarget = selection?.selectionTarget ?? selectionTargetFromTextTarget(selection?.target);
44018
+ const capture = superToolbar.pendingSelectionCapture;
44019
+ const liveSelection = currentSelectionSnapshot(superToolbar);
44020
+ const selection = liveSelection?.quotedText && JSON.stringify(liveSelection.selectionTarget ?? liveSelection.target) !== JSON.stringify(capture?.selectionTarget ?? capture?.target) ? liveSelection : capture ?? liveSelection;
44021
+ const selectionTarget = selection?.selectionTarget ?? selectionTargetFromTextTarget(selection?.target) ?? selection?.target;
43986
44022
  const restoreSelection = () => {
43987
- const capture = superToolbar.pendingSelectionCapture;
43988
- if (capture && typeof superToolbar.ui?.selection?.restore === "function") superToolbar.ui.selection.restore(capture);
44023
+ if (selection === capture && typeof superToolbar.ui?.selection?.restore === "function") superToolbar.ui.selection.restore(capture);
43989
44024
  };
43990
44025
  return require__plugin_vue_export_helper.h("div", {}, [require__plugin_vue_export_helper.h(LinkInput_default, {
43991
44026
  ui: superToolbar.ui,
43992
44027
  linkItem: link,
43993
44028
  textTarget: selectionTarget,
44029
+ selectedText: selection?.quotedText ?? null,
43994
44030
  restoreSelection,
43995
44031
  closePopover: () => {
43996
44032
  closeDropdown(link);
@@ -46433,7 +46469,7 @@ var SuperDoc = class extends require_eventemitter3.import_eventemitter3.default
46433
46469
  }
46434
46470
  this.userColorMap = /* @__PURE__ */ new Map();
46435
46471
  this.colorIndex = 0;
46436
- this.version = "2.23.0-next.8";
46472
+ this.version = "2.23.0";
46437
46473
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
46438
46474
  this.superdocId = config.superdocId || require_uuid.v4();
46439
46475
  this.colors = this.config.colors ?? [];
@@ -1,6 +1,6 @@
1
1
  import { i as __toESM$2 } from "./chunks/rolldown-runtime-0pSA04fp.es.js";
2
2
  import { t as blank_default } from "./chunks/blank-docx-DzQccOlW.es.js";
3
- import { c as createImageFilePicker, d as DOM_CLASS_NAMES, f as closeInteractionHistory, g as recordInteraction, h as isWorkflowRecordingEnabled, i as registerFirstPartyCommandMutation, l as resolveImageSrc, m as getWorkflowRecording, n as executeFirstPartyCommandAsync, o as applyV2CommentInvalidationFromMutation, p as createInteractionHistory, r as readFirstPartyPageNumbers, s as getV2TrackedChangeMutationImpact, t as createSuperDocUI } from "./chunks/create-super-doc-ui-DHW9Toxn.es.js";
3
+ import { c as createImageFilePicker, d as DOM_CLASS_NAMES, f as closeInteractionHistory, g as recordInteraction, h as isWorkflowRecordingEnabled, i as registerFirstPartyCommandMutation, l as resolveImageSrc, m as getWorkflowRecording, n as executeFirstPartyCommandAsync, o as applyV2CommentInvalidationFromMutation, p as createInteractionHistory, r as readFirstPartyPageNumbers, s as getV2TrackedChangeMutationImpact, t as createSuperDocUI } from "./chunks/create-super-doc-ui-B8N_IUG2.es.js";
4
4
  import { t as import_eventemitter3 } from "./chunks/eventemitter3-DEIiXiH2.es.js";
5
5
  import { t as v4 } from "./chunks/uuid-H0Xcmmhy.es.js";
6
6
  import { $ as watch$1, A as onActivated, B as resolveDirective, C as isRef$1, D as normalizeClass, E as nextTick, F as openBlock, G as toRef, H as shallowRef$1, I as reactive, J as useAttrs, K as toRefs, L as ref, M as onDeactivated, N as onMounted, O as normalizeProps, P as onScopeDispose$1, Q as vModelText, R as renderList, S as isReactive$1, T as mergeProps, U as toDisplayString, V as resolveDynamicComponent, W as toRaw$2, X as vModelCheckbox, Y as useSlots, Z as vModelSelect, _ as getCurrentInstance, a as computed$1, b as hasInjectionContext, c as createCommentVNode, d as createStaticVNode, et as withCtx, f as createTextVNode, g as effectScope, h as defineComponent, i as Transition, j as onBeforeUnmount, k as normalizeStyle, l as createElementBlock, m as defineAsyncComponent, n as Fragment, nt as withKeys, o as createApp, p as createVNode, q as unref, r as Teleport, rt as withModifiers, s as createBlock, t as _plugin_vue_export_helper_default, tt as withDirectives, u as createElementVNode, v as getCurrentScope, w as markRaw, x as inject$1, y as h, z as renderSlot } from "./chunks/_plugin-vue_export-helper-DHiJKCsy.es.js";
@@ -302,7 +302,7 @@ var awarenessStatesToArray = (context, states) => {
302
302
  var DEFAULT_ENDPOINT = "https://ingest.superdoc.dev/v1/collect";
303
303
  function getSuperdocVersion() {
304
304
  try {
305
- return "2.23.0-next.8";
305
+ return "2.23.0";
306
306
  } catch {
307
307
  return "unknown";
308
308
  }
@@ -13198,12 +13198,12 @@ var _hoisted_14$2 = {
13198
13198
  key: 0,
13199
13199
  class: "tracked-change-text"
13200
13200
  };
13201
- var _hoisted_15$1 = {
13201
+ var _hoisted_15$2 = {
13202
13202
  key: 1,
13203
13203
  class: "change-type"
13204
13204
  };
13205
- var _hoisted_16$1 = { class: "change-type" };
13206
- var _hoisted_17$1 = { key: 1 };
13205
+ var _hoisted_16$2 = { class: "change-type" };
13206
+ var _hoisted_17$2 = { key: 1 };
13207
13207
  var _hoisted_18$1 = { class: "tracked-change-text is-inserted" };
13208
13208
  var _hoisted_19$1 = { key: 2 };
13209
13209
  var _hoisted_20$1 = { class: "tracked-change-text is-inserted" };
@@ -14268,10 +14268,10 @@ var CommentDialog_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
14268
14268
  class: "tracked-change-detail-line"
14269
14269
  }, [
14270
14270
  line.excerpt ? (openBlock(), createElementBlock("span", _hoisted_14$2, "\"" + toDisplayString(line.excerpt) + "\"", 1)) : createCommentVNode("", true),
14271
- line.excerpt ? (openBlock(), createElementBlock("span", _hoisted_15$1, " — ")) : createCommentVNode("", true),
14272
- createElementVNode("span", _hoisted_16$1, toDisplayString(line.label), 1)
14271
+ line.excerpt ? (openBlock(), createElementBlock("span", _hoisted_15$2, " — ")) : createCommentVNode("", true),
14272
+ createElementVNode("span", _hoisted_16$2, toDisplayString(line.label), 1)
14273
14273
  ]);
14274
- }), 128))])) : createCommentVNode("", true)])) : comment.trackedChangeDisplayType === "hyperlinkAdded" ? (openBlock(), createElementBlock("div", _hoisted_17$1, [_cache[2] || (_cache[2] = createElementVNode("span", { class: "change-type" }, "Added hyperlink ", -1)), createElementVNode("span", _hoisted_18$1, "\"" + toDisplayString(comment.trackedChangeText) + "\"", 1)])) : comment.trackedChangeDisplayType === "hyperlinkModified" ? (openBlock(), createElementBlock("div", _hoisted_19$1, [_cache[3] || (_cache[3] = createElementVNode("span", { class: "change-type" }, "Changed hyperlink to ", -1)), createElementVNode("span", _hoisted_20$1, "\"" + toDisplayString(comment.trackedChangeText) + "\"", 1)])) : comment.trackedChangeDisplayType === "paragraphSplit" ? (openBlock(), createElementBlock("div", _hoisted_21$1, [..._cache[4] || (_cache[4] = [createElementVNode("span", { class: "change-type" }, "Added new line", -1)])])) : comment.trackedChangeDisplayType === "tableInsert" ? (openBlock(), createElementBlock("div", _hoisted_22$1, [..._cache[5] || (_cache[5] = [createElementVNode("span", { class: "change-type" }, "Added table", -1)])])) : comment.trackedChangeDisplayType === "tableDelete" ? (openBlock(), createElementBlock("div", _hoisted_23$1, [..._cache[6] || (_cache[6] = [createElementVNode("span", { class: "change-type" }, "Deleted table", -1)])])) : comment.trackedChangeType === "trackFormat" ? (openBlock(), createElementBlock("div", _hoisted_24, [_cache[7] || (_cache[7] = createElementVNode("span", { class: "change-type" }, "Format: ", -1)), createElementVNode("span", _hoisted_25, toDisplayString(comment.trackedChangeText), 1)])) : comment.trackedChangeType === "both" ? (openBlock(), createElementBlock("div", _hoisted_26, [
14274
+ }), 128))])) : createCommentVNode("", true)])) : comment.trackedChangeDisplayType === "hyperlinkAdded" ? (openBlock(), createElementBlock("div", _hoisted_17$2, [_cache[2] || (_cache[2] = createElementVNode("span", { class: "change-type" }, "Added hyperlink ", -1)), createElementVNode("span", _hoisted_18$1, "\"" + toDisplayString(comment.trackedChangeText) + "\"", 1)])) : comment.trackedChangeDisplayType === "hyperlinkModified" ? (openBlock(), createElementBlock("div", _hoisted_19$1, [_cache[3] || (_cache[3] = createElementVNode("span", { class: "change-type" }, "Changed hyperlink to ", -1)), createElementVNode("span", _hoisted_20$1, "\"" + toDisplayString(comment.trackedChangeText) + "\"", 1)])) : comment.trackedChangeDisplayType === "paragraphSplit" ? (openBlock(), createElementBlock("div", _hoisted_21$1, [..._cache[4] || (_cache[4] = [createElementVNode("span", { class: "change-type" }, "Added new line", -1)])])) : comment.trackedChangeDisplayType === "tableInsert" ? (openBlock(), createElementBlock("div", _hoisted_22$1, [..._cache[5] || (_cache[5] = [createElementVNode("span", { class: "change-type" }, "Added table", -1)])])) : comment.trackedChangeDisplayType === "tableDelete" ? (openBlock(), createElementBlock("div", _hoisted_23$1, [..._cache[6] || (_cache[6] = [createElementVNode("span", { class: "change-type" }, "Deleted table", -1)])])) : comment.trackedChangeType === "trackFormat" ? (openBlock(), createElementBlock("div", _hoisted_24, [_cache[7] || (_cache[7] = createElementVNode("span", { class: "change-type" }, "Format: ", -1)), createElementVNode("span", _hoisted_25, toDisplayString(comment.trackedChangeText), 1)])) : comment.trackedChangeType === "both" ? (openBlock(), createElementBlock("div", _hoisted_26, [
14275
14275
  _cache[8] || (_cache[8] = createElementVNode("span", { class: "change-type" }, "Replaced ", -1)),
14276
14276
  createElementVNode("span", _hoisted_27, "\"" + toDisplayString(comment.deletedText) + "\"", 1),
14277
14277
  _cache[9] || (_cache[9] = createElementVNode("span", { class: "change-type" }, " with ", -1)),
@@ -18888,8 +18888,15 @@ var _hoisted_12$1 = {
18888
18888
  key: 0,
18889
18889
  class: "input-row link-buttons"
18890
18890
  };
18891
- var _hoisted_13$1 = ["innerHTML"];
18892
- var _hoisted_14$1 = {
18891
+ var _hoisted_13$1 = ["disabled"];
18892
+ var _hoisted_14$1 = ["innerHTML"];
18893
+ var _hoisted_15$1 = ["disabled"];
18894
+ var _hoisted_16$1 = {
18895
+ key: 1,
18896
+ role: "alert",
18897
+ class: "sd-error"
18898
+ };
18899
+ var _hoisted_17$1 = {
18893
18900
  key: 5,
18894
18901
  class: "input-row go-to-anchor clickable"
18895
18902
  };
@@ -18954,6 +18961,10 @@ var LinkInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
18954
18961
  type: Object,
18955
18962
  default: null
18956
18963
  },
18964
+ selectedText: {
18965
+ type: String,
18966
+ default: null
18967
+ },
18957
18968
  /**
18958
18969
  * Re-applies the toolbar's pre-interaction selection capture before the link
18959
18970
  * command runs. LinkInput executes the command directly (bypassing Toolbar.vue's
@@ -18974,8 +18985,11 @@ var LinkInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
18974
18985
  const props = __props;
18975
18986
  const { isHighContrastMode } = useHighContrastMode();
18976
18987
  const urlError = ref(false);
18988
+ const commandError = ref("");
18989
+ const isSubmitting = ref(false);
18977
18990
  const readSelectedText = () => {
18978
18991
  if (typeof props.hyperlinkText === "string" && props.hyperlinkText) return props.hyperlinkText;
18992
+ if (typeof props.selectedText === "string" && props.selectedText) return props.selectedText;
18979
18993
  const snapshot = props.ui?.selection?.getSnapshot?.();
18980
18994
  if (typeof snapshot?.quotedText === "string" && snapshot.quotedText) return snapshot.quotedText;
18981
18995
  const clickedText = props.clickedElement?.innerText ?? props.clickedElement?.textContent;
@@ -19006,7 +19020,7 @@ var LinkInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
19006
19020
  const validUrl = computed$1(() => sanitizedUrl.value !== null);
19007
19021
  const hadExistingLink = ref(false);
19008
19022
  const isEditing = computed$1(() => !isAnchor.value && hadExistingLink.value);
19009
- const isDisabled = computed$1(() => !validUrl.value);
19023
+ const isDisabled = computed$1(() => !validUrl.value || isSubmitting.value);
19010
19024
  const isViewingMode = computed$1(() => readDocumentMode() === "viewing");
19011
19025
  const openLink = () => {
19012
19026
  const href = sanitizedUrl.value?.href;
@@ -19025,20 +19039,36 @@ var LinkInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
19025
19039
  isAnchor.value = rawUrl.value.startsWith("#");
19026
19040
  if (props.showInput && !isViewingMode.value) focusInput();
19027
19041
  });
19028
- const runLinkCommand = (payload) => {
19042
+ const runLinkCommand = async (payload) => {
19029
19043
  const ui = props.ui;
19030
- if (!ui?.commands?.execute) return false;
19044
+ if (!ui?.commands?.executeAsync) return false;
19031
19045
  props.restoreSelection?.();
19032
- return ui.commands.execute("link", payload);
19046
+ return executeFirstPartyCommandAsync(ui, "link", payload);
19033
19047
  };
19034
- const handleSubmit = () => {
19035
- if (isViewingMode.value) return;
19048
+ const applyLinkCommand = async (payload) => {
19049
+ if (isSubmitting.value) return;
19050
+ isSubmitting.value = true;
19051
+ commandError.value = "";
19052
+ try {
19053
+ const result = await runLinkCommand(payload);
19054
+ if (result === false || result == null || typeof result === "object" && (result.success === false || result.status === "rejected")) {
19055
+ commandError.value = "Could not apply link. Check the selection and try again.";
19056
+ return;
19057
+ }
19058
+ props.closePopover();
19059
+ } catch {
19060
+ commandError.value = "Could not apply link. Check the selection and try again.";
19061
+ } finally {
19062
+ isSubmitting.value = false;
19063
+ }
19064
+ };
19065
+ const handleSubmit = async () => {
19066
+ if (isViewingMode.value || isSubmitting.value) return;
19036
19067
  if (!rawUrl.value) {
19037
- runLinkCommand({
19068
+ await applyLinkCommand({
19038
19069
  href: null,
19039
19070
  hyperlinkTarget: props.hyperlinkTarget
19040
19071
  });
19041
- props.closePopover();
19042
19072
  return;
19043
19073
  }
19044
19074
  if (!validUrl.value) {
@@ -19057,23 +19087,22 @@ var LinkInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
19057
19087
  textTarget: props.textTarget
19058
19088
  };
19059
19089
  if (text.value) payload.text = text.value;
19060
- else if (!isEditing.value) payload.text = href;
19061
- runLinkCommand(payload);
19062
- props.closePopover();
19090
+ else if (!isEditing.value && !props.textTarget) payload.text = href;
19091
+ await applyLinkCommand(payload);
19063
19092
  };
19064
- const handleRemove = () => {
19065
- runLinkCommand({
19093
+ const handleRemove = async () => {
19094
+ if (isViewingMode.value || isSubmitting.value) return;
19095
+ await applyLinkCommand({
19066
19096
  href: null,
19067
19097
  hyperlinkTarget: props.hyperlinkTarget
19068
19098
  });
19069
- props.closePopover();
19070
19099
  };
19071
19100
  const navigateToAnchor = (anchorUrl) => {
19072
19101
  if (props.goToAnchor) props.goToAnchor(anchorUrl);
19073
19102
  };
19074
19103
  return (_ctx, _cache) => {
19075
19104
  return openBlock(), createElementBlock("div", { class: normalizeClass(["link-input-ctn", { "high-contrast": unref(isHighContrastMode) }]) }, [isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_1$20, "Page anchor")) : isViewingMode.value ? (openBlock(), createElementBlock("div", _hoisted_2$16, "Link details")) : isEditing.value ? (openBlock(), createElementBlock("div", _hoisted_3$13, "Edit link")) : (openBlock(), createElementBlock("div", _hoisted_4$8, "Add link")), __props.showInput && !isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_5$6, [
19076
- createElementVNode("div", _hoisted_6$5, [_cache[4] || (_cache[4] = createElementVNode("div", { class: "input-icon text-input-icon" }, "T", -1)), withDirectives(createElementVNode("input", {
19105
+ createElementVNode("div", _hoisted_6$5, [_cache[5] || (_cache[5] = createElementVNode("div", { class: "input-icon text-input-icon" }, "T", -1)), withDirectives(createElementVNode("input", {
19077
19106
  type: "text",
19078
19107
  name: "text",
19079
19108
  placeholder: "Text",
@@ -19093,7 +19122,8 @@ var LinkInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
19093
19122
  class: normalizeClass({ "sd-error": urlError.value }),
19094
19123
  "onUpdate:modelValue": _cache[1] || (_cache[1] = ($event) => rawUrl.value = $event),
19095
19124
  readonly: isViewingMode.value,
19096
- onKeydown: [withKeys(withModifiers(handleSubmit, ["stop", "prevent"]), ["enter"]), _cache[2] || (_cache[2] = ($event) => urlError.value = false)]
19125
+ onInput: _cache[2] || (_cache[2] = ($event) => commandError.value = ""),
19126
+ onKeydown: [withKeys(withModifiers(handleSubmit, ["stop", "prevent"]), ["enter"]), _cache[3] || (_cache[3] = ($event) => urlError.value = false)]
19097
19127
  }, null, 42, _hoisted_10$2), [[vModelText, rawUrl.value]]),
19098
19128
  createElementVNode("div", {
19099
19129
  class: normalizeClass(["open-link-icon", { "sd-disabled": !validUrl.value }]),
@@ -19106,19 +19136,22 @@ var LinkInput_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
19106
19136
  key: 0,
19107
19137
  class: "remove-btn",
19108
19138
  onClick: handleRemove,
19139
+ disabled: isSubmitting.value,
19109
19140
  "data-item": "btn-link-remove"
19110
19141
  }, [createElementVNode("div", {
19111
19142
  class: "remove-btn__icon",
19112
19143
  innerHTML: unref(toolbarIcons).removeLink
19113
- }, null, 8, _hoisted_13$1), _cache[5] || (_cache[5] = createTextVNode(" Remove ", -1))])) : createCommentVNode("", true), createElementVNode("button", {
19144
+ }, null, 8, _hoisted_14$1), _cache[6] || (_cache[6] = createTextVNode(" Remove ", -1))], 8, _hoisted_13$1)) : createCommentVNode("", true), createElementVNode("button", {
19114
19145
  class: normalizeClass(["sd-submit-btn", { "disable-btn": isDisabled.value }]),
19115
19146
  onClick: handleSubmit,
19147
+ disabled: isSubmitting.value,
19116
19148
  "data-item": "btn-link-apply"
19117
- }, " Apply ", 2)])) : createCommentVNode("", true)
19118
- ])) : isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_14$1, [createElementVNode("a", { onClick: _cache[3] || (_cache[3] = withModifiers(($event) => navigateToAnchor(rawUrl.value), ["stop", "prevent"])) }, "Go to " + toDisplayString(rawUrl.value.startsWith("#_") ? rawUrl.value.substring(2) : rawUrl.value), 1)])) : createCommentVNode("", true)], 2);
19149
+ }, " Apply ", 10, _hoisted_15$1)])) : createCommentVNode("", true),
19150
+ commandError.value ? (openBlock(), createElementBlock("div", _hoisted_16$1, toDisplayString(commandError.value), 1)) : createCommentVNode("", true)
19151
+ ])) : isAnchor.value ? (openBlock(), createElementBlock("div", _hoisted_17$1, [createElementVNode("a", { onClick: _cache[4] || (_cache[4] = withModifiers(($event) => navigateToAnchor(rawUrl.value), ["stop", "prevent"])) }, "Go to " + toDisplayString(rawUrl.value.startsWith("#_") ? rawUrl.value.substring(2) : rawUrl.value), 1)])) : createCommentVNode("", true)], 2);
19119
19152
  };
19120
19153
  }
19121
- }, [["__scopeId", "data-v-3e4bd44e"]]);
19154
+ }, [["__scopeId", "data-v-498a6e6e"]]);
19122
19155
  //#endregion
19123
19156
  //#region src/internal/toolbar/built-in/scroll-helpers.js
19124
19157
  function getScrollableParent(element) {
@@ -22206,6 +22239,7 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
22206
22239
  return () => {
22207
22240
  const linkItem = toolbar.getToolbarItemByName("link");
22208
22241
  if (!linkItem || linkItem.disabled?.value === true) return;
22242
+ toolbar.pendingSelectionCapture = toolbar.ui?.selection?.capture?.() ?? null;
22209
22243
  if (linkItem.expand && typeof linkItem.expand === "object" && "value" in linkItem.expand) linkItem.expand.value = true;
22210
22244
  toolbar.updateToolbarState?.();
22211
22245
  };
@@ -24568,7 +24602,7 @@ var SuperDoc_default = /*#__PURE__*/ _plugin_vue_export_helper_default({
24568
24602
  ], 38);
24569
24603
  };
24570
24604
  }
24571
- }, [["__scopeId", "data-v-3a8bc935"]]);
24605
+ }, [["__scopeId", "data-v-f53aafe0"]]);
24572
24606
  //#endregion
24573
24607
  //#region src/core/create-app.js
24574
24608
  var PINIA_DEVTOOLS_SETUP_EVENT = "devtools-plugin:setup";
@@ -43910,16 +43944,18 @@ var makeDefaultItems = ({ superToolbar, toolbarIcons, toolbarTexts, toolbarFonts
43910
43944
  }
43911
43945
  });
43912
43946
  function renderLinkDropdown(link) {
43913
- const selection = currentSelectionSnapshot(superToolbar);
43914
- const selectionTarget = selection?.selectionTarget ?? selectionTargetFromTextTarget(selection?.target);
43947
+ const capture = superToolbar.pendingSelectionCapture;
43948
+ const liveSelection = currentSelectionSnapshot(superToolbar);
43949
+ const selection = liveSelection?.quotedText && JSON.stringify(liveSelection.selectionTarget ?? liveSelection.target) !== JSON.stringify(capture?.selectionTarget ?? capture?.target) ? liveSelection : capture ?? liveSelection;
43950
+ const selectionTarget = selection?.selectionTarget ?? selectionTargetFromTextTarget(selection?.target) ?? selection?.target;
43915
43951
  const restoreSelection = () => {
43916
- const capture = superToolbar.pendingSelectionCapture;
43917
- if (capture && typeof superToolbar.ui?.selection?.restore === "function") superToolbar.ui.selection.restore(capture);
43952
+ if (selection === capture && typeof superToolbar.ui?.selection?.restore === "function") superToolbar.ui.selection.restore(capture);
43918
43953
  };
43919
43954
  return h("div", {}, [h(LinkInput_default, {
43920
43955
  ui: superToolbar.ui,
43921
43956
  linkItem: link,
43922
43957
  textTarget: selectionTarget,
43958
+ selectedText: selection?.quotedText ?? null,
43923
43959
  restoreSelection,
43924
43960
  closePopover: () => {
43925
43961
  closeDropdown(link);
@@ -46362,7 +46398,7 @@ var SuperDoc = class extends import_eventemitter3.default {
46362
46398
  }
46363
46399
  this.userColorMap = /* @__PURE__ */ new Map();
46364
46400
  this.colorIndex = 0;
46365
- this.version = "2.23.0-next.8";
46401
+ this.version = "2.23.0";
46366
46402
  this.#log("🦋 [superdoc] Using SuperDoc version:", this.version);
46367
46403
  this.superdocId = config.superdocId || v4();
46368
46404
  this.colors = this.config.colors ?? [];