@threadlabs/looma 0.28.14 → 0.28.16

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.
@@ -3,7 +3,7 @@ import "./looma-editor.css";
3
3
  import { type AnyExtension, type Editor, type JSONContent } from "@tiptap/core";
4
4
  import { type PropType, type VNode } from "vue";
5
5
  import { type LoomaSlashCommand, type LoomaMentionItem, type LoomaMentionProvider, type LoomaCodeLanguages } from "@threadlabs/looma/editor";
6
- import { type LoomaImageActivationDetail, type LoomaImageAttributeResolver, type LoomaImageDescriptor, type LoomaImageRenditionErrorDetail } from "../../editor/image-delivery.js";
6
+ import { type LoomaImageActivationDetail, type LoomaImageAttributeResolver, type LoomaImageSourceResolver, type LoomaImageDescriptor, type LoomaImageRenditionErrorDetail } from "../../editor/image-delivery.js";
7
7
  import { type LoomaLinkResolve, type LoomaLinkSearch } from "../../editor/link-editing.js";
8
8
  /**
9
9
  * Host upload result normalized into the editor's durable image descriptor.
@@ -162,6 +162,10 @@ export declare const LoomaEditor: import("vue").DefineComponent<import("vue").Ex
162
162
  type: PropType<LoomaImageAttributeResolver | undefined>;
163
163
  default: undefined;
164
164
  };
165
+ resolveImageSource: {
166
+ type: PropType<LoomaImageSourceResolver | undefined>;
167
+ default: undefined;
168
+ };
165
169
  toolbarMode: {
166
170
  type: PropType<LoomaEditorToolbarMode>;
167
171
  default: string;
@@ -300,6 +304,10 @@ export declare const LoomaEditor: import("vue").DefineComponent<import("vue").Ex
300
304
  type: PropType<LoomaImageAttributeResolver | undefined>;
301
305
  default: undefined;
302
306
  };
307
+ resolveImageSource: {
308
+ type: PropType<LoomaImageSourceResolver | undefined>;
309
+ default: undefined;
310
+ };
303
311
  toolbarMode: {
304
312
  type: PropType<LoomaEditorToolbarMode>;
305
313
  default: string;
@@ -369,6 +377,7 @@ export declare const LoomaEditor: import("vue").DefineComponent<import("vue").Ex
369
377
  linkTargetLabel: string;
370
378
  uploadImage: LoomaImageUploader | undefined;
371
379
  resolveImageAttributes: LoomaImageAttributeResolver | undefined;
380
+ resolveImageSource: LoomaImageSourceResolver | undefined;
372
381
  toolbarMode: LoomaEditorToolbarMode;
373
382
  compactToolbar: boolean;
374
383
  selectionActions: LoomaEditorSelectionAction[];
@@ -1,4 +1,4 @@
1
1
  export * from "@threadlabs/looma/editor";
2
2
  export * from "./primitives.js";
3
3
  export { LoomaEditor, type LoomaEditorToolbarMode, type LoomaEditorSelectionAction, type LoomaEditorSelectionActionDetail, type LoomaEditorRangeAction, type LoomaEditorRangeActionDetail, type LoomaEditorSlashCommands, type LoomaLinkTarget, type LoomaLinkSearch, type LoomaLinkResolve, type LoomaImageUploader, type LoomaImageUploadResult, } from "./LoomaEditor.js";
4
- export type { LoomaImageActivationDetail, LoomaImageActivationTrigger, LoomaImageAttributeResolver, LoomaImageDescriptor, LoomaImageRenditionErrorDetail, LoomaImageRenditionAttributes, } from "../../editor/image-delivery.js";
4
+ export type { LoomaImageActivationDetail, LoomaImageActivationTrigger, LoomaImageAttributeResolver, LoomaImageSourceResolver, LoomaImageDescriptor, LoomaImageRenditionErrorDetail, LoomaImageRenditionAttributes, } from "../../editor/image-delivery.js";
@@ -705,20 +705,27 @@ function imageDescriptorFromAttrs(attrs) {
705
705
  ...attrs.responsive === true ? { responsive: true } : {}
706
706
  };
707
707
  }
708
- function transientAttributes(resolver, image, editable) {
708
+ function transientAttributes(resolveSource, resolver, image, editable) {
709
+ let masterSource = image.src;
710
+ try {
711
+ masterSource = optionalString(resolveSource?.({ ...image })) ?? masterSource;
712
+ } catch {}
709
713
  const attributes = {
710
714
  ...editable ? {} : {
711
715
  "aria-label": image.alt ? `Open image: ${image.alt}` : "Open image",
712
716
  role: "button"
713
717
  },
714
718
  "data-looma-image": "",
715
- src: image.src,
719
+ src: masterSource,
716
720
  tabindex: editable ? "-1" : "0"
717
721
  };
718
722
  if (!image.responsive || !resolver) return attributes;
719
723
  let rendition;
720
724
  try {
721
- rendition = resolver(image);
725
+ rendition = resolver({
726
+ ...image,
727
+ src: masterSource
728
+ });
722
729
  } catch {
723
730
  return attributes;
724
731
  }
@@ -740,10 +747,10 @@ function transientAttributes(resolver, image, editable) {
740
747
  "high",
741
748
  "low"
742
749
  ].includes(rendition.fetchPriority ?? "")) attributes.fetchpriority = rendition.fetchPriority;
743
- if (src && src !== image.src || srcset) attributes["data-looma-rendition"] = "true";
750
+ if (src && src !== masterSource || srcset) attributes["data-looma-rendition"] = "true";
744
751
  return attributes;
745
752
  }
746
- function createDecorations(doc, resolver, failedRenditions, editable) {
753
+ function createDecorations(doc, resolveSource, resolver, failedRenditions, editable) {
747
754
  const decorations = [];
748
755
  const currentSources = /* @__PURE__ */ new Set();
749
756
  doc.descendants((node, position) => {
@@ -751,7 +758,7 @@ function createDecorations(doc, resolver, failedRenditions, editable) {
751
758
  const image = imageDescriptorFromAttrs(node.attrs);
752
759
  if (!image) return;
753
760
  currentSources.add(image.src);
754
- decorations.push(Decoration.node(position, position + node.nodeSize, {}, { loomaImageAttributes: transientAttributes(failedRenditions.has(image.src) ? void 0 : resolver, image, editable) }));
761
+ decorations.push(Decoration.node(position, position + node.nodeSize, {}, { loomaImageAttributes: transientAttributes(resolveSource, failedRenditions.has(image.src) ? void 0 : resolver, image, editable) }));
755
762
  });
756
763
  for (const src of failedRenditions) if (!currentSources.has(src)) failedRenditions.delete(src);
757
764
  return DecorationSet.create(doc, decorations);
@@ -789,10 +796,10 @@ function createLoomaImageDeliveryController(options) {
789
796
  return [new Plugin({
790
797
  key: pluginKey,
791
798
  state: {
792
- init: (_, state) => createDecorations(state.doc, options.resolveAttributes(), failedRenditions, options.isEditable()),
799
+ init: (_, state) => createDecorations(state.doc, options.resolveSource?.(), options.resolveAttributes(), failedRenditions, options.isEditable()),
793
800
  apply: (transaction, previous) => {
794
801
  if (!transaction.getMeta(pluginKey) && !transactionChangesImages(transaction)) return previous.map(transaction.mapping, transaction.doc);
795
- return createDecorations(transaction.doc, options.resolveAttributes(), failedRenditions, options.isEditable());
802
+ return createDecorations(transaction.doc, options.resolveSource?.(), options.resolveAttributes(), failedRenditions, options.isEditable());
796
803
  }
797
804
  },
798
805
  props: { decorations: (state) => pluginKey.getState(state) }
@@ -2643,7 +2650,7 @@ var imageNodeView = ({ editor, node, getPos, decorations }) => {
2643
2650
  const attrs = current.value.attrs;
2644
2651
  const transient = Object.assign({}, ...delivery.value.map((decoration) => decoration.spec.loomaImageAttributes ?? {}));
2645
2652
  return h(Image, {
2646
- src: attrs.src,
2653
+ src: transient.src ?? attrs.src,
2647
2654
  alt: attrs.alt ?? "",
2648
2655
  width: attrs.width,
2649
2656
  height: attrs.height,
@@ -2857,6 +2864,10 @@ var LoomaEditor = defineComponent({
2857
2864
  type: Function,
2858
2865
  default: void 0
2859
2866
  },
2867
+ resolveImageSource: {
2868
+ type: Function,
2869
+ default: void 0
2870
+ },
2860
2871
  toolbarMode: {
2861
2872
  type: String,
2862
2873
  default: "bubble"
@@ -3094,6 +3105,7 @@ var LoomaEditor = defineComponent({
3094
3105
  }
3095
3106
  });
3096
3107
  const imageDelivery = createLoomaImageDeliveryController({
3108
+ resolveSource: () => props.resolveImageSource,
3097
3109
  resolveAttributes: () => props.resolveImageAttributes,
3098
3110
  isEditable: () => props.editable
3099
3111
  });
@@ -3142,6 +3154,7 @@ var LoomaEditor = defineComponent({
3142
3154
  content: props.modelValue,
3143
3155
  editable: props.editable,
3144
3156
  editorProps: {
3157
+ nodeViews: { image: () => ({ dom: document.createElement("span") }) },
3145
3158
  attributes: {
3146
3159
  role: "textbox",
3147
3160
  "aria-multiline": "true",
@@ -3193,6 +3206,7 @@ var LoomaEditor = defineComponent({
3193
3206
  emit("update", value);
3194
3207
  }
3195
3208
  }, Editor$1);
3209
+ delete session.editor.options.editorProps.nodeViews;
3196
3210
  session.subscribe(() => {
3197
3211
  editorStateVersion.value += 1;
3198
3212
  });
@@ -3318,7 +3332,7 @@ var LoomaEditor = defineComponent({
3318
3332
  watch(() => props.editable, (editable) => {
3319
3333
  formatting?.press.cancel();
3320
3334
  formatting?.release();
3321
- editor.value?.setEditable(editable);
3335
+ editor.value?.setEditable(editable, false);
3322
3336
  if (!editable) formattingPopup?.hide();
3323
3337
  if (editor.value) imageDelivery.reset(editor.value);
3324
3338
  root.value?.querySelectorAll("[data-looma-chip]").forEach((chip) => {
@@ -3346,7 +3360,7 @@ var LoomaEditor = defineComponent({
3346
3360
  "aria-label": label
3347
3361
  } } });
3348
3362
  });
3349
- watch(() => props.resolveImageAttributes, () => {
3363
+ watch([() => props.resolveImageAttributes, () => props.resolveImageSource], () => {
3350
3364
  const instance = editor.value;
3351
3365
  if (instance) imageDelivery.reset(instance);
3352
3366
  });