markdown-wysiwyg-editor 0.2.5 → 0.2.6

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/README.md CHANGED
@@ -1,5 +1,8 @@
1
1
  # markdown-wysiwyg-editor
2
2
 
3
+ [![npm version](https://badge.fury.io/js/markdown-wysiwyg-editor.svg)](https://badge.fury.io/js/markdown-wysiwyg-editor)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
3
6
  Lightweight Markdown WYSIWYG editor for React, powered by TipTap.
4
7
 
5
8
  [Live Demo](https://wysiwyg-doc.com/markdown-wysiwyg/index.html)
@@ -1 +1 @@
1
- {"version":3,"file":"EmojiPicker.d.ts","sourceRoot":"","sources":["../../src/components/EmojiPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAiB/B,UAAU,gBAAgB;IACxB,uCAAuC;IACvC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,0CAA0C;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wCAAwC;IACxC,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CAC/C;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAwKlD,CAAC"}
1
+ {"version":3,"file":"EmojiPicker.d.ts","sourceRoot":"","sources":["../../src/components/EmojiPicker.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAiB/B,UAAU,gBAAgB;IACxB,uCAAuC;IACvC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,0CAA0C;IAC1C,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,wCAAwC;IACxC,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;CAC/C;AAED,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAuKlD,CAAC"}
@@ -13,6 +13,8 @@ interface LinkContextMenuProps {
13
13
  linkData: {
14
14
  href: string;
15
15
  text: string;
16
+ from?: number;
17
+ to?: number;
16
18
  } | null;
17
19
  onClose: () => void;
18
20
  onOpenLink: (href: string) => void;
@@ -1 +1 @@
1
- {"version":3,"file":"LinkContextMenu.d.ts","sourceRoot":"","sources":["../../src/components/LinkContextMenu.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,UAAU,oBAAoB;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;KACd,GAAG,IAAI,CAAC;IACT,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,UAAU,EAAE,CAAC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAChE;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAkN1D,CAAC"}
1
+ {"version":3,"file":"LinkContextMenu.d.ts","sourceRoot":"","sources":["../../src/components/LinkContextMenu.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAO/B,UAAU,oBAAoB;IAC5B,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,EAAE,CAAC,EAAE,MAAM,CAAC;KACb,GAAG,IAAI,CAAC;IACT,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,UAAU,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,UAAU,EAAE,CAAC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAChE;AAED,eAAO,MAAM,eAAe,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAkN1D,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownEditor.d.ts","sourceRoot":"","sources":["../../src/components/MarkdownEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AA0BhE,OAAO,EAAa,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAetE,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAkczD,CAAC"}
1
+ {"version":3,"file":"MarkdownEditor.d.ts","sourceRoot":"","sources":["../../src/components/MarkdownEditor.tsx"],"names":[],"mappings":"AAAA,OAAO,KAA2C,MAAM,OAAO,CAAC;AA0BhE,OAAO,EAAa,KAAK,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAetE,eAAO,MAAM,cAAc,EAAE,KAAK,CAAC,EAAE,CAAC,oBAAoB,CAwczD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"HeadingMenu.d.ts","sourceRoot":"","sources":["../../../src/components/toolbar/HeadingMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAIzD,UAAU,gBAAgB;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,CAAC,EAAE,UAAU,CAAC;CACf;AAwCD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CAyGlD,CAAC"}
1
+ {"version":3,"file":"HeadingMenu.d.ts","sourceRoot":"","sources":["../../../src/components/toolbar/HeadingMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,wBAAwB,CAAC;AAIzD,UAAU,gBAAgB;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,EAAE,MAAM,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,gBAAgB,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,CAAC,EAAE,UAAU,CAAC;CACf;AAwCD,eAAO,MAAM,WAAW,EAAE,KAAK,CAAC,EAAE,CAAC,gBAAgB,CA+FlD,CAAC"}
@@ -3,5 +3,7 @@ import type React from 'react';
3
3
  export declare const createLinkClickExtension: (handleContextMenu: (event: React.MouseEvent, linkData: {
4
4
  href: string;
5
5
  text: string;
6
+ from: number;
7
+ to: number;
6
8
  }) => void) => Extension<any, any>;
7
9
  //# sourceMappingURL=LinkClickExtension.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"LinkClickExtension.d.ts","sourceRoot":"","sources":["../../src/extensions/LinkClickExtension.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,eAAO,MAAM,wBAAwB,GACnC,mBAAmB,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,EAAE,QAAQ,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,KAAK,IAAI,wBA2D5F,CAAC"}
1
+ {"version":3,"file":"LinkClickExtension.d.ts","sourceRoot":"","sources":["../../src/extensions/LinkClickExtension.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAgB,MAAM,cAAc,CAAC;AAEvD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,eAAO,MAAM,wBAAwB,GACnC,mBAAmB,CACjB,KAAK,EAAE,KAAK,CAAC,UAAU,EACvB,QAAQ,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAA;CAAE,KAC/D,IAAI,wBA0FP,CAAC"}
@@ -7,6 +7,8 @@ export interface LinkContextMenuState {
7
7
  linkData: {
8
8
  href: string;
9
9
  text: string;
10
+ from: number;
11
+ to: number;
10
12
  } | null;
11
13
  }
12
14
  export interface TableContextMenuState {
@@ -22,6 +24,8 @@ export declare const useEditorContextMenus: () => {
22
24
  handleLinkContextMenu: (event: React.MouseEvent, linkData: {
23
25
  href: string;
24
26
  text: string;
27
+ from: number;
28
+ to: number;
25
29
  }) => void;
26
30
  handleTableContextMenu: (event: React.MouseEvent) => void;
27
31
  handleCloseLinkContextMenu: () => void;
@@ -1 +1 @@
1
- {"version":3,"file":"useEditorContextMenus.d.ts","sourceRoot":"","sources":["../../src/hooks/useEditorContextMenus.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CACjD;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACpC;AAED,eAAO,MAAM,qBAAqB;;;mCAatB,KAAK,CAAC,UAAU,YAAY;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE;oCAajB,KAAK,CAAC,UAAU;;;CA2DpE,CAAC"}
1
+ {"version":3,"file":"useEditorContextMenus.d.ts","sourceRoot":"","sources":["../../src/hooks/useEditorContextMenus.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnC,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;CAC3E;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CACpC;AAED,eAAO,MAAM,qBAAqB;;;mCAcrB,KAAK,CAAC,UAAU,YACb;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE;oCAcnB,KAAK,CAAC,UAAU;;;CA2DpE,CAAC"}
@@ -23,6 +23,8 @@ interface UseMarkdownEditorProps {
23
23
  handleLinkContextMenu: (event: React.MouseEvent, linkData: {
24
24
  href: string;
25
25
  text: string;
26
+ from: number;
27
+ to: number;
26
28
  }) => void;
27
29
  handleTableContextMenu: (event: React.MouseEvent) => void;
28
30
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useMarkdownEditor.d.ts","sourceRoot":"","sources":["../../src/hooks/useMarkdownEditor.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,WAAW,EAAa,MAAM,eAAe,CAAC;AAYzE,OAAO,EAAE,KAAK,cAAc,EAAkB,MAAM,yBAAyB,CAAC;AAI9E,UAAU,sBAAsB;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;IACxD,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,CAAC,YAAY,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,qBAAqB,EAAE,CAAC,QAAQ,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAChF,gBAAgB,EAAE,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,KAAK,IAAI,CAAC;IACxD,UAAU,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAC3C,qBAAqB,EAAE,CACrB,KAAK,EAAE,KAAK,CAAC,UAAU,EACvB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KACrC,IAAI,CAAC;IACV,sBAAsB,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;CAC3D;AAKD,eAAO,MAAM,iBAAiB,GAAI,wSAmB/B,sBAAsB,WAuJxB,CAAC"}
1
+ {"version":3,"file":"useMarkdownEditor.d.ts","sourceRoot":"","sources":["../../src/hooks/useMarkdownEditor.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,MAAM,EAAE,KAAK,WAAW,EAAa,MAAM,eAAe,CAAC;AAczE,OAAO,EAAE,KAAK,cAAc,EAAkB,MAAM,yBAAyB,CAAC;AAI9E,UAAU,sBAAsB;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,OAAO,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IACjD,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC9C,iBAAiB,CAAC,EAAE,CAAC,SAAS,EAAE,cAAc,KAAK,IAAI,CAAC;IACxD,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACzC,UAAU,EAAE,OAAO,CAAC;IACpB,YAAY,EAAE,OAAO,CAAC;IACtB,eAAe,EAAE,CAAC,YAAY,EAAE,OAAO,KAAK,IAAI,CAAC;IACjD,qBAAqB,EAAE,CAAC,QAAQ,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IAChF,gBAAgB,EAAE,CAAC,IAAI,EAAE,cAAc,GAAG,IAAI,KAAK,IAAI,CAAC;IACxD,UAAU,EAAE,CAAC,OAAO,EAAE,WAAW,KAAK,IAAI,CAAC;IAC3C,qBAAqB,EAAE,CACrB,KAAK,EAAE,KAAK,CAAC,UAAU,EACvB,QAAQ,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,EAAE,EAAE,MAAM,CAAA;KAAE,KAC/D,IAAI,CAAC;IACV,sBAAsB,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;CAC3D;AAKD,eAAO,MAAM,iBAAiB,GAAI,wSAmB/B,sBAAsB,WA2JxB,CAAC"}
package/dist/index.js CHANGED
@@ -38998,6 +38998,9 @@ class HastEmitter {
38998
38998
  return "";
38999
38999
  }
39000
39000
  }
39001
+ // src/hooks/useMarkdownEditor.ts
39002
+ import { useRef as useRef3 } from "react";
39003
+
39001
39004
  // src/converters/JsonToMarkdownConverter.ts
39002
39005
  var log = createLogger("JsonToMarkdownConverter");
39003
39006
 
@@ -40406,37 +40409,63 @@ var createLinkClickExtension = (handleContextMenu) => Extension.create({
40406
40409
  key: new PluginKey("linkClick"),
40407
40410
  props: {
40408
40411
  handleDOMEvents: {
40409
- contextmenu: (_, event) => {
40412
+ contextmenu: (view, event) => {
40410
40413
  const target = event.target;
40411
40414
  const linkElement = target.closest("a[href]");
40412
40415
  if (linkElement) {
40413
40416
  const href = linkElement.getAttribute("href") || "";
40414
40417
  const text = linkElement.textContent || "";
40415
- logger.debug("\uD83D\uDD17 Link right-clicked:", { href, text });
40418
+ const pos = view.posAtDOM(linkElement, 0);
40419
+ if (pos < 0)
40420
+ return false;
40421
+ const $pos = view.state.doc.resolve(pos);
40422
+ const markRange = getMarkRange($pos, view.state.schema.marks.link, { href });
40423
+ const from2 = markRange?.from ?? pos;
40424
+ const to = markRange?.to ?? pos + text.length;
40425
+ logger.debug("\uD83D\uDD17 Link right-clicked:", { href, text, from: from2, to });
40416
40426
  if (href) {
40417
- handleContextMenu(event, { href, text });
40427
+ handleContextMenu(event, {
40428
+ href,
40429
+ text,
40430
+ from: from2,
40431
+ to
40432
+ });
40418
40433
  return true;
40419
40434
  }
40420
40435
  }
40421
40436
  return false;
40422
40437
  },
40423
- click: (_, event) => {
40438
+ click: (view, event) => {
40424
40439
  const target = event.target;
40425
40440
  const linkElement = target.closest("a[href]");
40426
40441
  if (linkElement) {
40427
40442
  const href = linkElement.getAttribute("href") || "";
40428
40443
  const text = linkElement.textContent || "";
40444
+ const pos = view.posAtDOM(linkElement, 0);
40445
+ if (pos < 0)
40446
+ return false;
40447
+ const $pos = view.state.doc.resolve(pos);
40448
+ const markRange = getMarkRange($pos, view.state.schema.marks.link, { href });
40449
+ const from2 = markRange?.from ?? pos;
40450
+ const to = markRange?.to ?? pos + text.length;
40429
40451
  logger.debug("\uD83D\uDD17 Link clicked:", {
40430
40452
  href,
40431
40453
  text,
40432
40454
  ctrlKey: event.ctrlKey,
40433
40455
  metaKey: event.metaKey,
40434
- shiftKey: event.shiftKey
40456
+ shiftKey: event.shiftKey,
40457
+ from: from2,
40458
+ to
40435
40459
  });
40436
40460
  if (href) {
40437
40461
  event.preventDefault();
40438
40462
  event.stopPropagation();
40439
- handleContextMenu(event, { href, text });
40463
+ handleContextMenu(event, {
40464
+ href,
40465
+ text,
40466
+ from: from2,
40467
+ to
40468
+ });
40440
40469
  return true;
40441
40470
  }
40442
40471
  }
@@ -41176,7 +41205,9 @@ var handleMarkdownPaste = async ({
41176
41205
  markdownToTipTapOptions
41177
41206
  }) => {
41178
41207
  editor.commands.deleteSelection();
41208
+ const startPos = editor.state.selection.from;
41179
41209
  insertPlainText(editor, plainText);
41210
+ const endPos = editor.state.selection.from;
41180
41211
  if (plainText.length >= largeTextThreshold) {
41181
41212
  logger2.info("\uD83D\uDCCB Large text detected - keeping as plain text to prevent performance issues");
41182
41213
  return;
@@ -41185,17 +41216,19 @@ var handleMarkdownPaste = async ({
41185
41216
  setIsProcessing(true);
41186
41217
  setProcessingProgress({ processed: 0, total: plainText.split(`
41187
41218
  `).length });
41188
- const currentPos = editor.state.selection.from;
41189
- const insertionStart = currentPos - plainText.length;
41190
41219
  try {
41191
- editor.commands.deleteRange({ from: insertionStart, to: currentPos });
41192
- editor.commands.setTextSelection(insertionStart);
41193
- await MarkdownTipTapConverter.processMarkdownInSmallChunksWithRender(plainText, editor, (processed, total) => {
41194
- setProcessingProgress({ processed, total });
41195
- }, markdownToTipTapOptions);
41220
+ if (endPos > startPos) {
41221
+ editor.commands.deleteRange({ from: startPos, to: endPos });
41222
+ editor.commands.setTextSelection(startPos);
41223
+ await MarkdownTipTapConverter.processMarkdownInSmallChunksWithRender(plainText, editor, (processed, total) => {
41224
+ setProcessingProgress({ processed, total });
41225
+ }, markdownToTipTapOptions);
41226
+ } else {
41227
+ logger2.warn("⚠️ Nothing inserted or invalid range detected");
41228
+ }
41196
41229
  } catch (error) {
41197
41230
  logger2.warn("⚠️ Sequential rendering failed, keeping plain text:", error);
41198
- editor.commands.setTextSelection(insertionStart);
41231
+ editor.commands.setTextSelection(startPos);
41199
41232
  insertPlainText(editor, plainText);
41200
41233
  } finally {
41201
41234
  editor.__isProcessing = false;
@@ -41522,6 +41555,7 @@ var useMarkdownEditor = ({
41522
41555
  handleTableContextMenu
41523
41556
  }) => {
41524
41557
  const lowlight = createLowlight(grammars);
41558
+ const lastEmittedDocRef = useRef3(null);
41525
41559
  const editor = useEditor({
41526
41560
  enableContentCheck: false,
41527
41561
  emitContentError: true,
@@ -41598,39 +41632,39 @@ var useMarkdownEditor = ({
41598
41632
  if (isUpdating || editor2.__preventUpdate || isProcessing) {
41599
41633
  return;
41600
41634
  }
41635
+ const { doc: doc3 } = editor2.state;
41601
41636
  const json2 = editor2.getJSON();
41602
41637
  setContent2(json2);
41603
41638
  if (onContentChange) {
41604
41639
  onContentChange(json2);
41605
41640
  }
41606
- if (onChange) {
41607
- try {
41608
- const markdown2 = JsonToMarkdownConverter_default.convertToMarkdown(json2);
41609
- onChange(markdown2);
41610
- } catch (error) {
41611
- logger3.warn("⚠️ Markdown conversion failed in onUpdate:", error);
41612
- }
41613
- }
41614
- if (onMarkdownChange) {
41641
+ if (onChange || onMarkdownChange) {
41615
41642
  try {
41616
41643
  const markdown2 = JsonToMarkdownConverter_default.convertToMarkdown(json2);
41617
- onMarkdownChange(markdown2);
41644
+ if (onChange)
41645
+ onChange(markdown2);
41646
+ if (onMarkdownChange)
41647
+ onMarkdownChange(markdown2);
41648
+ lastEmittedDocRef.current = doc3;
41618
41649
  } catch (error) {
41619
41650
  logger3.warn("⚠️ Markdown conversion failed in onUpdate:", error);
41620
41651
  }
41621
41652
  }
41622
41653
  },
41623
41654
  onBlur: ({ editor: editor2 }) => {
41624
- if (onMarkdownChange) {
41655
+ if (lastEmittedDocRef.current && editor2.state.doc.eq(lastEmittedDocRef.current)) {
41656
+ return;
41657
+ }
41658
+ const hasListeners = onChange || onMarkdownChange;
41659
+ if (hasListeners) {
41625
41660
  try {
41626
41661
  const json2 = editor2.getJSON();
41627
41662
  const markdown2 = JsonToMarkdownConverter_default.convertToMarkdown(json2);
41628
- if (onChange) {
41663
+ if (onChange)
41629
41664
  onChange(markdown2);
41630
- }
41631
- if (onMarkdownChange) {
41665
+ if (onMarkdownChange)
41632
41666
  onMarkdownChange(markdown2);
41633
- }
41667
+ lastEmittedDocRef.current = editor2.state.doc;
41634
41668
  } catch (error) {
41635
41669
  logger3.warn("⚠️ Markdown conversion failed in onBlur:", error);
41636
41670
  }
@@ -42265,7 +42299,7 @@ var MarkdownSyntaxStatus = ({
42265
42299
  import React7 from "react";
42266
42300
 
42267
42301
  // src/components/EmojiPicker.tsx
42268
- import { useEffect as useEffect9, useMemo as useMemo2, useRef as useRef3, useState as useState10 } from "react";
42302
+ import { useEffect as useEffect9, useMemo as useMemo2, useRef as useRef4, useState as useState10 } from "react";
42269
42303
 
42270
42304
  // src/constants/emojiData.ts
42271
42305
  var EMOJI_CATEGORIES = [
@@ -42769,7 +42803,7 @@ var EmojiPicker = ({
42769
42803
  }) => {
42770
42804
  const [activeGroup, setActiveGroup] = useState10("smileys_people");
42771
42805
  const [query, setQuery] = useState10("");
42772
- const pickerRef = useRef3(null);
42806
+ const pickerRef = useRef4(null);
42773
42807
  useEffect9(() => {
42774
42808
  const handleClickOutside = (event) => {
42775
42809
  if (pickerRef.current && !pickerRef.current.contains(event.target)) {
@@ -42811,11 +42845,10 @@ var EmojiPicker = ({
42811
42845
  const g = EMOJI_CATEGORY_GROUPS.find((x) => x.id === activeGroup);
42812
42846
  return g?.categories ?? [];
42813
42847
  }, [activeGroup]);
42814
- return /* @__PURE__ */ jsxDEV8("dialog", {
42848
+ return /* @__PURE__ */ jsxDEV8("div", {
42815
42849
  ref: pickerRef,
42816
- className: "mw-emoji-picker bg-popover text-popover-foreground border border-border shadow-xl rounded-xl",
42850
+ className: "mw-emoji-picker bg-popover text-popover-foreground border border-border shadow-lg ring-1 ring-black ring-opacity-5 rounded-[calc(var(--radius)+4px)]",
42817
42851
  "aria-label": t(I18N_KEYS.emoji.pickerTitle, "Emoji picker"),
42818
- open: true,
42819
42852
  children: [
42820
42853
  /* @__PURE__ */ jsxDEV8("div", {
42821
42854
  className: "mw-emoji-search",
@@ -42917,7 +42950,7 @@ var EmojiPicker = ({
42917
42950
  };
42918
42951
 
42919
42952
  // src/components/ImagePicker.tsx
42920
- import { useEffect as useEffect10, useRef as useRef4, useState as useState11 } from "react";
42953
+ import { useEffect as useEffect10, useRef as useRef5, useState as useState11 } from "react";
42921
42954
  import { jsxDEV as jsxDEV9 } from "react/jsx-dev-runtime";
42922
42955
  var ImagePicker = ({
42923
42956
  onInsertMarkdown,
@@ -42927,7 +42960,7 @@ var ImagePicker = ({
42927
42960
  }) => {
42928
42961
  const [url, setUrl] = useState11("");
42929
42962
  const [alt, setAlt] = useState11("");
42930
- const pickerRef = useRef4(null);
42963
+ const pickerRef = useRef5(null);
42931
42964
  useEffect10(() => {
42932
42965
  const handleClickOutside = (event) => {
42933
42966
  if (pickerRef.current && !pickerRef.current.contains(event.target)) {
@@ -43224,54 +43257,43 @@ var HeadingMenu = ({
43224
43257
  ${isOpen ? "opacity-100 scale-100" : "opacity-0 scale-95 pointer-events-none"}
43225
43258
  `,
43226
43259
  children: /* @__PURE__ */ jsxDEV11("div", {
43227
- className: "py-ui-y",
43260
+ className: "flex flex-col py-1",
43228
43261
  children: headingLevels.map((heading) => /* @__PURE__ */ jsxDEV11("button", {
43229
43262
  type: "button",
43263
+ className: "w-full flex items-center px-4 py-2 hover:bg-accent hover:text-accent-foreground transition-colors text-left group",
43230
43264
  onClick: () => {
43231
43265
  onInsertMarkdown(heading.markdown);
43232
43266
  onClose();
43233
43267
  },
43234
- children: /* @__PURE__ */ jsxDEV11("div", {
43235
- className: "flex items-center w-full",
43236
- children: [
43237
- /* @__PURE__ */ jsxDEV11("div", {
43268
+ children: [
43269
+ /* @__PURE__ */ jsxDEV11("div", {
43270
+ className: "flex-shrink-0 w-12 h-8 rounded border flex items-center justify-center font-bold shadow-sm bg-background border-border text-foreground group-hover:border-accent-foreground/30 transition-colors",
43271
+ children: /* @__PURE__ */ jsxDEV11("span", {
43238
43272
  className: `
43239
- flex-1 px-ui-x py-ui-y rounded-md transition-colors duration-150
43240
- hover:bg-accent hover:text-accent-foreground
43241
- `,
43242
- children: /* @__PURE__ */ jsxDEV11("div", {
43243
- className: "flex items-center space-x-3",
43244
- children: /* @__PURE__ */ jsxDEV11("div", {
43245
- className: "flex-shrink-0 w-12 h-8 rounded-ui border flex items-center justify-center font-bold shadow-sm bg-background border-border text-foreground",
43246
- children: /* @__PURE__ */ jsxDEV11("span", {
43247
- className: `
43248
- ${heading.level === 1 ? "text-[18px]" : ""}
43249
- ${heading.level === 2 ? "text-[16px]" : ""}
43250
- ${heading.level === 3 ? "text-[14px]" : ""}
43251
- ${heading.level >= 4 ? "text-[12px]" : ""}
43252
- `,
43253
- children: heading.preview
43254
- }, undefined, false, undefined, this)
43255
- }, undefined, false, undefined, this)
43256
- }, undefined, false, undefined, this)
43257
- }, undefined, false, undefined, this),
43258
- /* @__PURE__ */ jsxDEV11("div", {
43259
- className: "flex-shrink-0 ml-3",
43260
- children: /* @__PURE__ */ jsxDEV11("div", {
43261
- className: `
43262
- truncate max-w-[200px] text-popover-foreground
43263
- ${heading.level === 1 ? "text-[22px] font-bold leading-[28px]" : ""}
43264
- ${heading.level === 2 ? "text-[18px] font-bold leading-[24px]" : ""}
43265
- ${heading.level === 3 ? "text-[16px] font-semibold leading-[22px]" : ""}
43266
- ${heading.level === 4 ? "text-[14px] font-semibold leading-[20px]" : ""}
43267
- ${heading.level === 5 ? "text-[13px] font-semibold leading-[18px]" : ""}
43268
- `,
43269
- children: `${t(I18N_KEYS.heading)}${heading.level}`
43270
- }, undefined, false, undefined, this)
43273
+ ${heading.level === 1 ? "text-[18px]" : ""}
43274
+ ${heading.level === 2 ? "text-[16px]" : ""}
43275
+ ${heading.level === 3 ? "text-[14px]" : ""}
43276
+ ${heading.level >= 4 ? "text-[12px]" : ""}
43277
+ `,
43278
+ children: heading.preview
43271
43279
  }, undefined, false, undefined, this)
43272
- ]
43273
- }, undefined, true, undefined, this)
43274
- }, heading.level, false, undefined, this))
43280
+ }, undefined, false, undefined, this),
43281
+ /* @__PURE__ */ jsxDEV11("div", {
43282
+ className: "ml-3 flex-1",
43283
+ children: /* @__PURE__ */ jsxDEV11("div", {
43284
+ className: `
43285
+ truncate max-w-[180px]
43286
+ ${heading.level === 1 ? "text-[20px] font-bold" : ""}
43287
+ ${heading.level === 2 ? "text-[18px] font-bold" : ""}
43288
+ ${heading.level === 3 ? "text-[16px] font-semibold" : ""}
43289
+ ${heading.level === 4 ? "text-[14px] font-semibold" : ""}
43290
+ ${heading.level === 5 ? "text-[13px] font-medium" : ""}
43291
+ `,
43292
+ children: `${t(I18N_KEYS.heading)}${heading.level}`
43293
+ }, undefined, false, undefined, this)
43294
+ }, undefined, false, undefined, this)
43295
+ ]
43296
+ }, heading.level, true, undefined, this))
43275
43297
  }, undefined, false, undefined, this)
43276
43298
  }, undefined, false, undefined, this)
43277
43299
  ]
@@ -43685,7 +43707,7 @@ var MarkdownToolbar = ({
43685
43707
  disabled
43686
43708
  }, undefined, false, undefined, this),
43687
43709
  item.icon === Smile && showEmojiPicker && /* @__PURE__ */ jsxDEV14("div", {
43688
- className: "absolute top-full left-0 mt-1 z-20",
43710
+ className: "absolute top-full left-1/2 -translate-x-1/2 mt-ui-y z-20",
43689
43711
  children: /* @__PURE__ */ jsxDEV14(EmojiPicker, {
43690
43712
  onSelect: handleEmojiSelect,
43691
43713
  onClose: () => setShowEmojiPicker(false),
@@ -43694,7 +43716,7 @@ var MarkdownToolbar = ({
43694
43716
  }, undefined, false, undefined, this)
43695
43717
  }, undefined, false, undefined, this),
43696
43718
  item.icon === Image3 && showImagePicker && /* @__PURE__ */ jsxDEV14("div", {
43697
- className: "absolute top-full left-0 mt-1 z-20",
43719
+ className: "absolute top-full left-1/2 -translate-x-1/2 mt-ui-y z-20",
43698
43720
  children: /* @__PURE__ */ jsxDEV14(ImagePicker, {
43699
43721
  onInsertMarkdown: handleInsertImageMarkdown,
43700
43722
  onClose: () => setShowImagePicker(false),
@@ -44556,6 +44578,8 @@ var MarkdownEditor = ({
44556
44578
  setProcessingProgress
44557
44579
  } = useEditorState2();
44558
44580
  const editorElementRef = React8.useRef(null);
44581
+ const abortControllerRef = React8.useRef(null);
44582
+ const lastProcessedContentRef = React8.useRef(undefined);
44559
44583
  const {
44560
44584
  linkContextMenu,
44561
44585
  tableContextMenu,
@@ -44616,22 +44640,34 @@ var MarkdownEditor = ({
44616
44640
  useEffect14(() => {
44617
44641
  const processInitialMarkdown = async () => {
44618
44642
  const contentToProcess = value !== undefined ? value : initialContent;
44643
+ if (contentToProcess === lastProcessedContentRef.current) {
44644
+ return;
44645
+ }
44619
44646
  if (!editor)
44620
44647
  return;
44648
+ if (abortControllerRef.current) {
44649
+ abortControllerRef.current.abort();
44650
+ }
44651
+ const controller = new AbortController;
44652
+ abortControllerRef.current = controller;
44621
44653
  if (!contentToProcess || !contentToProcess.trim()) {
44622
- if (!editor.isEmpty) {
44654
+ if (!editor.isEmpty && !controller.signal.aborted) {
44623
44655
  editor.commands.clearContent();
44656
+ lastProcessedContentRef.current = contentToProcess;
44624
44657
  }
44625
44658
  return;
44626
44659
  }
44627
44660
  const trimmed = contentToProcess.trim();
44628
44661
  try {
44629
44662
  if (editor.isFocused && editable) {
44663
+ lastProcessedContentRef.current = contentToProcess;
44630
44664
  return;
44631
44665
  }
44632
44666
  const json2 = await MarkdownTipTapConverter.markdownToTipTapJson(trimmed, {
44633
44667
  publicImagePathPrefix
44634
44668
  });
44669
+ if (controller.signal.aborted)
44670
+ return;
44635
44671
  const codeBlocks = json2?.content?.filter((node) => node.type === "codeBlock") || [];
44636
44672
  if (codeBlocks.length > 0) {
44637
44673
  codeBlocks.forEach((block, idx) => {
@@ -44642,7 +44678,10 @@ var MarkdownEditor = ({
44642
44678
  });
44643
44679
  }
44644
44680
  editor.commands.setContent(json2);
44681
+ lastProcessedContentRef.current = contentToProcess;
44645
44682
  } catch (error) {
44683
+ if (controller.signal.aborted)
44684
+ return;
44646
44685
  logger5.warn("[MarkdownEditor] Automatic Markdown conversion failed:", error);
44647
44686
  const lines = trimmed.split(`
44648
44687
  `);
@@ -44653,11 +44692,17 @@ var MarkdownEditor = ({
44653
44692
  content: line.length > 0 ? [{ type: "text", text: line }] : []
44654
44693
  }))
44655
44694
  });
44695
+ lastProcessedContentRef.current = contentToProcess;
44656
44696
  }
44657
44697
  };
44658
44698
  if (editor) {
44659
44699
  processInitialMarkdown();
44660
44700
  }
44701
+ return () => {
44702
+ if (abortControllerRef.current) {
44703
+ abortControllerRef.current.abort();
44704
+ }
44705
+ };
44661
44706
  }, [editor, initialContent, value, editable, publicImagePathPrefix]);
44662
44707
  useEffect14(() => {
44663
44708
  if (editor && editor.isEditable !== editable) {
@@ -44710,33 +44755,19 @@ var MarkdownEditor = ({
44710
44755
  editor.__preventUpdate = true;
44711
44756
  try {
44712
44757
  const { state, dispatch } = editor.view;
44713
- let linkUpdated = false;
44714
- state.doc.descendants((node, pos) => {
44715
- if (linkUpdated)
44716
- return false;
44717
- if (node.isText && node.marks) {
44718
- const linkMark = node.marks.find((mark) => mark.type.name === "link");
44719
- if (linkMark && linkMark.attrs.href === linkContextMenu.linkData?.href && node.text === linkContextMenu.linkData?.text) {
44720
- if (!state.schema.marks.link) {
44721
- logger5.warn("Link mark type not found in schema");
44722
- return false;
44723
- }
44724
- const from2 = pos;
44725
- const to = pos + node.nodeSize;
44726
- const newLinkMark = state.schema.marks.link.create({ href: newLinkData.href });
44727
- const transaction = state.tr;
44728
- transaction.delete(from2, to);
44729
- transaction.insert(from2, state.schema.text(newLinkData.text, [newLinkMark]));
44730
- dispatch(transaction);
44731
- linkUpdated = true;
44732
- return false;
44733
- }
44734
- }
44735
- return true;
44736
- });
44737
- if (!linkUpdated) {
44738
- logger5.warn("Link not found for update");
44758
+ const { from: from2, to } = linkContextMenu.linkData;
44759
+ const node = state.doc.nodeAt(from2);
44760
+ if (typeof from2 === "number" && typeof to === "number") {
44761
+ const newLinkMark = state.schema.marks.link.create({ href: newLinkData.href });
44762
+ const transaction = state.tr;
44763
+ transaction.delete(from2, to);
44764
+ transaction.insert(from2, state.schema.text(newLinkData.text, [newLinkMark]));
44765
+ dispatch(transaction);
44766
+ } else {
44767
+ logger5.warn("Use of old link editing fallback");
44739
44768
  }
44769
+ } catch (error) {
44770
+ logger5.error("Link update failed", error);
44740
44771
  } finally {
44741
44772
  setTimeout(() => {
44742
44773
  editor.__preventUpdate = originalPreventUpdate;
@@ -45072,5 +45103,5 @@ export {
45072
45103
  CodeBlockNodeView
45073
45104
  };
45074
45105
 
45075
- //# debugId=70312CAF74302EFC64756E2164756E21
45106
+ //# debugId=DBA70DA96E49F65164756E2164756E21
45076
45107
  //# sourceMappingURL=index.js.map