rme 0.3.0-beta.6 → 0.3.0-beta.7

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,21 @@ 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
+ animation: loading-icon-spin 1s linear infinite;
899
+ }
900
+
901
+ @keyframes loading-icon-spin {
902
+ 0% {
903
+ transform: rotate(0deg);
904
+ }
905
+ 100% {
906
+ transform: rotate(360deg);
907
+ }
896
908
  }
897
909
 
898
910
  .html_tag {
@@ -3798,40 +3810,6 @@ var LineBlockquoteExtension = class extends BlockquoteExtension {
3798
3810
  // src/editor/extensions/Clipboard/clipboard-extension.ts
3799
3811
  import { extension as extension2, PlainExtension as PlainExtension2 } from "@rme-sdk/core";
3800
3812
  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
3813
  function isPureText(content) {
3836
3814
  if (!content) return false;
3837
3815
  if (Array.isArray(content)) {
@@ -3876,21 +3854,21 @@ var ClipboardExtension = class extends PlainExtension2 {
3876
3854
  if (html2.length === 0) {
3877
3855
  const slice2 = parser?.(text);
3878
3856
  if (!slice2 || typeof slice2 === "string") return false;
3879
- const res = [];
3857
+ const nodes = [];
3880
3858
  slice2.content.forEach((node2, index) => {
3881
3859
  if (node2.type.name === "paragraph" && index === 0) {
3882
3860
  node2.content.forEach((child) => {
3883
- res.push(child);
3861
+ nodes.push(child);
3884
3862
  });
3885
3863
  } else {
3886
- res.push(node2);
3864
+ nodes.push(node2);
3887
3865
  }
3888
3866
  });
3889
- this.processImagesInNodesAsync(res, view);
3890
- if (res.length === 1) {
3891
- view.dispatch(view.state.tr.replaceSelectionWith(res[0], false));
3867
+ this.processImagesInNodesSync(nodes, view);
3868
+ if (nodes.length === 1) {
3869
+ view.dispatch(view.state.tr.replaceSelectionWith(nodes[0], false));
3892
3870
  } else {
3893
- const fragment = Fragment3.from(res);
3871
+ const fragment = Fragment3.from(nodes);
3894
3872
  view.dispatch(view.state.tr.replaceSelection(new Slice(fragment, 0, 0)));
3895
3873
  }
3896
3874
  return true;
@@ -3902,16 +3880,9 @@ var ClipboardExtension = class extends PlainExtension2 {
3902
3880
  }
3903
3881
  const slice = domParser.parseSlice(dom);
3904
3882
  const node = isTextOnlySlice(slice);
3905
- console.log("slice", slice, node);
3906
3883
  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
- }
3884
+ node.attrs["data-rme-from-paste"] = "true";
3885
+ view.dispatch(view.state.tr.replaceSelectionWith(node, true));
3915
3886
  return true;
3916
3887
  }
3917
3888
  this.processImagesInSliceAsync(slice, view);
@@ -3991,60 +3962,16 @@ var ClipboardExtension = class extends PlainExtension2 {
3991
3962
  }
3992
3963
  };
3993
3964
  }
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
3965
  /**
4024
3966
  * Process a single image node asynchronously and update its src attribute using imageCopyHandler
4025
3967
  */
4026
3968
  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
- });
3969
+ node.attrs["data-rme-from-paste"] = "true";
4041
3970
  }
4042
3971
  /**
4043
3972
  * Process images in a slice asynchronously and update their src attributes using imageCopyHandler
4044
3973
  */
4045
3974
  processImagesInSliceAsync(slice, view) {
4046
- const { imageCopyHandler } = this.options;
4047
- if (!imageCopyHandler) return;
4048
3975
  const imageNodes = [];
4049
3976
  let currentPos = 0;
4050
3977
  const findImageNodes = (node, pos) => {
@@ -4060,18 +3987,16 @@ var ClipboardExtension = class extends PlainExtension2 {
4060
3987
  slice.content.forEach((node, offset) => {
4061
3988
  findImageNodes(node, currentPos + offset);
4062
3989
  });
4063
- imageNodes.forEach(({ node, pos }) => {
3990
+ imageNodes.map(({ node, pos }) => {
4064
3991
  if (node.attrs.src) {
4065
- this.processImageNode(node, view);
3992
+ return this.processImageNode(node, view);
4066
3993
  }
4067
3994
  });
4068
3995
  }
4069
3996
  /**
4070
3997
  * Process images in an array of nodes asynchronously and update their src attributes using imageCopyHandler
4071
3998
  */
4072
- processImagesInNodesAsync(nodes, view) {
4073
- const { imageCopyHandler } = this.options;
4074
- if (!imageCopyHandler) return;
3999
+ processImagesInNodesSync(nodes, view) {
4075
4000
  const processNode = (node) => {
4076
4001
  if ((node.type.name === "html_image" || node.type.name === "md_image") && node.attrs.src) {
4077
4002
  this.processImageNode(node, view);
@@ -4084,16 +4009,6 @@ var ClipboardExtension = class extends PlainExtension2 {
4084
4009
  };
4085
4010
  nodes.forEach(processNode);
4086
4011
  }
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
4012
  };
4098
4013
  ClipboardExtension = __decorateClass([
4099
4014
  extension2({
@@ -4425,13 +4340,57 @@ FindExtension = __decorateClass([
4425
4340
 
4426
4341
  // src/editor/extensions/HandleInput/handle-input-extension.ts
4427
4342
  import { PlainExtension as PlainExtension4 } from "@rme-sdk/core";
4343
+
4344
+ // src/editor/inline-input-regex/index.ts
4345
+ var getMdImageInputRule = (nodeType) => [
4346
+ {
4347
+ regexp: /!\[([^\]]*)\]\(([^\s"]+(?:\s+[^\s"]+)*)?(?:\s+"(.*?)")?\)/,
4348
+ type: nodeType,
4349
+ getAttributes: (match) => {
4350
+ const [, alt, src, title] = match;
4351
+ return { alt, src, title };
4352
+ }
4353
+ }
4354
+ ];
4355
+ var getHtmlImageInputRule = (nodeType) => [
4356
+ {
4357
+ regexp: new RegExp("<img[^>]*>"),
4358
+ type: nodeType,
4359
+ getAttributes: (match) => {
4360
+ return getAttrsBySignalHtmlContent(match[0]);
4361
+ }
4362
+ }
4363
+ ];
4364
+ var getInlineMathInputRule = (nodeType) => [
4365
+ // Typed inline math trigger: $$ -> insert empty inline math and focus inside
4366
+ {
4367
+ regexp: /\$\$(?!\$)/,
4368
+ type: nodeType,
4369
+ getAttributes: () => ({ tex: "", fromInput: true })
4370
+ },
4371
+ {
4372
+ regexp: /<span[^>]*data-type=["']math-inline["'][^>]*><\/span>/,
4373
+ type: nodeType,
4374
+ getAttributes: () => ({ fromInput: false })
4375
+ },
4376
+ {
4377
+ regexp: /\$([^$\n]+?)\$/,
4378
+ type: nodeType,
4379
+ getAttributes: (match) => {
4380
+ return { tex: match[1] ?? "", fromInput: true };
4381
+ }
4382
+ }
4383
+ ];
4384
+
4385
+ // src/editor/extensions/HandleInput/handle-input-extension.ts
4428
4386
  var excludeNodeName = ["math_block", "codeMirror"];
4429
4387
  var HandleInputExtension = class extends PlainExtension4 {
4430
4388
  constructor(options) {
4431
4389
  super();
4432
4390
  this.inputRules = [
4433
4391
  ...getMdImageInputRule("md_image"),
4434
- ...getInlineMathInputRule("math_inline")
4392
+ ...getInlineMathInputRule("math_inline"),
4393
+ ...getHtmlImageInputRule("html_image")
4435
4394
  ];
4436
4395
  if (options?.rules) {
4437
4396
  this.inputRules = [...this.inputRules, ...options.rules];
@@ -4491,7 +4450,11 @@ var HandleInputExtension = class extends PlainExtension4 {
4491
4450
  const start = pos + matchIndex;
4492
4451
  const end = start + match[0].length;
4493
4452
  if (start >= 0 && end <= newState.doc.content.size) {
4453
+ console.log("nodenode", node);
4494
4454
  const attrs = rule6.getAttributes ? rule6.getAttributes(match) : null;
4455
+ if (node.attrs["data-rme-from-paste"] === "true" && attrs) {
4456
+ attrs["data-rme-from-paste"] = "true";
4457
+ }
4495
4458
  const nodeType = schema.nodes[rule6.type];
4496
4459
  if (!nodeType) {
4497
4460
  console.warn(`Node type '${rule6.type}' not found in schema`);
@@ -6816,10 +6779,43 @@ var ImageToolTips = (props) => {
6816
6779
  import { jsx as jsx14 } from "react/jsx-runtime";
6817
6780
  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
6781
  function ImageNodeView(props) {
6819
- const { node, selected, updateAttributes, handleViewImgSrcUrl, imageHostingHandler } = props;
6782
+ const {
6783
+ node,
6784
+ selected,
6785
+ updateAttributes,
6786
+ handleViewImgSrcUrl,
6787
+ imageCopyHandler,
6788
+ imageHostingHandler
6789
+ } = props;
6820
6790
  const initRef = useRef7(null);
6821
6791
  const popoverStore = useRef7(null);
6822
6792
  const popoverRef = useRef7(null);
6793
+ const fromPaste = node.attrs["data-rme-from-paste"] === "true";
6794
+ console.log("fromPaste", fromPaste, node);
6795
+ useEffect6(() => {
6796
+ if (fromPaste) {
6797
+ const handlePasteEvent = async () => {
6798
+ let src = node.attrs.src || "";
6799
+ if (imageCopyHandler) {
6800
+ try {
6801
+ src = await imageCopyHandler(node.attrs.src);
6802
+ } catch (error) {
6803
+ }
6804
+ }
6805
+ if (handleViewImgSrcUrl) {
6806
+ try {
6807
+ src = await handleViewImgSrcUrl(src);
6808
+ } catch (error) {
6809
+ }
6810
+ }
6811
+ updateAttributes({
6812
+ "data-rme-from-paste": null,
6813
+ src
6814
+ });
6815
+ };
6816
+ handlePasteEvent();
6817
+ }
6818
+ }, [fromPaste, node.attrs.src]);
6823
6819
  const handleStoreChange = (store) => {
6824
6820
  popoverStore.current = store;
6825
6821
  };
@@ -6841,47 +6837,41 @@ function ImageNodeView(props) {
6841
6837
  ["data-rme-type"]: "html"
6842
6838
  });
6843
6839
  }, [updateAttributes]);
6844
- const Main = /* @__PURE__ */ jsx14(
6845
- Resizable,
6840
+ const Loading = /* @__PURE__ */ jsx14("span", { className: "inline-loading", children: /* @__PURE__ */ jsx14("i", { className: "inline-loading-icon ri-loader-4-line" }) });
6841
+ if (fromPaste) {
6842
+ return Loading;
6843
+ }
6844
+ const Main = /* @__PURE__ */ jsx14(Resizable, { controlInit: (init) => initRef.current = init, onResize: handleResize, ...props, children: /* @__PURE__ */ jsx14(
6845
+ ZensImage,
6846
6846
  {
6847
- controlInit: (init) => initRef.current = init,
6848
- onResize: handleResize,
6849
- ...props,
6850
- children: /* @__PURE__ */ jsx14(
6851
- ZensImage,
6852
- {
6853
- onLoad: () => initRef.current?.(),
6854
- 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
- }
6847
+ onLoad: () => initRef.current?.(),
6848
+ src: node.attrs.src,
6849
+ loader: Loading,
6850
+ imgPromise: (src) => {
6851
+ return new Promise((resolve, reject) => {
6852
+ const makeImageLoad = (targetSrc) => {
6853
+ const img = new Image();
6854
+ img.src = targetSrc;
6855
+ img.onload = () => {
6856
+ resolve(targetSrc);
6857
+ };
6858
+ img.onerror = () => {
6859
+ reject(warningFallBack);
6860
+ };
6861
+ };
6862
+ if (handleViewImgSrcUrl) {
6863
+ handleViewImgSrcUrl(node.attrs.src).then((newSrc) => {
6864
+ makeImageLoad(newSrc);
6877
6865
  });
6878
- },
6879
- ...node.attrs
6880
- },
6881
- `${node.attrs.src}_${node.attrs["data-rme-loading"]}`
6882
- )
6883
- }
6884
- );
6866
+ } else {
6867
+ makeImageLoad(node.attrs.src);
6868
+ }
6869
+ });
6870
+ },
6871
+ ...node.attrs
6872
+ },
6873
+ `${node.attrs.src}_${node.attrs["data-rme-loading"]}`
6874
+ ) });
6885
6875
  return /* @__PURE__ */ jsx14("div", { ref: popoverRef, style: { position: "relative", zIndex: selected ? 10 : "auto" }, children: /* @__PURE__ */ jsx14(
6886
6876
  Popover2,
6887
6877
  {
@@ -6912,8 +6902,16 @@ var HtmlImageExtension = class extends NodeExtension6 {
6912
6902
  constructor() {
6913
6903
  super(...arguments);
6914
6904
  this.ReactComponent = (props) => {
6915
- const { handleViewImgSrcUrl, imageHostingHandler } = this.options;
6916
- return /* @__PURE__ */ jsx15(ImageNodeView, { handleViewImgSrcUrl, imageHostingHandler, ...props });
6905
+ const { handleViewImgSrcUrl, imageHostingHandler, imageCopyHandler } = this.options;
6906
+ return /* @__PURE__ */ jsx15(
6907
+ ImageNodeView,
6908
+ {
6909
+ handleViewImgSrcUrl,
6910
+ imageCopyHandler,
6911
+ imageHostingHandler,
6912
+ ...props
6913
+ }
6914
+ );
6917
6915
  };
6918
6916
  }
6919
6917
  get name() {
@@ -6939,7 +6937,8 @@ var HtmlImageExtension = class extends NodeExtension6 {
6939
6937
  src: { default: null },
6940
6938
  title: { default: "" },
6941
6939
  "data-file-name": { default: null },
6942
- "data-rme-loading": { default: null }
6940
+ "data-rme-loading": { default: null },
6941
+ "data-rme-from-paste": { default: null }
6943
6942
  },
6944
6943
  parseDOM: [
6945
6944
  {
@@ -7047,16 +7046,7 @@ var HtmlImageExtension = class extends NodeExtension6 {
7047
7046
  ];
7048
7047
  }
7049
7048
  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;
7049
+ return getHtmlImageInputRule(this.type).map(nodeInputRule5);
7060
7050
  }
7061
7051
  fromMarkdown() {
7062
7052
  return [
@@ -7170,12 +7160,13 @@ var MdImgUriExtension = class extends NodeExtension7 {
7170
7160
  constructor() {
7171
7161
  super(...arguments);
7172
7162
  this.ReactComponent = (props) => {
7173
- const { handleViewImgSrcUrl, imageHostingHandler } = this.options;
7163
+ const { handleViewImgSrcUrl, imageHostingHandler, imageCopyHandler } = this.options;
7174
7164
  return /* @__PURE__ */ jsx16(
7175
7165
  ImageNodeView,
7176
7166
  {
7177
7167
  handleViewImgSrcUrl,
7178
7168
  imageHostingHandler,
7169
+ imageCopyHandler,
7179
7170
  ...props
7180
7171
  }
7181
7172
  );
@@ -7204,7 +7195,8 @@ var MdImgUriExtension = class extends NodeExtension7 {
7204
7195
  rotate: { default: null },
7205
7196
  src: { default: null },
7206
7197
  title: { default: "" },
7207
- "data-file-name": { default: null }
7198
+ "data-file-name": { default: null },
7199
+ "data-rme-from-paste": { default: null }
7208
7200
  },
7209
7201
  parseDOM: [
7210
7202
  {
@@ -10267,11 +10259,13 @@ function extensions(options) {
10267
10259
  new CountExtension({}),
10268
10260
  new HtmlImageExtension({
10269
10261
  handleViewImgSrcUrl,
10270
- imageHostingHandler
10262
+ imageHostingHandler,
10263
+ imageCopyHandler
10271
10264
  }),
10272
10265
  new MdImgUriExtension({
10273
10266
  handleViewImgSrcUrl,
10274
- imageHostingHandler
10267
+ imageHostingHandler,
10268
+ imageCopyHandler
10275
10269
  }),
10276
10270
  new HandleInputExtension(),
10277
10271
  new HtmlBrExtension(),