@flogeez/angular-tiptap-editor 3.1.2 → 3.1.4

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 (113) hide show
  1. package/CHANGELOG.md +25 -0
  2. package/README.md +2 -2
  3. package/esm2022/flogeez-angular-tiptap-editor.mjs +5 -0
  4. package/esm2022/lib/ate-editor.provider.mjs +38 -0
  5. package/esm2022/lib/components/bubble-menus/base/ate-base-bubble-menu.mjs +207 -0
  6. package/esm2022/lib/components/bubble-menus/base/ate-base-sub-bubble-menu.mjs +137 -0
  7. package/esm2022/lib/components/bubble-menus/color/ate-color-bubble-menu.component.mjs +365 -0
  8. package/esm2022/lib/components/bubble-menus/image/ate-image-bubble-menu.component.mjs +309 -0
  9. package/esm2022/lib/components/bubble-menus/link/ate-link-bubble-menu.component.mjs +247 -0
  10. package/esm2022/lib/components/bubble-menus/table/ate-cell-bubble-menu.component.mjs +126 -0
  11. package/esm2022/lib/components/bubble-menus/table/ate-table-bubble-menu.component.mjs +271 -0
  12. package/esm2022/lib/components/bubble-menus/text/ate-bubble-menu.component.mjs +272 -0
  13. package/esm2022/lib/components/color-picker/ate-color-picker.component.mjs +123 -0
  14. package/esm2022/lib/components/edit-toggle/ate-edit-toggle.component.mjs +42 -0
  15. package/esm2022/lib/components/editor/angular-tiptap-editor.component.mjs +1031 -0
  16. package/esm2022/lib/components/editor/ate-block-controls.component.mjs +256 -0
  17. package/esm2022/lib/components/slash-commands/ate-slash-commands.component.mjs +328 -0
  18. package/esm2022/lib/components/toolbar/ate-toolbar.component.mjs +531 -0
  19. package/esm2022/lib/components/ui/ate-button.component.mjs +91 -0
  20. package/esm2022/lib/components/ui/ate-separator.component.mjs +11 -0
  21. package/esm2022/lib/config/ate-editor.config.mjs +133 -0
  22. package/esm2022/lib/config/ate-global-config.token.mjs +6 -0
  23. package/esm2022/lib/config/ate-slash-commands.config.mjs +130 -0
  24. package/esm2022/lib/directives/ate-noop-value-accessor.directive.mjs +40 -0
  25. package/esm2022/lib/directives/ate-tooltip.directive.mjs +138 -0
  26. package/esm2022/lib/extensions/ate-block-controls.extension.mjs +156 -0
  27. package/esm2022/lib/extensions/ate-link-click-behavior.extension.mjs +32 -0
  28. package/esm2022/lib/extensions/ate-resizable-image.extension.mjs +277 -0
  29. package/esm2022/lib/extensions/ate-table.extension.mjs +27 -0
  30. package/esm2022/lib/extensions/ate-tiptap-state.extension.mjs +85 -0
  31. package/esm2022/lib/extensions/ate-upload-progress.extension.mjs +195 -0
  32. package/esm2022/lib/extensions/calculators/ate-discovery.calculator.mjs +62 -0
  33. package/esm2022/lib/extensions/calculators/ate-image.calculator.mjs +8 -0
  34. package/esm2022/lib/extensions/calculators/ate-marks.calculator.mjs +75 -0
  35. package/esm2022/lib/extensions/calculators/ate-selection.calculator.mjs +35 -0
  36. package/esm2022/lib/extensions/calculators/ate-structure.calculator.mjs +34 -0
  37. package/esm2022/lib/extensions/calculators/ate-table.calculator.mjs +38 -0
  38. package/esm2022/lib/models/ate-bubble-menu.model.mjs +53 -0
  39. package/esm2022/lib/models/ate-editor-config.model.mjs +2 -0
  40. package/esm2022/lib/models/ate-editor-state.model.mjs +90 -0
  41. package/esm2022/lib/models/ate-image.model.mjs +2 -0
  42. package/esm2022/lib/models/ate-slash-command.model.mjs +2 -0
  43. package/esm2022/lib/models/ate-toolbar.model.mjs +35 -0
  44. package/esm2022/lib/node-view/ate-angular-node-view.mjs +97 -0
  45. package/esm2022/lib/node-view/ate-injector.registry.mjs +16 -0
  46. package/esm2022/lib/node-view/ate-node-view.factory.mjs +125 -0
  47. package/esm2022/lib/node-view/ate-node-view.models.mjs +2 -0
  48. package/esm2022/lib/node-view/ate-node-view.renderer.mjs +154 -0
  49. package/esm2022/lib/node-view/ate-register-angular-component.mjs +49 -0
  50. package/esm2022/lib/services/ate-color-picker.service.mjs +194 -0
  51. package/esm2022/lib/services/ate-editor-commands.service.mjs +474 -0
  52. package/esm2022/lib/services/ate-i18n.service.mjs +422 -0
  53. package/esm2022/lib/services/ate-image.service.mjs +459 -0
  54. package/esm2022/lib/services/ate-link.service.mjs +99 -0
  55. package/esm2022/lib/utils/ate-color.utils.mjs +60 -0
  56. package/esm2022/public-api.mjs +40 -0
  57. package/fesm2022/flogeez-angular-tiptap-editor.mjs +321 -354
  58. package/fesm2022/flogeez-angular-tiptap-editor.mjs.map +1 -1
  59. package/index.d.ts +3 -1734
  60. package/lib/ate-editor.provider.d.ts +21 -0
  61. package/lib/components/bubble-menus/base/ate-base-bubble-menu.d.ts +71 -0
  62. package/lib/components/bubble-menus/base/ate-base-sub-bubble-menu.d.ts +60 -0
  63. package/lib/components/bubble-menus/color/ate-color-bubble-menu.component.d.ts +77 -0
  64. package/lib/components/bubble-menus/image/ate-image-bubble-menu.component.d.ts +49 -0
  65. package/lib/components/bubble-menus/link/ate-link-bubble-menu.component.d.ts +55 -0
  66. package/lib/components/bubble-menus/table/ate-cell-bubble-menu.component.d.ts +16 -0
  67. package/lib/components/bubble-menus/table/ate-table-bubble-menu.component.d.ts +25 -0
  68. package/lib/components/bubble-menus/text/ate-bubble-menu.component.d.ts +53 -0
  69. package/lib/components/color-picker/ate-color-picker.component.d.ts +54 -0
  70. package/lib/components/edit-toggle/ate-edit-toggle.component.d.ts +13 -0
  71. package/lib/components/editor/angular-tiptap-editor.component.d.ts +242 -0
  72. package/lib/components/editor/ate-block-controls.component.d.ts +44 -0
  73. package/lib/components/slash-commands/ate-slash-commands.component.d.ts +34 -0
  74. package/lib/components/toolbar/ate-toolbar.component.d.ts +47 -0
  75. package/lib/components/ui/ate-button.component.d.ts +25 -0
  76. package/lib/components/ui/ate-separator.component.d.ts +5 -0
  77. package/lib/config/ate-editor.config.d.ts +19 -0
  78. package/lib/config/ate-global-config.token.d.ts +6 -0
  79. package/lib/config/ate-slash-commands.config.d.ts +41 -0
  80. package/lib/directives/ate-noop-value-accessor.directive.d.ts +13 -0
  81. package/lib/directives/ate-tooltip.directive.d.ts +30 -0
  82. package/lib/extensions/ate-block-controls.extension.d.ts +10 -0
  83. package/lib/extensions/ate-link-click-behavior.extension.d.ts +2 -0
  84. package/lib/extensions/ate-resizable-image.extension.d.ts +27 -0
  85. package/lib/extensions/ate-table.extension.d.ts +2 -0
  86. package/lib/extensions/ate-tiptap-state.extension.d.ts +7 -0
  87. package/lib/extensions/ate-upload-progress.extension.d.ts +7 -0
  88. package/lib/extensions/calculators/ate-discovery.calculator.d.ts +7 -0
  89. package/lib/extensions/calculators/ate-image.calculator.d.ts +2 -0
  90. package/lib/extensions/calculators/ate-marks.calculator.d.ts +2 -0
  91. package/lib/extensions/calculators/ate-selection.calculator.d.ts +2 -0
  92. package/lib/extensions/calculators/ate-structure.calculator.d.ts +2 -0
  93. package/lib/extensions/calculators/ate-table.calculator.d.ts +2 -0
  94. package/lib/models/ate-bubble-menu.model.d.ts +33 -0
  95. package/lib/models/ate-editor-config.model.d.ts +113 -0
  96. package/lib/models/ate-editor-state.model.d.ts +109 -0
  97. package/lib/models/ate-image.model.d.ts +104 -0
  98. package/lib/models/ate-slash-command.model.d.ts +17 -0
  99. package/lib/models/ate-toolbar.model.d.ts +18 -0
  100. package/lib/node-view/ate-angular-node-view.d.ts +115 -0
  101. package/lib/node-view/ate-injector.registry.d.ts +3 -0
  102. package/lib/node-view/ate-node-view.factory.d.ts +10 -0
  103. package/lib/node-view/ate-node-view.models.d.ts +138 -0
  104. package/lib/node-view/ate-node-view.renderer.d.ts +23 -0
  105. package/lib/node-view/ate-register-angular-component.d.ts +35 -0
  106. package/lib/services/ate-color-picker.service.d.ts +65 -0
  107. package/lib/services/ate-editor-commands.service.d.ts +75 -0
  108. package/lib/services/ate-i18n.service.d.ts +406 -0
  109. package/lib/services/ate-image.service.d.ts +82 -0
  110. package/lib/services/ate-link.service.d.ts +42 -0
  111. package/lib/utils/ate-color.utils.d.ts +12 -0
  112. package/package.json +3 -1
  113. package/public-api.d.ts +31 -0
@@ -0,0 +1,138 @@
1
+ import { Directive, ElementRef, input, inject, effect, computed } from "@angular/core";
2
+ import tippy from "tippy.js";
3
+ import * as i0 from "@angular/core";
4
+ // Pre-calculate platform once to avoid repeated checks
5
+ const IS_MAC = typeof window !== "undefined" && /Mac|iPod|iPhone|iPad/.test(navigator.platform);
6
+ export class AteTooltipDirective {
7
+ constructor() {
8
+ this.el = inject(ElementRef);
9
+ this.tippyInstance = null;
10
+ // Signal Inputs
11
+ this.content = input(null, { alias: "ateTooltip" });
12
+ this.placement = input("top", { alias: "ateTooltipPlacement" });
13
+ this.delay = input([200, 50], { alias: "ateTooltipDelay" });
14
+ this.disabled = input(false, { alias: "ateTooltipDisabled" });
15
+ /**
16
+ * Computed logic for ARIA shortcuts.
17
+ */
18
+ this.ariaShortcut = computed(() => {
19
+ const text = this.content();
20
+ if (!text || !text.includes("\n")) {
21
+ return null;
22
+ }
23
+ return text.split("\n")[1].replace(/\+/g, " ");
24
+ });
25
+ /**
26
+ * Computed logic for Tippy content.
27
+ * Includes strict escaping of dynamic content to prevent XSS.
28
+ */
29
+ this.processedTooltip = computed(() => {
30
+ const text = this.content();
31
+ if (!text) {
32
+ return { content: "", isHTML: false };
33
+ }
34
+ if (text.includes("\n")) {
35
+ const [label, shortcut] = text.split("\n");
36
+ // Escape dynamic parts to prevent XSS before wrapping in safe HTML
37
+ const safeLabel = this.escapeHtml(label);
38
+ let safeShortcut = this.escapeHtml(shortcut);
39
+ if (IS_MAC) {
40
+ safeShortcut = safeShortcut.replace(/Ctrl\+/g, "⌘").replace(/Mod\+/g, "⌘");
41
+ }
42
+ else {
43
+ safeShortcut = safeShortcut.replace(/Mod\+/g, "Ctrl+");
44
+ }
45
+ return {
46
+ content: `<div class="ate-tooltip-label">${safeLabel}</div><div class="ate-tooltip-shortcut"><kbd>${safeShortcut}</kbd></div>`,
47
+ isHTML: true,
48
+ };
49
+ }
50
+ // No newline? Keep it as plain text (Tippy handles string as text by default)
51
+ return { content: text, isHTML: false };
52
+ });
53
+ effect(() => {
54
+ const { content, isHTML } = this.processedTooltip();
55
+ const placement = this.placement();
56
+ const delay = this.delay();
57
+ const isDisabled = this.disabled();
58
+ if (isDisabled || !content) {
59
+ this.destroyTippy();
60
+ return;
61
+ }
62
+ if (!this.tippyInstance) {
63
+ this.initTippy(content, isHTML, placement, delay);
64
+ }
65
+ else {
66
+ this.tippyInstance.setProps({
67
+ content,
68
+ allowHTML: isHTML,
69
+ placement,
70
+ delay,
71
+ });
72
+ }
73
+ });
74
+ }
75
+ ngOnDestroy() {
76
+ this.destroyTippy();
77
+ }
78
+ /**
79
+ * Basic HTML escaping for security.
80
+ * Effectively neutralizes scripts or malicious HTML tags.
81
+ */
82
+ escapeHtml(unsafe) {
83
+ return unsafe
84
+ .replace(/&/g, "&amp;")
85
+ .replace(/</g, "&lt;")
86
+ .replace(/>/g, "&gt;")
87
+ .replace(/"/g, "&quot;")
88
+ .replace(/'/g, "&#039;");
89
+ }
90
+ initTippy(content, allowHTML, placement, delay) {
91
+ const container = this.el.nativeElement.closest(".ate-editor") || document.body;
92
+ this.tippyInstance = tippy(this.el.nativeElement, {
93
+ content,
94
+ allowHTML,
95
+ placement,
96
+ delay,
97
+ duration: [100, 100],
98
+ offset: [0, 6],
99
+ theme: "ate-tooltip",
100
+ touch: ["hold", 500],
101
+ maxWidth: 250,
102
+ appendTo: () => container,
103
+ aria: {
104
+ content: "describedby",
105
+ },
106
+ popperOptions: {
107
+ modifiers: [
108
+ {
109
+ name: "preventOverflow",
110
+ options: {
111
+ boundary: document.body,
112
+ padding: 8,
113
+ },
114
+ },
115
+ ],
116
+ },
117
+ });
118
+ }
119
+ destroyTippy() {
120
+ if (this.tippyInstance) {
121
+ this.tippyInstance.destroy();
122
+ this.tippyInstance = null;
123
+ }
124
+ }
125
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteTooltipDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
126
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.14", type: AteTooltipDirective, isStandalone: true, selector: "[ateTooltip]", inputs: { content: { classPropertyName: "content", publicName: "ateTooltip", isSignal: true, isRequired: false, transformFunction: null }, placement: { classPropertyName: "placement", publicName: "ateTooltipPlacement", isSignal: true, isRequired: false, transformFunction: null }, delay: { classPropertyName: "delay", publicName: "ateTooltipDelay", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "ateTooltipDisabled", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "attr.aria-keyshortcuts": "ariaShortcut()" } }, ngImport: i0 }); }
127
+ }
128
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: AteTooltipDirective, decorators: [{
129
+ type: Directive,
130
+ args: [{
131
+ selector: "[ateTooltip]",
132
+ standalone: true,
133
+ host: {
134
+ "[attr.aria-keyshortcuts]": "ariaShortcut()",
135
+ },
136
+ }]
137
+ }], ctorParameters: () => [] });
138
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRlLXRvb2x0aXAuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci10aXB0YXAtZWRpdG9yL3NyYy9saWIvZGlyZWN0aXZlcy9hdGUtdG9vbHRpcC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsS0FBSyxFQUFhLE1BQU0sRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2xHLE9BQU8sS0FBK0MsTUFBTSxVQUFVLENBQUM7O0FBRXZFLHVEQUF1RDtBQUN2RCxNQUFNLE1BQU0sR0FBRyxPQUFPLE1BQU0sS0FBSyxXQUFXLElBQUksc0JBQXNCLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsQ0FBQztBQVNoRyxNQUFNLE9BQU8sbUJBQW1CO0lBc0Q5QjtRQXJEaUIsT0FBRSxHQUFHLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUNqQyxrQkFBYSxHQUF5QixJQUFJLENBQUM7UUFFbkQsZ0JBQWdCO1FBQ2hCLFlBQU8sR0FBRyxLQUFLLENBQWdCLElBQUksRUFBRSxFQUFFLEtBQUssRUFBRSxZQUFZLEVBQUUsQ0FBQyxDQUFDO1FBQzlELGNBQVMsR0FBRyxLQUFLLENBQVksS0FBSyxFQUFFLEVBQUUsS0FBSyxFQUFFLHFCQUFxQixFQUFFLENBQUMsQ0FBQztRQUN0RSxVQUFLLEdBQUcsS0FBSyxDQUE0QixDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsRUFBRSxFQUFFLEtBQUssRUFBRSxpQkFBaUIsRUFBRSxDQUFDLENBQUM7UUFDbEYsYUFBUSxHQUFHLEtBQUssQ0FBVSxLQUFLLEVBQUUsRUFBRSxLQUFLLEVBQUUsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDO1FBRWxFOztXQUVHO1FBQ2dCLGlCQUFZLEdBQUcsUUFBUSxDQUFDLEdBQUcsRUFBRTtZQUM5QyxN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QUM7SUFFTyxZQUFZO1FBQ2xCLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxhQUFhLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDN0IsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUM7UUFDNUIsQ0FBQztJQUNILENBQUM7K0dBeklVLG1CQUFtQjttR0FBbkIsbUJBQW1COzs0RkFBbkIsbUJBQW1CO2tCQVAvQixTQUFTO21CQUFDO29CQUNULFFBQVEsRUFBRSxjQUFjO29CQUN4QixVQUFVLEVBQUUsSUFBSTtvQkFDaEIsSUFBSSxFQUFFO3dCQUNKLDBCQUEwQixFQUFFLGdCQUFnQjtxQkFDN0M7aUJBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBEaXJlY3RpdmUsIEVsZW1lbnRSZWYsIGlucHV0LCBPbkRlc3Ryb3ksIGluamVjdCwgZWZmZWN0LCBjb21wdXRlZCB9IGZyb20gXCJAYW5ndWxhci9jb3JlXCI7XG5pbXBvcnQgdGlwcHksIHsgSW5zdGFuY2UgYXMgVGlwcHlJbnN0YW5jZSwgUGxhY2VtZW50IH0gZnJvbSBcInRpcHB5LmpzXCI7XG5cbi8vIFByZS1jYWxjdWxhdGUgcGxhdGZvcm0gb25jZSB0byBhdm9pZCByZXBlYXRlZCBjaGVja3NcbmNvbnN0IElTX01BQyA9IHR5cGVvZiB3aW5kb3cgIT09IFwidW5kZWZpbmVkXCIgJiYgL01hY3xpUG9kfGlQaG9uZXxpUGFkLy50ZXN0KG5hdmlnYXRvci5wbGF0Zm9ybSk7XG5cbkBEaXJlY3RpdmUoe1xuICBzZWxlY3RvcjogXCJbYXRlVG9vbHRpcF1cIixcbiAgc3RhbmRhbG9uZTogdHJ1ZSxcbiAgaG9zdDoge1xuICAgIFwiW2F0dHIuYXJpYS1rZXlzaG9ydGN1dHNdXCI6IFwiYXJpYVNob3J0Y3V0KClcIixcbiAgfSxcbn0pXG5leHBvcnQgY2xhc3MgQXRlVG9vbHRpcERpcmVjdGl2ZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgZWwgPSBpbmplY3QoRWxlbWVudFJlZik7XG4gIHByaXZhdGUgdGlwcHlJbnN0YW5jZTogVGlwcHlJbnN0YW5jZSB8IG51bGwgPSBudWxsO1xuXG4gIC8vIFNpZ25hbCBJbnB1dHNcbiAgY29udGVudCA9IGlucHV0PHN0cmluZyB8IG51bGw+KG51bGwsIHsgYWxpYXM6IFwiYXRlVG9vbHRpcFwiIH0pO1xuICBwbGFjZW1lbnQgPSBpbnB1dDxQbGFjZW1lbnQ+KFwidG9wXCIsIHsgYWxpYXM6IFwiYXRlVG9vbHRpcFBsYWNlbWVudFwiIH0pO1xuICBkZWxheSA9IGlucHV0PG51bWJlciB8IFtudW1iZXIsIG51bWJlcl0+KFsyMDAsIDUwXSwgeyBhbGlhczogXCJhdGVUb29sdGlwRGVsYXlcIiB9KTtcbiAgZGlzYWJsZWQgPSBpbnB1dDxib29sZWFuPihmYWxzZSwgeyBhbGlhczogXCJhdGVUb29sdGlwRGlzYWJsZWRcIiB9KTtcblxuICAvKipcbiAgICogQ29tcHV0ZWQgbG9naWMgZm9yIEFSSUEgc2hvcnRjdXRzLlxuICAgKi9cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGFyaWFTaG9ydGN1dCA9IGNvbXB1dGVkKCgpID0+IHtcbiAgICBjb25zdCB0ZXh0ID0gdGhpcy5jb250ZW50KCk7XG4gICAgaWYgKCF0ZXh0IHx8ICF0ZXh0LmluY2x1ZGVzKFwiXFxuXCIpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIHRleHQuc3BsaXQoXCJcXG5cIilbMV0ucmVwbGFjZSgvXFwrL2csIFwiIFwiKTtcbiAgfSk7XG5cbiAgLyoqXG4gICAqIENvbXB1dGVkIGxvZ2ljIGZvciBUaXBweSBjb250ZW50LlxuICAgKiBJbmNsdWRlcyBzdHJpY3QgZXNjYXBpbmcgb2YgZHluYW1pYyBjb250ZW50IHRvIHByZXZlbnQgWFNTLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBwcm9jZXNzZWRUb29sdGlwID0gY29tcHV0ZWQoKCkgPT4ge1xuICAgIGNvbnN0IHRleHQgPSB0aGlzLmNvbnRlbnQoKTtcbiAgICBpZiAoIXRleHQpIHtcbiAgICAgIHJldHVybiB7IGNvbnRlbnQ6IFwiXCIsIGlzSFRNTDogZmFsc2UgfTtcbiAgICB9XG5cbiAgICBpZiAodGV4dC5pbmNsdWRlcyhcIlxcblwiKSkge1xuICAgICAgY29uc3QgW2xhYmVsLCBzaG9ydGN1dF0gPSB0ZXh0LnNwbGl0KFwiXFxuXCIpO1xuXG4gICAgICAvLyBFc2NhcGUgZHluYW1pYyBwYXJ0cyB0byBwcmV2ZW50IFhTUyBiZWZvcmUgd3JhcHBpbmcgaW4gc2FmZSBIVE1MXG4gICAgICBjb25zdCBzYWZlTGFiZWwgPSB0aGlzLmVzY2FwZUh0bWwobGFiZWwpO1xuICAgICAgbGV0IHNhZmVTaG9ydGN1dCA9IHRoaXMuZXNjYXBlSHRtbChzaG9ydGN1dCk7XG5cbiAgICAgIGlmIChJU19NQUMpIHtcbiAgICAgICAgc2FmZVNob3J0Y3V0ID0gc2FmZVNob3J0Y3V0LnJlcGxhY2UoL0N0cmxcXCsvZywgXCLijJhcIikucmVwbGFjZSgvTW9kXFwrL2csIFwi4oyYXCIpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc2FmZVNob3J0Y3V0ID0gc2FmZVNob3J0Y3V0LnJlcGxhY2UoL01vZFxcKy9nLCBcIkN0cmwrXCIpO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBjb250ZW50OiBgPGRpdiBjbGFzcz1cImF0ZS10b29sdGlwLWxhYmVsXCI+JHtzYWZlTGFiZWx9PC9kaXY+PGRpdiBjbGFzcz1cImF0ZS10b29sdGlwLXNob3J0Y3V0XCI+PGtiZD4ke3NhZmVTaG9ydGN1dH08L2tiZD48L2Rpdj5gLFxuICAgICAgICBpc0hUTUw6IHRydWUsXG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIE5vIG5ld2xpbmU/IEtlZXAgaXQgYXMgcGxhaW4gdGV4dCAoVGlwcHkgaGFuZGxlcyBzdHJpbmcgYXMgdGV4dCBieSBkZWZhdWx0KVxuICAgIHJldHVybiB7IGNvbnRlbnQ6IHRleHQsIGlzSFRNTDogZmFsc2UgfTtcbiAgfSk7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgZWZmZWN0KCgpID0+IHtcbiAgICAgIGNvbnN0IHsgY29udGVudCwgaXNIVE1MIH0gPSB0aGlzLnByb2Nlc3NlZFRvb2x0aXAoKTtcbiAgICAgIGNvbnN0IHBsYWNlbWVudCA9IHRoaXMucGxhY2VtZW50KCk7XG4gICAgICBjb25zdCBkZWxheSA9IHRoaXMuZGVsYXkoKTtcbiAgICAgIGNvbnN0IGlzRGlzYWJsZWQgPSB0aGlzLmRpc2FibGVkKCk7XG5cbiAgICAgIGlmIChpc0Rpc2FibGVkIHx8ICFjb250ZW50KSB7XG4gICAgICAgIHRoaXMuZGVzdHJveVRpcHB5KCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgaWYgKCF0aGlzLnRpcHB5SW5zdGFuY2UpIHtcbiAgICAgICAgdGhpcy5pbml0VGlwcHkoY29udGVudCwgaXNIVE1MLCBwbGFjZW1lbnQsIGRlbGF5KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMudGlwcHlJbnN0YW5jZS5zZXRQcm9wcyh7XG4gICAgICAgICAgY29udGVudCxcbiAgICAgICAgICBhbGxvd0hUTUw6IGlzSFRNTCxcbiAgICAgICAgICBwbGFjZW1lbnQsXG4gICAgICAgICAgZGVsYXksXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95VGlwcHkoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBCYXNpYyBIVE1MIGVzY2FwaW5nIGZvciBzZWN1cml0eS5cbiAgICogRWZmZWN0aXZlbHkgbmV1dHJhbGl6ZXMgc2NyaXB0cyBvciBtYWxpY2lvdXMgSFRNTCB0YWdzLlxuICAgKi9cbiAgcHJpdmF0ZSBlc2NhcGVIdG1sKHVuc2FmZTogc3RyaW5nKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdW5zYWZlXG4gICAgICAucmVwbGFjZSgvJi9nLCBcIiZhbXA7XCIpXG4gICAgICAucmVwbGFjZSgvPC9nLCBcIiZsdDtcIilcbiAgICAgIC5yZXBsYWNlKC8+L2csIFwiJmd0O1wiKVxuICAgICAgLnJlcGxhY2UoL1wiL2csIFwiJnF1b3Q7XCIpXG4gICAgICAucmVwbGFjZSgvJy9nLCBcIiYjMDM5O1wiKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdFRpcHB5KFxuICAgIGNvbnRlbnQ6IHN0cmluZyxcbiAgICBhbGxvd0hUTUw6IGJvb2xlYW4sXG4gICAgcGxhY2VtZW50OiBQbGFjZW1lbnQsXG4gICAgZGVsYXk6IG51bWJlciB8IFtudW1iZXIsIG51bWJlcl1cbiAgKTogdm9pZCB7XG4gICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5lbC5uYXRpdmVFbGVtZW50LmNsb3Nlc3QoXCIuYXRlLWVkaXRvclwiKSB8fCBkb2N1bWVudC5ib2R5O1xuXG4gICAgdGhpcy50aXBweUluc3RhbmNlID0gdGlwcHkodGhpcy5lbC5uYXRpdmVFbGVtZW50LCB7XG4gICAgICBjb250ZW50LFxuICAgICAgYWxsb3dIVE1MLFxuICAgICAgcGxhY2VtZW50LFxuICAgICAgZGVsYXksXG4gICAgICBkdXJhdGlvbjogWzEwMCwgMTAwXSxcbiAgICAgIG9mZnNldDogWzAsIDZdLFxuICAgICAgdGhlbWU6IFwiYXRlLXRvb2x0aXBcIixcbiAgICAgIHRvdWNoOiBbXCJob2xkXCIsIDUwMF0sXG4gICAgICBtYXhXaWR0aDogMjUwLFxuICAgICAgYXBwZW5kVG86ICgpID0+IGNvbnRhaW5lcixcbiAgICAgIGFyaWE6IHtcbiAgICAgICAgY29udGVudDogXCJkZXNjcmliZWRieVwiLFxuICAgICAgfSxcbiAgICAgIHBvcHBlck9wdGlvbnM6IHtcbiAgICAgICAgbW9kaWZpZXJzOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgbmFtZTogXCJwcmV2ZW50T3ZlcmZsb3dcIixcbiAgICAgICAgICAgIG9wdGlvbnM6IHtcbiAgICAgICAgICAgICAgYm91bmRhcnk6IGRvY3VtZW50LmJvZHksXG4gICAgICAgICAgICAgIHBhZGRpbmc6IDgsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgIH0pIGFzIHVua25vd24gYXMgVGlwcHlJbnN0YW5jZTtcbiAgfVxuXG4gIHByaXZhdGUgZGVzdHJveVRpcHB5KCk6IHZvaWQge1xuICAgIGlmICh0aGlzLnRpcHB5SW5zdGFuY2UpIHtcbiAgICAgIHRoaXMudGlwcHlJbnN0YW5jZS5kZXN0cm95KCk7XG4gICAgICB0aGlzLnRpcHB5SW5zdGFuY2UgPSBudWxsO1xuICAgIH1cbiAgfVxufVxuIl19
@@ -0,0 +1,156 @@
1
+ import { Extension } from "@tiptap/core";
2
+ import { Plugin, PluginKey } from "@tiptap/pm/state";
3
+ // Helper to get the DOM element properly
4
+ function getDomElement(view, pos) {
5
+ const dom = view.nodeDOM(pos);
6
+ if (!dom) {
7
+ return null;
8
+ }
9
+ if (dom instanceof HTMLElement) {
10
+ return dom;
11
+ }
12
+ return dom.parentElement;
13
+ }
14
+ // VERTICAL SCAN (For the empty margin)
15
+ function findBlockElementAtY(view, y) {
16
+ const editorDom = view.dom;
17
+ const children = Array.from(editorDom.children);
18
+ // We look for the direct child of the editor (Level 1) that intercepts the Y line
19
+ return (children.find(child => {
20
+ if (getComputedStyle(child).position === "absolute") {
21
+ return false;
22
+ }
23
+ const rect = child.getBoundingClientRect();
24
+ // Tolérance de 5px
25
+ return y >= rect.top - 5 && y <= rect.bottom + 5;
26
+ }) || null);
27
+ }
28
+ function resolveBlockData(view, y, targetElement) {
29
+ let blockEl = null;
30
+ // 1. FAST PATH : Direct target
31
+ // LEVEL 1: We look for the first parent element that is a direct child of the editor
32
+ if (targetElement && !targetElement.classList.contains("ProseMirror")) {
33
+ blockEl = targetElement.closest(".ProseMirror > *");
34
+ }
35
+ // 2. GUTTER PATH : Vertical scan
36
+ if (!blockEl) {
37
+ blockEl = findBlockElementAtY(view, y);
38
+ }
39
+ if (!blockEl) {
40
+ return null;
41
+ }
42
+ // 3. PROSEMIRROR NODE RESOLUTION
43
+ try {
44
+ // We ask for the position at the beginning of this root block
45
+ const pos = view.posAtDOM(blockEl, 0);
46
+ const $pos = view.state.doc.resolve(pos);
47
+ // CASE A : STANDARD BLOCKS (H1, P, Lists, Blockquotes...)
48
+ // We make sure to take the node of depth 1 (Direct child of the Doc)
49
+ if ($pos.depth >= 1) {
50
+ const rootNode = $pos.node(1);
51
+ const rootPos = $pos.before(1);
52
+ const rootElement = getDomElement(view, rootPos);
53
+ // Sécurité : on vérifie que l'élément DOM correspond bien
54
+ if (rootNode && (rootElement || blockEl)) {
55
+ return { node: rootNode, element: rootElement || blockEl, pos: rootPos };
56
+ }
57
+ }
58
+ // CASE B : IMAGES / ATOMS (Depth 0)
59
+ // Sometimes a root image is seen as Depth 0 by resolve()
60
+ // We look at the node right after the position
61
+ if ($pos.depth === 0) {
62
+ const nodeAfter = $pos.nodeAfter;
63
+ if (nodeAfter && (nodeAfter.isBlock || nodeAfter.isAtom)) {
64
+ return { node: nodeAfter, element: blockEl, pos: pos };
65
+ }
66
+ }
67
+ }
68
+ catch (_e) {
69
+ // console.warn(_e);
70
+ }
71
+ return null;
72
+ }
73
+ export const AteBlockControlsExtension = Extension.create({
74
+ name: "ateBlockControls",
75
+ addOptions() {
76
+ return { onHover: undefined };
77
+ },
78
+ addProseMirrorPlugins() {
79
+ let lastHoveredElement = null;
80
+ let lastHoveredPos = null;
81
+ let rafId = null;
82
+ let lastMouseX = 0;
83
+ let lastMouseY = 0;
84
+ const update = (view) => {
85
+ if (!this.editor.isEditable) {
86
+ return;
87
+ }
88
+ const editorRect = view.dom.getBoundingClientRect();
89
+ const gutterWidth = 80;
90
+ // Check Limites (Marge Gauche + Editeur)
91
+ if (lastMouseY < editorRect.top ||
92
+ lastMouseY > editorRect.bottom ||
93
+ lastMouseX > editorRect.right ||
94
+ lastMouseX < editorRect.left - gutterWidth) {
95
+ if (lastHoveredElement) {
96
+ reset();
97
+ }
98
+ return;
99
+ }
100
+ // STICKY ANTI-FLICKER
101
+ // On garde le bloc tant qu'on est dans sa hauteur
102
+ if (lastHoveredElement && lastHoveredElement.isConnected) {
103
+ const rect = lastHoveredElement.getBoundingClientRect();
104
+ if (lastMouseY >= rect.top && lastMouseY <= rect.bottom) {
105
+ return;
106
+ }
107
+ }
108
+ const target = document.elementFromPoint(lastMouseX, lastMouseY);
109
+ const data = resolveBlockData(view, lastMouseY, target);
110
+ if (data && (data.element !== lastHoveredElement || data.pos !== lastHoveredPos)) {
111
+ lastHoveredElement = data.element;
112
+ lastHoveredPos = data.pos;
113
+ this.options.onHover?.(data);
114
+ }
115
+ else if (!data) {
116
+ if (!lastHoveredElement || !lastHoveredElement.isConnected) {
117
+ reset();
118
+ }
119
+ }
120
+ };
121
+ const reset = () => {
122
+ this.options.onHover?.(null);
123
+ lastHoveredElement = null;
124
+ lastHoveredPos = null;
125
+ };
126
+ return [
127
+ new Plugin({
128
+ key: new PluginKey("ateBlockControls"),
129
+ props: {
130
+ handleDOMEvents: {
131
+ mousemove: (view, event) => {
132
+ lastMouseX = event.clientX;
133
+ lastMouseY = event.clientY;
134
+ if (rafId === null) {
135
+ rafId = window.requestAnimationFrame(() => {
136
+ update(view);
137
+ rafId = null;
138
+ });
139
+ }
140
+ return false;
141
+ },
142
+ mouseleave: () => {
143
+ if (rafId) {
144
+ window.cancelAnimationFrame(rafId);
145
+ rafId = null;
146
+ }
147
+ reset();
148
+ return false;
149
+ },
150
+ },
151
+ },
152
+ }),
153
+ ];
154
+ },
155
+ });
156
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRlLWJsb2NrLWNvbnRyb2xzLmV4dGVuc2lvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItdGlwdGFwLWVkaXRvci9zcmMvbGliL2V4dGVuc2lvbnMvYXRlLWJsb2NrLWNvbnRyb2xzLmV4dGVuc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sY0FBYyxDQUFDO0FBQ3pDLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFRckQseUNBQXlDO0FBQ3pDLFNBQVMsYUFBYSxDQUFDLElBQWdCLEVBQUUsR0FBVztJQUNsRCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzlCLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztRQUNULE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELElBQUksR0FBRyxZQUFZLFdBQVcsRUFBRSxDQUFDO1FBQy9CLE9BQU8sR0FBRyxDQUFDO0lBQ2IsQ0FBQztJQUNELE9BQU8sR0FBRyxDQUFDLGFBQWEsQ0FBQztBQUMzQixDQUFDO0FBRUQsdUNBQXVDO0FBQ3ZDLFNBQVMsbUJBQW1CLENBQUMsSUFBZ0IsRUFBRSxDQUFTO0lBQ3RELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFrQixDQUFDO0lBQzFDLE1BQU0sUUFBUSxHQUFHLEtBQUssQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLFFBQVEsQ0FBa0IsQ0FBQztJQUVqRSxrRkFBa0Y7SUFDbEYsT0FBTyxDQUNMLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUU7UUFDcEIsSUFBSSxnQkFBZ0IsQ0FBQyxLQUFLLENBQUMsQ0FBQyxRQUFRLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDcEQsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO1FBQ0QsTUFBTSxJ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TUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO29DQUNiLEtBQUssR0FBRyxJQUFJLENBQUM7Z0NBQ2YsQ0FBQyxDQUFDLENBQUM7NEJBQ0wsQ0FBQzs0QkFDRCxPQUFPLEtBQUssQ0FBQzt3QkFDZixDQUFDO3dCQUNELFVBQVUsRUFBRSxHQUFHLEVBQUU7NEJBQ2YsSUFBSSxLQUFLLEVBQUUsQ0FBQztnQ0FDVixNQUFNLENBQUMsb0JBQW9CLENBQUMsS0FBSyxDQUFDLENBQUM7Z0NBQ25DLEtBQUssR0FBRyxJQUFJLENBQUM7NEJBQ2YsQ0FBQzs0QkFDRCxLQUFLLEVBQUUsQ0FBQzs0QkFDUixPQUFPLEtBQUssQ0FBQzt3QkFDZixDQUFDO3FCQUNGO2lCQUNGO2FBQ0YsQ0FBQztTQUNILENBQUM7SUFDSixDQUFDO0NBQ0YsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRXh0ZW5zaW9uIH0gZnJvbSBcIkB0aXB0YXAvY29yZVwiO1xuaW1wb3J0IHsgUGx1Z2luLCBQbHVnaW5LZXkgfSBmcm9tIFwiQHRpcHRhcC9wbS9zdGF0ZVwiO1xuaW1wb3J0IHsgRWRpdG9yVmlldyB9IGZyb20gXCJAdGlwdGFwL3BtL3ZpZXdcIjtcbmltcG9ydCB7IE5vZGUgfSBmcm9tIFwiQHRpcHRhcC9wbS9tb2RlbFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIEF0ZUJsb2NrQ29udHJvbHNPcHRpb25zIHtcbiAgb25Ib3Zlcj86IChkYXRhOiB7IG5vZGU6IE5vZGU7IGVsZW1lbnQ6IEhUTUxFbGVtZW50OyBwb3M6IG51bWJlciB9IHwgbnVsbCkgPT4gdm9pZDtcbn1cblxuLy8gSGVscGVyIHRvIGdldCB0aGUgRE9NIGVsZW1lbnQgcHJvcGVybHlcbmZ1bmN0aW9uIGdldERvbUVsZW1lbnQodmlldzogRWRpdG9yVmlldywgcG9zOiBudW1iZXIpOiBIVE1MRWxlbWVudCB8IG51bGwge1xuICBjb25zdCBkb20gPSB2aWV3Lm5vZGVET00ocG9zKTtcbiAgaWYgKCFkb20pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBpZiAoZG9tIGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHtcbiAgICByZXR1cm4gZG9tO1xuICB9XG4gIHJldHVybiBkb20ucGFyZW50RWxlbWVudDtcbn1cblxuLy8gVkVSVElDQUwgU0NBTiAoRm9yIHRoZSBlbXB0eSBtYXJnaW4pXG5mdW5jdGlvbiBmaW5kQmxvY2tFbGVtZW50QXRZKHZpZXc6IEVkaXRvclZpZXcsIHk6IG51bWJlcik6IEhUTUxFbGVtZW50IHwgbnVsbCB7XG4gIGNvbnN0IGVkaXRvckRvbSA9IHZpZXcuZG9tIGFzIEhUTUxFbGVtZW50O1xuICBjb25zdCBjaGlsZHJlbiA9IEFycmF5LmZyb20oZWRpdG9yRG9tLmNoaWxkcmVuKSBhcyBIVE1MRWxlbWVudFtdO1xuXG4gIC8vIFdlIGxvb2sgZm9yIHRoZSBkaXJlY3QgY2hpbGQgb2YgdGhlIGVkaXRvciAoTGV2ZWwgMSkgdGhhdCBpbnRlcmNlcHRzIHRoZSBZIGxpbmVcbiAgcmV0dXJuIChcbiAgICBjaGlsZHJlbi5maW5kKGNoaWxkID0+IHtcbiAgICAgIGlmIChnZXRDb21wdXRlZFN0eWxlKGNoaWxkKS5wb3NpdGlvbiA9PT0gXCJhYnNvbHV0ZVwiKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHJlY3QgPSBjaGlsZC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIC8vIFRvbMOpcmFuY2UgZGUgNXB4XG4gICAgICByZXR1cm4geSA+PSByZWN0LnRvcCAtIDUgJiYgeSA8PSByZWN0LmJvdHRvbSArIDU7XG4gICAgfSkgfHwgbnVsbFxuICApO1xufVxuXG5mdW5jdGlvbiByZXNvbHZlQmxvY2tEYXRhKFxuICB2aWV3OiBFZGl0b3JWaWV3LFxuICB5OiBudW1iZXIsXG4gIHRhcmdldEVsZW1lbnQ6IEhUTUxFbGVtZW50IHwgbnVsbFxuKTogeyBub2RlOiBOb2RlOyBlbGVtZW50OiBIVE1MRWxlbWVudDsgcG9zOiBudW1iZXIgfSB8IG51bGwge1xuICBsZXQgYmxvY2tFbDogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcblxuICAvLyAxLiBGQVNUIFBBVEggOiBEaXJlY3QgdGFyZ2V0XG4gIC8vIExFVkVMIDE6IFdlIGxvb2sgZm9yIHRoZSBmaXJzdCBwYXJlbnQgZWxlbWVudCB0aGF0IGlzIGEgZGlyZWN0IGNoaWxkIG9mIHRoZSBlZGl0b3JcbiAgaWYgKHRhcmdldEVsZW1lbnQgJiYgIXRhcmdldEVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKFwiUHJvc2VNaXJyb3JcIikpIHtcbiAgICBibG9ja0VsID0gdGFyZ2V0RWxlbWVudC5jbG9zZXN0KFwiLlByb3NlTWlycm9yID4gKlwiKSBhcyBIVE1MRWxlbWVudDtcbiAgfVxuXG4gIC8vIDIuIEdVVFRFUiBQQVRIIDogVmVydGljYWwgc2NhblxuICBpZiAoIWJsb2NrRWwpIHtcbiAgICBibG9ja0VsID0gZmluZEJsb2NrRWxlbWVudEF0WSh2aWV3LCB5KTtcbiAgfVxuXG4gIGlmICghYmxvY2tFbCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLy8gMy4gUFJPU0VNSVJST1IgTk9ERSBSRVNPTFVUSU9OXG4gIHRyeSB7XG4gICAgLy8gV2UgYXNrIGZvciB0aGUgcG9zaXRpb24gYXQgdGhlIGJlZ2lubmluZyBvZiB0aGlzIHJvb3QgYmxvY2tcbiAgICBjb25zdCBwb3MgPSB2aWV3LnBvc0F0RE9NKGJsb2NrRWwsIDApO1xuICAgIGNvbnN0ICRwb3MgPSB2aWV3LnN0YXRlLmRvYy5yZXNvbHZlKHBvcyk7XG5cbiAgICAvLyBDQVNFIEEgOiBTVEFOREFSRCBCTE9DS1MgKEgxLCBQLCBMaXN0cywgQmxvY2txdW90ZXMuLi4pXG4gICAgLy8gV2UgbWFrZSBzdXJlIHRvIHRha2UgdGhlIG5vZGUgb2YgZGVwdGggMSAoRGlyZWN0IGNoaWxkIG9mIHRoZSBEb2MpXG4gICAgaWYgKCRwb3MuZGVwdGggPj0gMSkge1xuICAgICAgY29uc3Qgcm9vdE5vZGUgPSAkcG9zLm5vZGUoMSk7XG4gICAgICBjb25zdCByb290UG9zID0gJHBvcy5iZWZvcmUoMSk7XG4gICAgICBjb25zdCByb290RWxlbWVudCA9IGdldERvbUVsZW1lbnQodmlldywgcm9vdFBvcyk7XG5cbiAgICAgIC8vIFPDqWN1cml0w6kgOiBvbiB2w6lyaWZpZSBxdWUgbCfDqWzDqW1lbnQgRE9NIGNvcnJlc3BvbmQgYmllblxuICAgICAgaWYgKHJvb3ROb2RlICYmIChyb290RWxlbWVudCB8fCBibG9ja0VsKSkge1xuICAgICAgICByZXR1cm4geyBub2RlOiByb290Tm9kZSwgZWxlbWVudDogcm9vdEVsZW1lbnQgfHwgYmxvY2tFbCwgcG9zOiByb290UG9zIH07XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gQ0FTRSBCIDogSU1BR0VTIC8gQVRPTVMgKERlcHRoIDApXG4gICAgLy8gU29tZXRpbWVzIGEgcm9vdCBpbWFnZSBpcyBzZWVuIGFzIERlcHRoIDAgYnkgcmVzb2x2ZSgpXG4gICAgLy8gV2UgbG9vayBhdCB0aGUgbm9kZSByaWdodCBhZnRlciB0aGUgcG9zaXRpb25cbiAgICBpZiAoJHBvcy5kZXB0aCA9PT0gMCkge1xuICAgICAgY29uc3Qgbm9kZUFmdGVyID0gJHBvcy5ub2RlQWZ0ZXI7XG4gICAgICBpZiAobm9kZUFmdGVyICYmIChub2RlQWZ0ZXIuaXNCbG9jayB8fCBub2RlQWZ0ZXIuaXNBdG9tKSkge1xuICAgICAgICByZXR1cm4geyBub2RlOiBub2RlQWZ0ZXIsIGVsZW1lbnQ6IGJsb2NrRWwsIHBvczogcG9zIH07XG4gICAgICB9XG4gICAgfVxuICB9IGNhdGNoIChfZSkge1xuICAgIC8vIGNvbnNvbGUud2FybihfZSk7XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZXhwb3J0IGNvbnN0IEF0ZUJsb2NrQ29udHJvbHNFeHRlbnNpb24gPSBFeHRlbnNpb24uY3JlYXRlPEF0ZUJsb2NrQ29udHJvbHNPcHRpb25zPih7XG4gIG5hbWU6IFwiYXRlQmxvY2tDb250cm9sc1wiLFxuXG4gIGFkZE9wdGlvbnMoKSB7XG4gICAgcmV0dXJuIHsgb25Ib3ZlcjogdW5kZWZpbmVkIH07XG4gIH0sXG5cbiAgYWRkUHJvc2VNaXJyb3JQbHVnaW5zKCkge1xuICAgIGxldCBsYXN0SG92ZXJlZEVsZW1lbnQ6IEhUTUxFbGVtZW50IHwgbnVsbCA9IG51bGw7XG4gICAgbGV0IGxhc3RIb3ZlcmVkUG9zOiBudW1iZXIgfCBudWxsID0gbnVsbDtcbiAgICBsZXQgcmFmSWQ6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICAgIGxldCBsYXN0TW91c2VYID0gMDtcbiAgICBsZXQgbGFzdE1vdXNlWSA9IDA7XG5cbiAgICBjb25zdCB1cGRhdGUgPSAodmlldzogRWRpdG9yVmlldykgPT4ge1xuICAgICAgaWYgKCF0aGlzLmVkaXRvci5pc0VkaXRhYmxlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZWRpdG9yUmVjdCA9IHZpZXcuZG9tLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgY29uc3QgZ3V0dGVyV2lkdGggPSA4MDtcblxuICAgICAgLy8gQ2hlY2sgTGltaXRlcyAoTWFyZ2UgR2F1Y2hlICsgRWRpdGV1cilcbiAgICAgIGlmIChcbiAgICAgICAgbGFzdE1vdXNlWSA8IGVkaXRvclJlY3QudG9wIHx8XG4gICAgICAgIGxhc3RNb3VzZVkgPiBlZGl0b3JSZWN0LmJvdHRvbSB8fFxuICAgICAgICBsYXN0TW91c2VYID4gZWRpdG9yUmVjdC5yaWdodCB8fFxuICAgICAgICBsYXN0TW91c2VYIDwgZWRpdG9yUmVjdC5sZWZ0IC0gZ3V0dGVyV2lkdGhcbiAgICAgICkge1xuICAgICAgICBpZiAobGFzdEhvdmVyZWRFbGVtZW50KSB7XG4gICAgICAgICAgcmVzZXQoKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIC8vIFNUSUNLWSBBTlRJLUZMSUNLRVJcbiAgICAgIC8vIE9uIGdhcmRlIGxlIGJsb2MgdGFudCBxdSdvbiBlc3QgZGFucyBzYSBoYXV0ZXVyXG4gICAgICBpZiAobGFzdEhvdmVyZWRFbGVtZW50ICYmIGxhc3RIb3ZlcmVkRWxlbWVudC5pc0Nvbm5lY3RlZCkge1xuICAgICAgICBjb25zdCByZWN0ID0gbGFzdEhvdmVyZWRFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICBpZiAobGFzdE1vdXNlWSA+PSByZWN0LnRvcCAmJiBsYXN0TW91c2VZIDw9IHJlY3QuYm90dG9tKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHRhcmdldCA9IGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnQobGFzdE1vdXNlWCwgbGFzdE1vdXNlWSkgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICAgIGNvbnN0IGRhdGEgPSByZXNvbHZlQmxvY2tEYXRhKHZpZXcsIGxhc3RNb3VzZVksIHRhcmdldCk7XG5cbiAgICAgIGlmIChkYXRhICYmIChkYXRhLmVsZW1lbnQgIT09IGxhc3RIb3ZlcmVkRWxlbWVudCB8fCBkYXRhLnBvcyAhPT0gbGFzdEhvdmVyZWRQb3MpKSB7XG4gICAgICAgIGxhc3RIb3ZlcmVkRWxlbWVudCA9IGRhdGEuZWxlbWVudDtcbiAgICAgICAgbGFzdEhvdmVyZWRQb3MgPSBkYXRhLnBvcztcbiAgICAgICAgdGhpcy5vcHRpb25zLm9uSG92ZXI/LihkYXRhKTtcbiAgICAgIH0gZWxzZSBpZiAoIWRhdGEpIHtcbiAgICAgICAgaWYgKCFsYXN0SG92ZXJlZEVsZW1lbnQgfHwgIWxhc3RIb3ZlcmVkRWxlbWVudC5pc0Nvbm5lY3RlZCkge1xuICAgICAgICAgIHJlc2V0KCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3QgcmVzZXQgPSAoKSA9PiB7XG4gICAgICB0aGlzLm9wdGlvbnMub25Ib3Zlcj8uKG51bGwpO1xuICAgICAgbGFzdEhvdmVyZWRFbGVtZW50ID0gbnVsbDtcbiAgICAgIGxhc3RIb3ZlcmVkUG9zID0gbnVsbDtcbiAgICB9O1xuXG4gICAgcmV0dXJuIFtcbiAgICAgIG5ldyBQbHVnaW4oe1xuICAgICAgICBrZXk6IG5ldyBQbHVnaW5LZXkoXCJhdGVCbG9ja0NvbnRyb2xzXCIpLFxuICAgICAgICBwcm9wczoge1xuICAgICAgICAgIGhhbmRsZURPTUV2ZW50czoge1xuICAgICAgICAgICAgbW91c2Vtb3ZlOiAodmlldzogRWRpdG9yVmlldywgZXZlbnQ6IE1vdXNlRXZlbnQpID0+IHtcbiAgICAgICAgICAgICAgbGFzdE1vdXNlWCA9IGV2ZW50LmNsaWVudFg7XG4gICAgICAgICAgICAgIGxhc3RNb3VzZVkgPSBldmVudC5jbGllbnRZO1xuXG4gICAgICAgICAgICAgIGlmIChyYWZJZCA9PT0gbnVsbCkge1xuICAgICAgICAgICAgICAgIHJhZklkID0gd2luZG93LnJlcXVlc3RBbmltYXRpb25GcmFtZSgoKSA9PiB7XG4gICAgICAgICAgICAgICAgICB1cGRhdGUodmlldyk7XG4gICAgICAgICAgICAgICAgICByYWZJZCA9IG51bGw7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIG1vdXNlbGVhdmU6ICgpID0+IHtcbiAgICAgICAgICAgICAgaWYgKHJhZklkKSB7XG4gICAgICAgICAgICAgICAgd2luZG93LmNhbmNlbEFuaW1hdGlvbkZyYW1lKHJhZklkKTtcbiAgICAgICAgICAgICAgICByYWZJZCA9IG51bGw7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgcmVzZXQoKTtcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgXTtcbiAgfSxcbn0pO1xuIl19
@@ -0,0 +1,32 @@
1
+ import { Extension, getAttributes } from "@tiptap/core";
2
+ import { Plugin, PluginKey } from "@tiptap/pm/state";
3
+ export const AteLinkClickBehavior = Extension.create({
4
+ name: "linkClickBehavior",
5
+ addProseMirrorPlugins() {
6
+ return [
7
+ new Plugin({
8
+ key: new PluginKey("linkClickBehavior"),
9
+ props: {
10
+ handleClick(view, _pos, event) {
11
+ // handleClick only runs in the browser, but we guard it for absolute SSR safety
12
+ if (typeof window === "undefined") {
13
+ return false;
14
+ }
15
+ const isModKey = event.ctrlKey || event.metaKey;
16
+ // If editor is editable, only proceed if Ctrl/Cmd is pressed
17
+ if (view.editable && !isModKey) {
18
+ return false;
19
+ }
20
+ const attrs = getAttributes(view.state, "link");
21
+ if (attrs["href"]) {
22
+ window.open(attrs["href"], "_blank", "noopener,noreferrer");
23
+ return true;
24
+ }
25
+ return false;
26
+ },
27
+ },
28
+ }),
29
+ ];
30
+ },
31
+ });
32
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXRlLWxpbmstY2xpY2stYmVoYXZpb3IuZXh0ZW5zaW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvYW5ndWxhci10aXB0YXAtZWRpdG9yL3NyYy9saWIvZXh0ZW5zaW9ucy9hdGUtbGluay1jbGljay1iZWhhdmlvci5leHRlbnNpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxhQUFhLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDeEQsT0FBTyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUVyRCxNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxTQUFTLENBQUMsTUFBTSxDQUFDO0lBQ25ELElBQUksRUFBRSxtQkFBbUI7SUFFekIscUJBQXFCO1FBQ25CLE9BQU87WUFDTCxJQUFJLE1BQU0sQ0FBQztnQkFDVCxHQUFHLEVBQUUsSUFBSSxTQUFTLENBQUMsbUJBQW1CLENBQUM7Z0JBQ3ZDLEtBQUssRUFBRTtvQkFDTCxXQUFXLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxLQUFLO3dCQUMzQixnRkFBZ0Y7d0JBQ2hGLElBQUksT0FBTyxNQUFNLEtBQUssV0FBVyxFQUFFLENBQUM7NEJBQ2xDLE9BQU8sS0FBSyxDQUFDO3dCQUNmLENBQUM7d0JBRUQsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLE9BQU8sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDO3dCQUVoRCw2REFBNkQ7d0JBQzdELElBQUksSUFBSSxDQUFDLFFBQVEsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDOzRCQUMvQixPQUFPLEtBQUssQ0FBQzt3QkFDZixDQUFDO3dCQUVELE1BQU0sS0FBSyxHQUFHLGFBQWEsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO3dCQUNoRCxJQUFJLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDOzRCQUNsQixNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsRUFBRSxRQUFRLEVBQUUscUJBQXFCLENBQUMsQ0FBQzs0QkFDNUQsT0FBTyxJQUFJLENBQUM7d0JBQ2QsQ0FBQzt3QkFDRCxPQUFPLEtBQUssQ0FBQztvQkFDZixDQUFDO2lCQUNGO2FBQ0YsQ0FBQztTQUNILENBQUM7SUFDSixDQUFDO0NBQ0YsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgRXh0ZW5zaW9uLCBnZXRBdHRyaWJ1dGVzIH0gZnJvbSBcIkB0aXB0YXAvY29yZVwiO1xuaW1wb3J0IHsgUGx1Z2luLCBQbHVnaW5LZXkgfSBmcm9tIFwiQHRpcHRhcC9wbS9zdGF0ZVwiO1xuXG5leHBvcnQgY29uc3QgQXRlTGlua0NsaWNrQmVoYXZpb3IgPSBFeHRlbnNpb24uY3JlYXRlKHtcbiAgbmFtZTogXCJsaW5rQ2xpY2tCZWhhdmlvclwiLFxuXG4gIGFkZFByb3NlTWlycm9yUGx1Z2lucygpIHtcbiAgICByZXR1cm4gW1xuICAgICAgbmV3IFBsdWdpbih7XG4gICAgICAgIGtleTogbmV3IFBsdWdpbktleShcImxpbmtDbGlja0JlaGF2aW9yXCIpLFxuICAgICAgICBwcm9wczoge1xuICAgICAgICAgIGhhbmRsZUNsaWNrKHZpZXcsIF9wb3MsIGV2ZW50KSB7XG4gICAgICAgICAgICAvLyBoYW5kbGVDbGljayBvbmx5IHJ1bnMgaW4gdGhlIGJyb3dzZXIsIGJ1dCB3ZSBndWFyZCBpdCBmb3IgYWJzb2x1dGUgU1NSIHNhZmV0eVxuICAgICAgICAgICAgaWYgKHR5cGVvZiB3aW5kb3cgPT09IFwidW5kZWZpbmVkXCIpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBjb25zdCBpc01vZEtleSA9IGV2ZW50LmN0cmxLZXkgfHwgZXZlbnQubWV0YUtleTtcblxuICAgICAgICAgICAgLy8gSWYgZWRpdG9yIGlzIGVkaXRhYmxlLCBvbmx5IHByb2NlZWQgaWYgQ3RybC9DbWQgaXMgcHJlc3NlZFxuICAgICAgICAgICAgaWYgKHZpZXcuZWRpdGFibGUgJiYgIWlzTW9kS2V5KSB7XG4gICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgYXR0cnMgPSBnZXRBdHRyaWJ1dGVzKHZpZXcuc3RhdGUsIFwibGlua1wiKTtcbiAgICAgICAgICAgIGlmIChhdHRyc1tcImhyZWZcIl0pIHtcbiAgICAgICAgICAgICAgd2luZG93Lm9wZW4oYXR0cnNbXCJocmVmXCJdLCBcIl9ibGFua1wiLCBcIm5vb3BlbmVyLG5vcmVmZXJyZXJcIik7XG4gICAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICBdO1xuICB9LFxufSk7XG4iXX0=