rme 0.3.0-beta.6 → 0.3.0-beta.8

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/index.mjs CHANGED
@@ -890,9 +890,22 @@ var WysiwygThemeWrapper = styled.div.attrs((p) => ({
890
890
  color: ${(props) => props.theme.labelFontColor};
891
891
  }
892
892
 
893
- .md-mark {
894
- color: ${(props) => props.theme.accentColor};
895
- font-size: 0;
893
+ & .inline-loading {
894
+ width: min-content;
895
+ height: min-content;
896
+ display: inline-block;
897
+ font-size: 16px;
898
+ line-height: ${(props) => props.rootLineHeight};
899
+ animation: loading-icon-spin 1s linear infinite;
900
+ }
901
+
902
+ @keyframes loading-icon-spin {
903
+ 0% {
904
+ transform: rotate(0deg);
905
+ }
906
+ 100% {
907
+ transform: rotate(360deg);
908
+ }
896
909
  }
897
910
 
898
911
  .html_tag {
@@ -1263,8 +1276,9 @@ var WysiwygThemeWrapper = styled.div.attrs((p) => ({
1263
1276
 
1264
1277
  & .html-image-node-view-wrapper,
1265
1278
  & .md-image-node-view-wrapper {
1266
- display: inline-block;
1279
+ display: inline-flex;
1267
1280
  padding: 0 2px;
1281
+ vertical-align: bottom;
1268
1282
  z-index: 1;
1269
1283
  }
1270
1284
 
@@ -3798,40 +3812,6 @@ var LineBlockquoteExtension = class extends BlockquoteExtension {
3798
3812
  // src/editor/extensions/Clipboard/clipboard-extension.ts
3799
3813
  import { extension as extension2, PlainExtension as PlainExtension2 } from "@rme-sdk/core";
3800
3814
  import { DOMParser as DOMParser2, Fragment as Fragment3, Slice } from "@rme-sdk/pm/model";
3801
-
3802
- // src/editor/inline-input-regex/index.ts
3803
- var getMdImageInputRule = (nodeType) => [
3804
- {
3805
- regexp: /!\[([^\]]*)\]\(([^\s"]+(?:\s+[^\s"]+)*)?(?:\s+"(.*?)")?\)/,
3806
- type: nodeType,
3807
- getAttributes: (match) => {
3808
- const [, alt, src, title] = match;
3809
- return { alt, src, title };
3810
- }
3811
- }
3812
- ];
3813
- var getInlineMathInputRule = (nodeType) => [
3814
- // Typed inline math trigger: $$ -> insert empty inline math and focus inside
3815
- {
3816
- regexp: /\$\$(?!\$)/,
3817
- type: nodeType,
3818
- getAttributes: () => ({ tex: "", fromInput: true })
3819
- },
3820
- {
3821
- regexp: /<span[^>]*data-type=["']math-inline["'][^>]*><\/span>/,
3822
- type: nodeType,
3823
- getAttributes: () => ({ fromInput: false })
3824
- },
3825
- {
3826
- regexp: /\$([^$\n]+?)\$/,
3827
- type: nodeType,
3828
- getAttributes: (match) => {
3829
- return { tex: match[1] ?? "", fromInput: true };
3830
- }
3831
- }
3832
- ];
3833
-
3834
- // src/editor/extensions/Clipboard/clipboard-extension.ts
3835
3815
  function isPureText(content) {
3836
3816
  if (!content) return false;
3837
3817
  if (Array.isArray(content)) {
@@ -3876,21 +3856,21 @@ var ClipboardExtension = class extends PlainExtension2 {
3876
3856
  if (html2.length === 0) {
3877
3857
  const slice2 = parser?.(text);
3878
3858
  if (!slice2 || typeof slice2 === "string") return false;
3879
- const res = [];
3859
+ const nodes = [];
3880
3860
  slice2.content.forEach((node2, index) => {
3881
3861
  if (node2.type.name === "paragraph" && index === 0) {
3882
3862
  node2.content.forEach((child) => {
3883
- res.push(child);
3863
+ nodes.push(child);
3884
3864
  });
3885
3865
  } else {
3886
- res.push(node2);
3866
+ nodes.push(node2);
3887
3867
  }
3888
3868
  });
3889
- this.processImagesInNodesAsync(res, view);
3890
- if (res.length === 1) {
3891
- view.dispatch(view.state.tr.replaceSelectionWith(res[0], false));
3869
+ this.processImagesInNodesSync(nodes, view);
3870
+ if (nodes.length === 1) {
3871
+ view.dispatch(view.state.tr.replaceSelectionWith(nodes[0], false));
3892
3872
  } else {
3893
- const fragment = Fragment3.from(res);
3873
+ const fragment = Fragment3.from(nodes);
3894
3874
  view.dispatch(view.state.tr.replaceSelection(new Slice(fragment, 0, 0)));
3895
3875
  }
3896
3876
  return true;
@@ -3902,16 +3882,9 @@ var ClipboardExtension = class extends PlainExtension2 {
3902
3882
  }
3903
3883
  const slice = domParser.parseSlice(dom);
3904
3884
  const node = isTextOnlySlice(slice);
3905
- console.log("slice", slice, node);
3906
3885
  if (node) {
3907
- if ((node.type.name === "html_image" || node.type.name === "md_image") && node.attrs.src) {
3908
- this.processImageNode(node, view);
3909
- view.dispatch(view.state.tr.replaceSelectionWith(node, true));
3910
- } else {
3911
- this.processMarkdownImageSyntax(node, view).then(() => {
3912
- view.dispatch(view.state.tr.replaceSelectionWith(node, true));
3913
- });
3914
- }
3886
+ node.attrs["data-rme-from-paste"] = "true";
3887
+ view.dispatch(view.state.tr.replaceSelectionWith(node, true));
3915
3888
  return true;
3916
3889
  }
3917
3890
  this.processImagesInSliceAsync(slice, view);
@@ -3991,60 +3964,16 @@ var ClipboardExtension = class extends PlainExtension2 {
3991
3964
  }
3992
3965
  };
3993
3966
  }
3994
- /**
3995
- * Process markdown image syntax in text nodes and update their src attributes using imageCopyHandler
3996
- */
3997
- async processMarkdownImageSyntax(node, view) {
3998
- const { imageCopyHandler } = this.options;
3999
- if (!imageCopyHandler) return;
4000
- const imageRegex = new RegExp(getMdImageInputRule("md_image")[0]?.regexp, "g");
4001
- const processTextNode = async (n) => {
4002
- if (n.isText && n.text) {
4003
- let match;
4004
- imageRegex.lastIndex = 0;
4005
- while ((match = imageRegex.exec(n.text)) !== null) {
4006
- const [, , src] = match;
4007
- if (src) {
4008
- const newSrc = await imageCopyHandler(src);
4009
- if (newSrc && newSrc !== src) {
4010
- n.text = n.text.replace(src, newSrc);
4011
- }
4012
- }
4013
- }
4014
- }
4015
- if (n.content && n.content.size > 0) {
4016
- n.content.forEach((child) => {
4017
- processTextNode(child);
4018
- });
4019
- }
4020
- };
4021
- await processTextNode(node);
4022
- }
4023
3967
  /**
4024
3968
  * Process a single image node asynchronously and update its src attribute using imageCopyHandler
4025
3969
  */
4026
3970
  processImageNode(node, view) {
4027
- const { imageCopyHandler } = this.options;
4028
- if (!imageCopyHandler || !node.attrs.src) return;
4029
- node.attrs["data-rme-loading"] = "true";
4030
- imageCopyHandler(node.attrs.src).then((newSrc) => {
4031
- if (newSrc && newSrc !== node.attrs.src) {
4032
- this.updateImageNodeSrc(view, node, newSrc);
4033
- }
4034
- }).catch((error) => {
4035
- console.warn("imageCopyHandler failed:", error);
4036
- }).finally(() => {
4037
- const { state, dispatch } = view;
4038
- node.attrs["data-rme-loading"] = null;
4039
- dispatch(state.tr);
4040
- });
3971
+ node.attrs["data-rme-from-paste"] = "true";
4041
3972
  }
4042
3973
  /**
4043
3974
  * Process images in a slice asynchronously and update their src attributes using imageCopyHandler
4044
3975
  */
4045
3976
  processImagesInSliceAsync(slice, view) {
4046
- const { imageCopyHandler } = this.options;
4047
- if (!imageCopyHandler) return;
4048
3977
  const imageNodes = [];
4049
3978
  let currentPos = 0;
4050
3979
  const findImageNodes = (node, pos) => {
@@ -4060,18 +3989,16 @@ var ClipboardExtension = class extends PlainExtension2 {
4060
3989
  slice.content.forEach((node, offset) => {
4061
3990
  findImageNodes(node, currentPos + offset);
4062
3991
  });
4063
- imageNodes.forEach(({ node, pos }) => {
3992
+ imageNodes.map(({ node, pos }) => {
4064
3993
  if (node.attrs.src) {
4065
- this.processImageNode(node, view);
3994
+ return this.processImageNode(node, view);
4066
3995
  }
4067
3996
  });
4068
3997
  }
4069
3998
  /**
4070
3999
  * Process images in an array of nodes asynchronously and update their src attributes using imageCopyHandler
4071
4000
  */
4072
- processImagesInNodesAsync(nodes, view) {
4073
- const { imageCopyHandler } = this.options;
4074
- if (!imageCopyHandler) return;
4001
+ processImagesInNodesSync(nodes, view) {
4075
4002
  const processNode = (node) => {
4076
4003
  if ((node.type.name === "html_image" || node.type.name === "md_image") && node.attrs.src) {
4077
4004
  this.processImageNode(node, view);
@@ -4084,16 +4011,6 @@ var ClipboardExtension = class extends PlainExtension2 {
4084
4011
  };
4085
4012
  nodes.forEach(processNode);
4086
4013
  }
4087
- /**
4088
- * Update image node src attribute in the document
4089
- */
4090
- updateImageNodeSrc(view, node, newSrc) {
4091
- const { state, dispatch } = view;
4092
- let tr = state.tr;
4093
- node.attrs.src = newSrc;
4094
- node.attrs["data-rme-loading"] = null;
4095
- dispatch(tr);
4096
- }
4097
4014
  };
4098
4015
  ClipboardExtension = __decorateClass([
4099
4016
  extension2({
@@ -4425,13 +4342,57 @@ FindExtension = __decorateClass([
4425
4342
 
4426
4343
  // src/editor/extensions/HandleInput/handle-input-extension.ts
4427
4344
  import { PlainExtension as PlainExtension4 } from "@rme-sdk/core";
4345
+
4346
+ // src/editor/inline-input-regex/index.ts
4347
+ var getMdImageInputRule = (nodeType) => [
4348
+ {
4349
+ regexp: /!\[([^\]]*)\]\(([^\s"]+(?:\s+[^\s"]+)*)?(?:\s+"(.*?)")?\)/,
4350
+ type: nodeType,
4351
+ getAttributes: (match) => {
4352
+ const [, alt, src, title] = match;
4353
+ return { alt, src, title };
4354
+ }
4355
+ }
4356
+ ];
4357
+ var getHtmlImageInputRule = (nodeType) => [
4358
+ {
4359
+ regexp: new RegExp("<img[^>]*>"),
4360
+ type: nodeType,
4361
+ getAttributes: (match) => {
4362
+ return getAttrsBySignalHtmlContent(match[0]);
4363
+ }
4364
+ }
4365
+ ];
4366
+ var getInlineMathInputRule = (nodeType) => [
4367
+ // Typed inline math trigger: $$ -> insert empty inline math and focus inside
4368
+ {
4369
+ regexp: /\$\$(?!\$)/,
4370
+ type: nodeType,
4371
+ getAttributes: () => ({ tex: "", fromInput: true })
4372
+ },
4373
+ {
4374
+ regexp: /<span[^>]*data-type=["']math-inline["'][^>]*><\/span>/,
4375
+ type: nodeType,
4376
+ getAttributes: () => ({ fromInput: false })
4377
+ },
4378
+ {
4379
+ regexp: /\$([^$\n]+?)\$/,
4380
+ type: nodeType,
4381
+ getAttributes: (match) => {
4382
+ return { tex: match[1] ?? "", fromInput: true };
4383
+ }
4384
+ }
4385
+ ];
4386
+
4387
+ // src/editor/extensions/HandleInput/handle-input-extension.ts
4428
4388
  var excludeNodeName = ["math_block", "codeMirror"];
4429
4389
  var HandleInputExtension = class extends PlainExtension4 {
4430
4390
  constructor(options) {
4431
4391
  super();
4432
4392
  this.inputRules = [
4433
4393
  ...getMdImageInputRule("md_image"),
4434
- ...getInlineMathInputRule("math_inline")
4394
+ ...getInlineMathInputRule("math_inline"),
4395
+ ...getHtmlImageInputRule("html_image")
4435
4396
  ];
4436
4397
  if (options?.rules) {
4437
4398
  this.inputRules = [...this.inputRules, ...options.rules];
@@ -4491,7 +4452,11 @@ var HandleInputExtension = class extends PlainExtension4 {
4491
4452
  const start = pos + matchIndex;
4492
4453
  const end = start + match[0].length;
4493
4454
  if (start >= 0 && end <= newState.doc.content.size) {
4455
+ console.log("nodenode", node);
4494
4456
  const attrs = rule6.getAttributes ? rule6.getAttributes(match) : null;
4457
+ if (node.attrs["data-rme-from-paste"] === "true" && attrs) {
4458
+ attrs["data-rme-from-paste"] = "true";
4459
+ }
4495
4460
  const nodeType = schema.nodes[rule6.type];
4496
4461
  if (!nodeType) {
4497
4462
  console.warn(`Node type '${rule6.type}' not found in schema`);
@@ -5516,7 +5481,7 @@ var throttle = (delay, noTrailing, callback) => {
5516
5481
  };
5517
5482
  };
5518
5483
  var ResizableContainer = styled6.div`
5519
- display: inline-block;
5484
+ display: inline-flex;
5520
5485
  position: relative;
5521
5486
  max-width: 100%;
5522
5487
  user-select: none;
@@ -6633,6 +6598,8 @@ var Container2 = styled9.div`
6633
6598
  border: 1px solid ${(props) => props.theme.borderColor};
6634
6599
  border-radius: ${(props) => props.theme.smallBorderRadius};
6635
6600
  box-shadow: 0 4px 12px ${(props) => props.theme.boxShadowColor};
6601
+ font-size: ${(props) => props.theme.fontBase};
6602
+ line-height: normal;
6636
6603
  z-index: 100;
6637
6604
  `;
6638
6605
  var InputGroup = styled9.div`
@@ -6814,12 +6781,44 @@ var ImageToolTips = (props) => {
6814
6781
 
6815
6782
  // src/editor/extensions/Image/image-nodeview.tsx
6816
6783
  import { jsx as jsx14 } from "react/jsx-runtime";
6817
- var warningFallBack = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAAAAACIM/FCAAAChElEQVR4Ae3aMW/TQBxAcb70k91AAiGuGlZAtOlQApWaDiSdklZq2RPUTm1xUWL3PgqSpygkXlh88N54nn7S2Trd3y/CP5IQIUKECBEiRIgQIUKECBEiRIgQIUKECBEiRIgQIUKECBEiRIgQIUKECBEiRIgQIUKECBEiRIgQIUKECPmPIEKECBEiRIgQIeX82+FBO0naB4eTRRkt5P7sNWt1Rw9RQvKThI2SYR4f5OoVW2rfRAYpT6hqHc8WeVHki9mgRdWwiAmyfA9AdrlaW5tlAHxcxQMpK8feRbGxPEkrSREN5ARg/y780V0GMIwFcgXwLg9byvsAN3FA8lfAfr7jYQZ0nqKAfAb21vYVwNruSoEvMUDuE+Ai7IKECZA+RAA5A7JiN6TMgFHzIeUb4DLshoQZ0H1uPGQOvFzVQZYtYNF4yBg4DnWQMAAmjYccArN6yBQ4ajzkAFjUQ+ZAv/GQNpDXQ3Kg03hIAhT1kAJIhLi1/vJl39Ic6Mf3+a2K8PM7BgahtgEwjuKI0lqGjSI8opRdYFb3sk/jODSGEZCVuyFFDzgPzYc8JMBkN2QMpI8RQMIQ2LvdBblNgdM4Lh/aQJaHrf3sAe2nKCDhGqCfb3VEcx1UNQTItlzQ3fYAvoZYIMUHgHRSbiyPU4BPZUSX2JWEbLZcW5v2qByrmMYKxZCq1mA6z4sin08HLapOy8gGPddtttT5HuHobZiwUXr6K85h6KjLWm/PH+MdTy/GR/12knb6g8mPZ38YECJEiBAhQoQIESJEiBAhQoQIESJEiBAhQoQIESJEiBAhQoQIESJEiBAhQoQIESJEiBAhQoQIESJEiBAhQoQIESJEiBAh0fUb5q7oCGreEVEAAAAASUVORK5CYII=";
6818
6784
  function ImageNodeView(props) {
6819
- const { node, selected, updateAttributes, handleViewImgSrcUrl, imageHostingHandler } = props;
6785
+ const {
6786
+ node,
6787
+ selected,
6788
+ updateAttributes,
6789
+ handleViewImgSrcUrl,
6790
+ imageCopyHandler,
6791
+ imageHostingHandler
6792
+ } = props;
6820
6793
  const initRef = useRef7(null);
6821
6794
  const popoverStore = useRef7(null);
6822
6795
  const popoverRef = useRef7(null);
6796
+ const fromPaste = node.attrs["data-rme-from-paste"] === "true";
6797
+ console.log("fromPaste", fromPaste, node);
6798
+ useEffect6(() => {
6799
+ if (fromPaste) {
6800
+ const handlePasteEvent = async () => {
6801
+ let src = node.attrs.src || "";
6802
+ if (imageCopyHandler) {
6803
+ try {
6804
+ src = await imageCopyHandler(node.attrs.src);
6805
+ } catch (error) {
6806
+ }
6807
+ }
6808
+ if (handleViewImgSrcUrl) {
6809
+ try {
6810
+ src = await handleViewImgSrcUrl(src);
6811
+ } catch (error) {
6812
+ }
6813
+ }
6814
+ updateAttributes({
6815
+ "data-rme-from-paste": null,
6816
+ src
6817
+ });
6818
+ };
6819
+ handlePasteEvent();
6820
+ }
6821
+ }, [fromPaste, handleViewImgSrcUrl, imageCopyHandler, node.attrs.src]);
6823
6822
  const handleStoreChange = (store) => {
6824
6823
  popoverStore.current = store;
6825
6824
  };
@@ -6841,6 +6840,10 @@ function ImageNodeView(props) {
6841
6840
  ["data-rme-type"]: "html"
6842
6841
  });
6843
6842
  }, [updateAttributes]);
6843
+ const Loading = /* @__PURE__ */ jsx14("span", { className: "inline-loading", children: /* @__PURE__ */ jsx14("i", { className: "inline-loading-icon ri-loader-4-line" }) });
6844
+ if (fromPaste) {
6845
+ return Loading;
6846
+ }
6844
6847
  const Main = /* @__PURE__ */ jsx14(
6845
6848
  Resizable,
6846
6849
  {
@@ -6852,37 +6855,18 @@ function ImageNodeView(props) {
6852
6855
  {
6853
6856
  onLoad: () => initRef.current?.(),
6854
6857
  src: node.attrs.src,
6855
- imgPromise: (src) => {
6856
- return new Promise((resolve, reject) => {
6857
- if (node.attrs["data-rme-loading"] === "true") {
6858
- return;
6859
- }
6860
- const makeImageLoad = (targetSrc) => {
6861
- const img = new Image();
6862
- img.src = targetSrc;
6863
- img.onload = () => {
6864
- resolve(targetSrc);
6865
- };
6866
- img.onerror = () => {
6867
- reject(warningFallBack);
6868
- };
6869
- };
6870
- if (handleViewImgSrcUrl) {
6871
- handleViewImgSrcUrl(node.attrs.src).then((newSrc) => {
6872
- makeImageLoad(newSrc);
6873
- });
6874
- } else {
6875
- makeImageLoad(node.attrs.src);
6876
- }
6877
- });
6858
+ loader: Loading,
6859
+ style: {
6860
+ width: "100%",
6861
+ height: "100%"
6878
6862
  },
6879
6863
  ...node.attrs
6880
- },
6881
- `${node.attrs.src}_${node.attrs["data-rme-loading"]}`
6864
+ }
6882
6865
  )
6883
- }
6866
+ },
6867
+ `${node.attrs.src}_${node.attrs["data-rme-loading"]}`
6884
6868
  );
6885
- return /* @__PURE__ */ jsx14("div", { ref: popoverRef, style: { position: "relative", zIndex: selected ? 10 : "auto" }, children: /* @__PURE__ */ jsx14(
6869
+ return /* @__PURE__ */ jsx14("div", { ref: popoverRef, style: { position: "relative", zIndex: selected ? 10 : "auto", lineHeight: 0 }, children: /* @__PURE__ */ jsx14(
6886
6870
  Popover2,
6887
6871
  {
6888
6872
  customContent: /* @__PURE__ */ jsx14(
@@ -6897,6 +6881,11 @@ function ImageNodeView(props) {
6897
6881
  },
6898
6882
  `${node.attrs.src}`
6899
6883
  ),
6884
+ boxProps: {
6885
+ style: {
6886
+ display: "inline-flex"
6887
+ }
6888
+ },
6900
6889
  placement: "top-start",
6901
6890
  onStoreChange: handleStoreChange,
6902
6891
  toggleOnClick: true,
@@ -6912,8 +6901,16 @@ var HtmlImageExtension = class extends NodeExtension6 {
6912
6901
  constructor() {
6913
6902
  super(...arguments);
6914
6903
  this.ReactComponent = (props) => {
6915
- const { handleViewImgSrcUrl, imageHostingHandler } = this.options;
6916
- return /* @__PURE__ */ jsx15(ImageNodeView, { handleViewImgSrcUrl, imageHostingHandler, ...props });
6904
+ const { handleViewImgSrcUrl, imageHostingHandler, imageCopyHandler } = this.options;
6905
+ return /* @__PURE__ */ jsx15(
6906
+ ImageNodeView,
6907
+ {
6908
+ handleViewImgSrcUrl,
6909
+ imageCopyHandler,
6910
+ imageHostingHandler,
6911
+ ...props
6912
+ }
6913
+ );
6917
6914
  };
6918
6915
  }
6919
6916
  get name() {
@@ -6939,7 +6936,8 @@ var HtmlImageExtension = class extends NodeExtension6 {
6939
6936
  src: { default: null },
6940
6937
  title: { default: "" },
6941
6938
  "data-file-name": { default: null },
6942
- "data-rme-loading": { default: null }
6939
+ "data-rme-loading": { default: null },
6940
+ "data-rme-from-paste": { default: null }
6943
6941
  },
6944
6942
  parseDOM: [
6945
6943
  {
@@ -7047,16 +7045,7 @@ var HtmlImageExtension = class extends NodeExtension6 {
7047
7045
  ];
7048
7046
  }
7049
7047
  createInputRules() {
7050
- const rules = [
7051
- nodeInputRule5({
7052
- regexp: new RegExp("<img[^>]*>"),
7053
- type: this.type,
7054
- getAttributes: (match) => {
7055
- return getAttrsBySignalHtmlContent(match[0]);
7056
- }
7057
- })
7058
- ];
7059
- return rules;
7048
+ return getHtmlImageInputRule(this.type).map(nodeInputRule5);
7060
7049
  }
7061
7050
  fromMarkdown() {
7062
7051
  return [
@@ -7170,12 +7159,13 @@ var MdImgUriExtension = class extends NodeExtension7 {
7170
7159
  constructor() {
7171
7160
  super(...arguments);
7172
7161
  this.ReactComponent = (props) => {
7173
- const { handleViewImgSrcUrl, imageHostingHandler } = this.options;
7162
+ const { handleViewImgSrcUrl, imageHostingHandler, imageCopyHandler } = this.options;
7174
7163
  return /* @__PURE__ */ jsx16(
7175
7164
  ImageNodeView,
7176
7165
  {
7177
7166
  handleViewImgSrcUrl,
7178
7167
  imageHostingHandler,
7168
+ imageCopyHandler,
7179
7169
  ...props
7180
7170
  }
7181
7171
  );
@@ -7204,7 +7194,8 @@ var MdImgUriExtension = class extends NodeExtension7 {
7204
7194
  rotate: { default: null },
7205
7195
  src: { default: null },
7206
7196
  title: { default: "" },
7207
- "data-file-name": { default: null }
7197
+ "data-file-name": { default: null },
7198
+ "data-rme-from-paste": { default: null }
7208
7199
  },
7209
7200
  parseDOM: [
7210
7201
  {
@@ -10267,11 +10258,13 @@ function extensions(options) {
10267
10258
  new CountExtension({}),
10268
10259
  new HtmlImageExtension({
10269
10260
  handleViewImgSrcUrl,
10270
- imageHostingHandler
10261
+ imageHostingHandler,
10262
+ imageCopyHandler
10271
10263
  }),
10272
10264
  new MdImgUriExtension({
10273
10265
  handleViewImgSrcUrl,
10274
- imageHostingHandler
10266
+ imageHostingHandler,
10267
+ imageCopyHandler
10275
10268
  }),
10276
10269
  new HandleInputExtension(),
10277
10270
  new HtmlBrExtension(),