@mhamz.01/easyflow-texteditor 0.1.150 → 0.1.152
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.css +24 -24
- package/dist/index.css.map +1 -1
- package/dist/index.js +283 -185
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +283 -185
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -2874,6 +2874,115 @@ function useTiptapEditor(providedEditor) {
|
|
|
2874
2874
|
return editorState || { editor: null };
|
|
2875
2875
|
}
|
|
2876
2876
|
|
|
2877
|
+
// src/hooks/mark-preservers/mark-preserver.ts
|
|
2878
|
+
var MarkPreserver = class {
|
|
2879
|
+
static preservedStyles = /* @__PURE__ */ new Map();
|
|
2880
|
+
/**
|
|
2881
|
+
* Preserve current font and color before blur or node change
|
|
2882
|
+
*/
|
|
2883
|
+
static preserve(editor) {
|
|
2884
|
+
if (!editor) return;
|
|
2885
|
+
try {
|
|
2886
|
+
const { state } = editor;
|
|
2887
|
+
const { $from } = state.selection;
|
|
2888
|
+
const currentNode = $from.parent;
|
|
2889
|
+
let font = currentNode.attrs.fontFamily;
|
|
2890
|
+
let color = currentNode.attrs.color;
|
|
2891
|
+
const marks = state.storedMarks || $from.marks();
|
|
2892
|
+
const textStyleMark = marks.find((m) => m.type.name === "textStyle");
|
|
2893
|
+
if (!font && textStyleMark?.attrs.fontFamily) {
|
|
2894
|
+
font = textStyleMark.attrs.fontFamily;
|
|
2895
|
+
}
|
|
2896
|
+
if (!color && textStyleMark?.attrs.color) {
|
|
2897
|
+
color = textStyleMark.attrs.color;
|
|
2898
|
+
}
|
|
2899
|
+
if (font || color) {
|
|
2900
|
+
this.preservedStyles.set(editor, { font, color });
|
|
2901
|
+
}
|
|
2902
|
+
} catch (error) {
|
|
2903
|
+
console.debug("MarkPreserver.preserve error:", error);
|
|
2904
|
+
}
|
|
2905
|
+
}
|
|
2906
|
+
/**
|
|
2907
|
+
* Restore preserved styles to current node
|
|
2908
|
+
*/
|
|
2909
|
+
static restore(editor, delay = 0) {
|
|
2910
|
+
if (!editor) return;
|
|
2911
|
+
const styles = this.preservedStyles.get(editor);
|
|
2912
|
+
if (!styles) return;
|
|
2913
|
+
const restoreFn = () => {
|
|
2914
|
+
if (editor.isDestroyed) {
|
|
2915
|
+
this.preservedStyles.delete(editor);
|
|
2916
|
+
return;
|
|
2917
|
+
}
|
|
2918
|
+
try {
|
|
2919
|
+
const { state } = editor;
|
|
2920
|
+
const { $from } = state.selection;
|
|
2921
|
+
const depth = $from.depth;
|
|
2922
|
+
const pos = $from.before(depth);
|
|
2923
|
+
const node = $from.node(depth);
|
|
2924
|
+
const supportsAttributes = [
|
|
2925
|
+
"paragraph",
|
|
2926
|
+
"heading",
|
|
2927
|
+
"listItem",
|
|
2928
|
+
"taskItem",
|
|
2929
|
+
"blockquote"
|
|
2930
|
+
].includes(node.type.name);
|
|
2931
|
+
if (!supportsAttributes) {
|
|
2932
|
+
this.preservedStyles.delete(editor);
|
|
2933
|
+
editor.commands.focus();
|
|
2934
|
+
return;
|
|
2935
|
+
}
|
|
2936
|
+
const updates = {};
|
|
2937
|
+
if (styles.font && !node.attrs.fontFamily) {
|
|
2938
|
+
updates.fontFamily = styles.font;
|
|
2939
|
+
}
|
|
2940
|
+
if (styles.color && !node.attrs.color) {
|
|
2941
|
+
updates.color = styles.color;
|
|
2942
|
+
}
|
|
2943
|
+
if (Object.keys(updates).length > 0) {
|
|
2944
|
+
const newAttrs = { ...node.attrs, ...updates };
|
|
2945
|
+
editor.view.dispatch(
|
|
2946
|
+
state.tr.setNodeMarkup(pos, void 0, newAttrs)
|
|
2947
|
+
);
|
|
2948
|
+
}
|
|
2949
|
+
const marks = state.storedMarks || $from.marks();
|
|
2950
|
+
const filteredMarks = marks.filter((mark) => mark.type.name !== "textStyle");
|
|
2951
|
+
const textStyleAttrs = {};
|
|
2952
|
+
if (styles.font) textStyleAttrs.fontFamily = styles.font;
|
|
2953
|
+
if (styles.color) textStyleAttrs.color = styles.color;
|
|
2954
|
+
const newMarks = [
|
|
2955
|
+
...filteredMarks,
|
|
2956
|
+
state.schema.marks.textStyle.create(textStyleAttrs)
|
|
2957
|
+
];
|
|
2958
|
+
setTimeout(() => {
|
|
2959
|
+
if (!editor.isDestroyed) {
|
|
2960
|
+
editor.view.dispatch(
|
|
2961
|
+
editor.state.tr.setStoredMarks(newMarks)
|
|
2962
|
+
);
|
|
2963
|
+
editor.commands.focus();
|
|
2964
|
+
}
|
|
2965
|
+
}, 0);
|
|
2966
|
+
} catch (error) {
|
|
2967
|
+
console.debug("MarkPreserver.restore error:", error);
|
|
2968
|
+
} finally {
|
|
2969
|
+
this.preservedStyles.delete(editor);
|
|
2970
|
+
}
|
|
2971
|
+
};
|
|
2972
|
+
if (delay > 0) {
|
|
2973
|
+
setTimeout(restoreFn, delay);
|
|
2974
|
+
} else {
|
|
2975
|
+
restoreFn();
|
|
2976
|
+
}
|
|
2977
|
+
}
|
|
2978
|
+
/**
|
|
2979
|
+
* Clear preserved styles
|
|
2980
|
+
*/
|
|
2981
|
+
static clear(editor) {
|
|
2982
|
+
this.preservedStyles.delete(editor);
|
|
2983
|
+
}
|
|
2984
|
+
};
|
|
2985
|
+
|
|
2877
2986
|
// src/components/tiptap-ui/heading-button/heading-button.tsx
|
|
2878
2987
|
import { forwardRef as forwardRef6, useCallback as useCallback8 } from "react";
|
|
2879
2988
|
|
|
@@ -3478,9 +3587,15 @@ var HeadingDropdownMenu = forwardRef9(
|
|
|
3478
3587
|
if (!editor || !canToggle2) return;
|
|
3479
3588
|
setIsOpen(open);
|
|
3480
3589
|
onOpenChange?.(open);
|
|
3590
|
+
if (!open) {
|
|
3591
|
+
MarkPreserver.restore(editor, 10);
|
|
3592
|
+
}
|
|
3481
3593
|
},
|
|
3482
3594
|
[canToggle2, editor, onOpenChange]
|
|
3483
3595
|
);
|
|
3596
|
+
const handlePointerDown = useCallback10(() => {
|
|
3597
|
+
MarkPreserver.preserve(editor);
|
|
3598
|
+
}, [editor]);
|
|
3484
3599
|
if (!isVisible) {
|
|
3485
3600
|
return null;
|
|
3486
3601
|
}
|
|
@@ -3496,6 +3611,7 @@ var HeadingDropdownMenu = forwardRef9(
|
|
|
3496
3611
|
"aria-label": "Format text as heading",
|
|
3497
3612
|
"aria-pressed": isActive,
|
|
3498
3613
|
tooltip: "Heading",
|
|
3614
|
+
onPointerDown: handlePointerDown,
|
|
3499
3615
|
...buttonProps,
|
|
3500
3616
|
ref,
|
|
3501
3617
|
children: [
|
|
@@ -4383,9 +4499,15 @@ function ListDropdownMenu({
|
|
|
4383
4499
|
(open) => {
|
|
4384
4500
|
setIsOpen(open);
|
|
4385
4501
|
onOpenChange?.(open);
|
|
4502
|
+
if (!open) {
|
|
4503
|
+
MarkPreserver.restore(editor, 10);
|
|
4504
|
+
}
|
|
4386
4505
|
},
|
|
4387
|
-
[onOpenChange]
|
|
4506
|
+
[onOpenChange, editor]
|
|
4388
4507
|
);
|
|
4508
|
+
const handlePointerDown = useCallback15(() => {
|
|
4509
|
+
MarkPreserver.preserve(editor);
|
|
4510
|
+
}, [editor]);
|
|
4389
4511
|
if (!isVisible) {
|
|
4390
4512
|
return null;
|
|
4391
4513
|
}
|
|
@@ -4402,6 +4524,7 @@ function ListDropdownMenu({
|
|
|
4402
4524
|
"data-disabled": !canToggle2,
|
|
4403
4525
|
"aria-label": "List options",
|
|
4404
4526
|
tooltip: "List",
|
|
4527
|
+
onPointerDown: handlePointerDown,
|
|
4405
4528
|
...props,
|
|
4406
4529
|
children: [
|
|
4407
4530
|
/* @__PURE__ */ jsx44(Icon, { className: "tiptap-button-icon" }),
|
|
@@ -4423,56 +4546,6 @@ function ListDropdownMenu({
|
|
|
4423
4546
|
|
|
4424
4547
|
// src/components/tiptap-ui/blockquote-button/blockquote-button.tsx
|
|
4425
4548
|
import { forwardRef as forwardRef12, useCallback as useCallback16 } from "react";
|
|
4426
|
-
|
|
4427
|
-
// src/hooks/mark-preservers/mark-preserver.ts
|
|
4428
|
-
var MarkPreserver = class {
|
|
4429
|
-
static preservedMarks = /* @__PURE__ */ new Map();
|
|
4430
|
-
/**
|
|
4431
|
-
* Preserve marks before an action that will cause blur
|
|
4432
|
-
* Call this in onMouseDown or onPointerDown events
|
|
4433
|
-
*/
|
|
4434
|
-
static preserve(editor) {
|
|
4435
|
-
if (!editor) return;
|
|
4436
|
-
const { state } = editor;
|
|
4437
|
-
const { $from } = state.selection;
|
|
4438
|
-
const currentMarks = state.storedMarks || $from.marks();
|
|
4439
|
-
if (currentMarks.length > 0) {
|
|
4440
|
-
this.preservedMarks.set(editor, [...currentMarks]);
|
|
4441
|
-
}
|
|
4442
|
-
}
|
|
4443
|
-
/**
|
|
4444
|
-
* Restore marks after an action completes
|
|
4445
|
-
* Call this after the editor action in onClick or in a setTimeout
|
|
4446
|
-
*/
|
|
4447
|
-
static restore(editor, delay = 0) {
|
|
4448
|
-
if (!editor) return;
|
|
4449
|
-
const marks = this.preservedMarks.get(editor);
|
|
4450
|
-
if (!marks) return;
|
|
4451
|
-
const restoreFn = () => {
|
|
4452
|
-
if (editor.isDestroyed) {
|
|
4453
|
-
this.preservedMarks.delete(editor);
|
|
4454
|
-
return;
|
|
4455
|
-
}
|
|
4456
|
-
const { state } = editor;
|
|
4457
|
-
editor.view.dispatch(state.tr.setStoredMarks(marks));
|
|
4458
|
-
this.preservedMarks.delete(editor);
|
|
4459
|
-
editor.commands.focus();
|
|
4460
|
-
};
|
|
4461
|
-
if (delay > 0) {
|
|
4462
|
-
setTimeout(restoreFn, delay);
|
|
4463
|
-
} else {
|
|
4464
|
-
restoreFn();
|
|
4465
|
-
}
|
|
4466
|
-
}
|
|
4467
|
-
/**
|
|
4468
|
-
* Clear preserved marks for an editor
|
|
4469
|
-
*/
|
|
4470
|
-
static clear(editor) {
|
|
4471
|
-
this.preservedMarks.delete(editor);
|
|
4472
|
-
}
|
|
4473
|
-
};
|
|
4474
|
-
|
|
4475
|
-
// src/components/tiptap-ui/blockquote-button/blockquote-button.tsx
|
|
4476
4549
|
import { Fragment as Fragment7, jsx as jsx45, jsxs as jsxs26 } from "react/jsx-runtime";
|
|
4477
4550
|
function BlockquoteShortcutBadge({
|
|
4478
4551
|
shortcutKeys = BLOCKQUOTE_SHORTCUT_KEY
|
|
@@ -7622,6 +7695,7 @@ function useCursorVisibility({
|
|
|
7622
7695
|
|
|
7623
7696
|
// src/components/extensions/font-family-block.ts
|
|
7624
7697
|
import { Extension as Extension2 } from "@tiptap/core";
|
|
7698
|
+
import { Plugin, PluginKey } from "@tiptap/pm/state";
|
|
7625
7699
|
var FontFamilyBlock = Extension2.create({
|
|
7626
7700
|
name: "fontFamilyBlock",
|
|
7627
7701
|
addGlobalAttributes() {
|
|
@@ -7678,150 +7752,174 @@ var ColorBlock = Extension2.create({
|
|
|
7678
7752
|
];
|
|
7679
7753
|
}
|
|
7680
7754
|
});
|
|
7755
|
+
var stylePersistenceKey = new PluginKey("stylePersistence");
|
|
7681
7756
|
var StylePersistence = Extension2.create({
|
|
7682
7757
|
name: "stylePersistence",
|
|
7683
7758
|
addOptions() {
|
|
7684
7759
|
return {
|
|
7685
|
-
// Marks that should NOT inherit font family or color
|
|
7686
7760
|
excludedMarks: ["code", "codeBlock"]
|
|
7687
7761
|
};
|
|
7688
7762
|
},
|
|
7689
|
-
|
|
7690
|
-
return {
|
|
7691
|
-
// Store marks temporarily when editor loses focus
|
|
7692
|
-
preservedMarks: null,
|
|
7693
|
-
// Store marks from the previous node (for Enter key handling)
|
|
7694
|
-
previousNodeMarks: null
|
|
7695
|
-
};
|
|
7696
|
-
},
|
|
7697
|
-
addKeyboardShortcuts() {
|
|
7698
|
-
return {
|
|
7699
|
-
// Handle Enter key to preserve marks when creating new paragraphs
|
|
7700
|
-
"Enter": ({ editor }) => {
|
|
7701
|
-
const { state } = editor;
|
|
7702
|
-
const { $from } = state.selection;
|
|
7703
|
-
const currentNode = $from.parent;
|
|
7704
|
-
const blockFont = currentNode.attrs.fontFamily;
|
|
7705
|
-
const blockColor = currentNode.attrs.color;
|
|
7706
|
-
if (blockFont || blockColor) {
|
|
7707
|
-
this.storage.previousNodeMarks = { blockFont, blockColor };
|
|
7708
|
-
}
|
|
7709
|
-
return false;
|
|
7710
|
-
},
|
|
7711
|
-
// Handle Shift+Enter (soft break) - same logic
|
|
7712
|
-
"Shift-Enter": ({ editor }) => {
|
|
7713
|
-
const { state } = editor;
|
|
7714
|
-
const { $from } = state.selection;
|
|
7715
|
-
const currentNode = $from.parent;
|
|
7716
|
-
const blockFont = currentNode.attrs.fontFamily;
|
|
7717
|
-
const blockColor = currentNode.attrs.color;
|
|
7718
|
-
if (blockFont || blockColor) {
|
|
7719
|
-
this.storage.previousNodeMarks = { blockFont, blockColor };
|
|
7720
|
-
}
|
|
7721
|
-
return false;
|
|
7722
|
-
}
|
|
7723
|
-
};
|
|
7724
|
-
},
|
|
7725
|
-
onSelectionUpdate({ editor }) {
|
|
7763
|
+
addProseMirrorPlugins() {
|
|
7726
7764
|
const excludedMarks = this.options.excludedMarks;
|
|
7727
|
-
|
|
7728
|
-
|
|
7729
|
-
|
|
7730
|
-
|
|
7731
|
-
|
|
7732
|
-
|
|
7733
|
-
|
|
7734
|
-
|
|
7735
|
-
|
|
7736
|
-
|
|
7737
|
-
|
|
7738
|
-
|
|
7739
|
-
|
|
7740
|
-
|
|
7741
|
-
|
|
7742
|
-
|
|
7743
|
-
|
|
7744
|
-
|
|
7745
|
-
|
|
7746
|
-
|
|
7747
|
-
|
|
7748
|
-
|
|
7749
|
-
|
|
7750
|
-
|
|
7751
|
-
|
|
7752
|
-
|
|
7753
|
-
|
|
7754
|
-
|
|
7755
|
-
|
|
7756
|
-
|
|
7757
|
-
|
|
7758
|
-
|
|
7759
|
-
|
|
7765
|
+
return [
|
|
7766
|
+
new Plugin({
|
|
7767
|
+
key: stylePersistenceKey,
|
|
7768
|
+
state: {
|
|
7769
|
+
init() {
|
|
7770
|
+
return {
|
|
7771
|
+
lastFont: null,
|
|
7772
|
+
lastColor: null
|
|
7773
|
+
};
|
|
7774
|
+
},
|
|
7775
|
+
apply(tr, value, oldState, newState) {
|
|
7776
|
+
const { $from } = newState.selection;
|
|
7777
|
+
const marks = $from.marks();
|
|
7778
|
+
const hasExcludedMarks = marks.some(
|
|
7779
|
+
(mark) => excludedMarks.includes(mark.type.name)
|
|
7780
|
+
);
|
|
7781
|
+
let isInCodeBlock = false;
|
|
7782
|
+
for (let depth = $from.depth; depth > 0; depth--) {
|
|
7783
|
+
const node = $from.node(depth);
|
|
7784
|
+
if (node.type.name === "codeBlock") {
|
|
7785
|
+
isInCodeBlock = true;
|
|
7786
|
+
break;
|
|
7787
|
+
}
|
|
7788
|
+
}
|
|
7789
|
+
if (hasExcludedMarks || isInCodeBlock) {
|
|
7790
|
+
return value;
|
|
7791
|
+
}
|
|
7792
|
+
const parentNode = $from.parent;
|
|
7793
|
+
let font = parentNode.attrs.fontFamily;
|
|
7794
|
+
let color = parentNode.attrs.color;
|
|
7795
|
+
const textStyleMark = marks.find((m) => m.type.name === "textStyle");
|
|
7796
|
+
if (!font && textStyleMark?.attrs.fontFamily) {
|
|
7797
|
+
font = textStyleMark.attrs.fontFamily;
|
|
7798
|
+
}
|
|
7799
|
+
if (!color && textStyleMark?.attrs.color) {
|
|
7800
|
+
color = textStyleMark.attrs.color;
|
|
7801
|
+
}
|
|
7802
|
+
return {
|
|
7803
|
+
lastFont: font || value.lastFont,
|
|
7804
|
+
lastColor: color || value.lastColor
|
|
7805
|
+
};
|
|
7806
|
+
}
|
|
7807
|
+
},
|
|
7808
|
+
appendTransaction(transactions, oldState, newState) {
|
|
7809
|
+
if (!transactions.some((tr2) => tr2.docChanged)) {
|
|
7810
|
+
return null;
|
|
7811
|
+
}
|
|
7812
|
+
const pluginState = stylePersistenceKey.getState(newState);
|
|
7813
|
+
if (!pluginState.lastFont && !pluginState.lastColor) {
|
|
7814
|
+
return null;
|
|
7815
|
+
}
|
|
7816
|
+
const { $from } = newState.selection;
|
|
7817
|
+
const parentNode = $from.parent;
|
|
7818
|
+
const marks = $from.marks();
|
|
7819
|
+
const hasExcludedMarks = marks.some(
|
|
7820
|
+
(mark) => excludedMarks.includes(mark.type.name)
|
|
7821
|
+
);
|
|
7822
|
+
let isInCodeBlock = false;
|
|
7823
|
+
for (let depth = $from.depth; depth > 0; depth--) {
|
|
7824
|
+
const node = $from.node(depth);
|
|
7825
|
+
if (node.type.name === "codeBlock") {
|
|
7826
|
+
isInCodeBlock = true;
|
|
7827
|
+
break;
|
|
7828
|
+
}
|
|
7829
|
+
}
|
|
7830
|
+
if (hasExcludedMarks || isInCodeBlock) {
|
|
7831
|
+
return null;
|
|
7832
|
+
}
|
|
7833
|
+
const supportsAttributes = [
|
|
7834
|
+
"paragraph",
|
|
7835
|
+
"heading",
|
|
7836
|
+
"listItem",
|
|
7837
|
+
"taskItem",
|
|
7838
|
+
"blockquote"
|
|
7839
|
+
].includes(parentNode.type.name);
|
|
7840
|
+
if (!supportsAttributes) {
|
|
7841
|
+
return null;
|
|
7842
|
+
}
|
|
7843
|
+
const currentFont = parentNode.attrs.fontFamily;
|
|
7844
|
+
const currentColor = parentNode.attrs.color;
|
|
7845
|
+
const needsFont = !currentFont && pluginState.lastFont;
|
|
7846
|
+
const needsColor = !currentColor && pluginState.lastColor;
|
|
7847
|
+
if (!needsFont && !needsColor) {
|
|
7848
|
+
return null;
|
|
7849
|
+
}
|
|
7850
|
+
const tr = newState.tr;
|
|
7851
|
+
try {
|
|
7852
|
+
const depth = $from.depth;
|
|
7853
|
+
const pos = $from.before(depth);
|
|
7854
|
+
const node = $from.node(depth);
|
|
7855
|
+
const newAttrs = { ...node.attrs };
|
|
7856
|
+
if (needsFont) newAttrs.fontFamily = pluginState.lastFont;
|
|
7857
|
+
if (needsColor) newAttrs.color = pluginState.lastColor;
|
|
7858
|
+
tr.setNodeMarkup(pos, void 0, newAttrs);
|
|
7859
|
+
const storedMarks = newState.storedMarks || $from.marks();
|
|
7860
|
+
const filteredMarks = storedMarks.filter(
|
|
7861
|
+
(mark) => mark.type.name !== "textStyle" && !excludedMarks.includes(mark.type.name)
|
|
7862
|
+
);
|
|
7863
|
+
const textStyleAttrs = {};
|
|
7864
|
+
if (pluginState.lastFont) textStyleAttrs.fontFamily = pluginState.lastFont;
|
|
7865
|
+
if (pluginState.lastColor) textStyleAttrs.color = pluginState.lastColor;
|
|
7866
|
+
const newMarks = [
|
|
7867
|
+
...filteredMarks,
|
|
7868
|
+
newState.schema.marks.textStyle.create(textStyleAttrs)
|
|
7869
|
+
];
|
|
7870
|
+
tr.setStoredMarks(newMarks);
|
|
7871
|
+
return tr;
|
|
7872
|
+
} catch (error) {
|
|
7873
|
+
console.error("StylePersistence error:", error);
|
|
7874
|
+
return null;
|
|
7875
|
+
}
|
|
7876
|
+
},
|
|
7877
|
+
props: {
|
|
7878
|
+
handleKeyDown(view, event) {
|
|
7879
|
+
if (event.key === "Enter") {
|
|
7880
|
+
const { state } = view;
|
|
7881
|
+
const { $from } = state.selection;
|
|
7882
|
+
const marks = $from.marks();
|
|
7883
|
+
const hasExcludedMarks = marks.some(
|
|
7884
|
+
(mark) => excludedMarks.includes(mark.type.name)
|
|
7885
|
+
);
|
|
7886
|
+
if (hasExcludedMarks) {
|
|
7887
|
+
return false;
|
|
7888
|
+
}
|
|
7889
|
+
let isInCodeBlock = false;
|
|
7890
|
+
for (let depth = $from.depth; depth > 0; depth--) {
|
|
7891
|
+
const node = $from.node(depth);
|
|
7892
|
+
if (node.type.name === "codeBlock") {
|
|
7893
|
+
isInCodeBlock = true;
|
|
7894
|
+
break;
|
|
7895
|
+
}
|
|
7896
|
+
}
|
|
7897
|
+
if (isInCodeBlock) {
|
|
7898
|
+
return false;
|
|
7899
|
+
}
|
|
7900
|
+
const parentNode = $from.parent;
|
|
7901
|
+
let font = parentNode.attrs.fontFamily;
|
|
7902
|
+
let color = parentNode.attrs.color;
|
|
7903
|
+
const textStyleMark = marks.find((m) => m.type.name === "textStyle");
|
|
7904
|
+
if (!font && textStyleMark?.attrs.fontFamily) {
|
|
7905
|
+
font = textStyleMark.attrs.fontFamily;
|
|
7906
|
+
}
|
|
7907
|
+
if (!color && textStyleMark?.attrs.color) {
|
|
7908
|
+
color = textStyleMark.attrs.color;
|
|
7909
|
+
}
|
|
7910
|
+
if (font || color) {
|
|
7911
|
+
const pluginState = stylePersistenceKey.getState(state);
|
|
7912
|
+
pluginState.lastFont = font || pluginState.lastFont;
|
|
7913
|
+
pluginState.lastColor = color || pluginState.lastColor;
|
|
7914
|
+
}
|
|
7915
|
+
}
|
|
7916
|
+
return false;
|
|
7917
|
+
}
|
|
7918
|
+
}
|
|
7919
|
+
})
|
|
7920
|
+
];
|
|
7760
7921
|
}
|
|
7761
7922
|
});
|
|
7762
|
-
function syncStoredMarks(editor, excludedMarks, storage) {
|
|
7763
|
-
const { state } = editor;
|
|
7764
|
-
const { $from } = state.selection;
|
|
7765
|
-
const marks = $from.marks();
|
|
7766
|
-
const hasExcludedMarks = marks.some(
|
|
7767
|
-
(mark) => excludedMarks.includes(mark.type.name)
|
|
7768
|
-
);
|
|
7769
|
-
let isInCodeBlock = false;
|
|
7770
|
-
for (let depth = $from.depth; depth > 0; depth--) {
|
|
7771
|
-
const node = $from.node(depth);
|
|
7772
|
-
if (node.type.name === "codeBlock") {
|
|
7773
|
-
isInCodeBlock = true;
|
|
7774
|
-
break;
|
|
7775
|
-
}
|
|
7776
|
-
}
|
|
7777
|
-
if (hasExcludedMarks || isInCodeBlock) {
|
|
7778
|
-
return;
|
|
7779
|
-
}
|
|
7780
|
-
const parentNode = $from.parent;
|
|
7781
|
-
let blockFont = parentNode.attrs.fontFamily;
|
|
7782
|
-
let blockColor = parentNode.attrs.color;
|
|
7783
|
-
if ((!blockFont || !blockColor) && storage?.previousNodeMarks) {
|
|
7784
|
-
if (!blockFont && storage.previousNodeMarks.blockFont) {
|
|
7785
|
-
blockFont = storage.previousNodeMarks.blockFont;
|
|
7786
|
-
}
|
|
7787
|
-
if (!blockColor && storage.previousNodeMarks.blockColor) {
|
|
7788
|
-
blockColor = storage.previousNodeMarks.blockColor;
|
|
7789
|
-
}
|
|
7790
|
-
if (blockFont || blockColor) {
|
|
7791
|
-
const depth = $from.depth;
|
|
7792
|
-
const nodePos = $from.before(depth);
|
|
7793
|
-
const node = $from.node(depth);
|
|
7794
|
-
const newAttrs = { ...node.attrs };
|
|
7795
|
-
if (blockFont) newAttrs.fontFamily = blockFont;
|
|
7796
|
-
if (blockColor) newAttrs.color = blockColor;
|
|
7797
|
-
const tr = state.tr.setNodeMarkup(nodePos, void 0, newAttrs);
|
|
7798
|
-
editor.view.dispatch(tr);
|
|
7799
|
-
}
|
|
7800
|
-
storage.previousNodeMarks = null;
|
|
7801
|
-
}
|
|
7802
|
-
if (!blockFont && !blockColor) {
|
|
7803
|
-
return;
|
|
7804
|
-
}
|
|
7805
|
-
const storedMarks = state.storedMarks || $from.marks();
|
|
7806
|
-
const existingTextStyle = storedMarks.find((mark) => mark.type.name === "textStyle");
|
|
7807
|
-
const needsUpdate = !existingTextStyle || blockFont && existingTextStyle.attrs.fontFamily !== blockFont || blockColor && existingTextStyle.attrs.color !== blockColor;
|
|
7808
|
-
if (!needsUpdate) {
|
|
7809
|
-
return;
|
|
7810
|
-
}
|
|
7811
|
-
const filteredMarks = storedMarks.filter(
|
|
7812
|
-
(mark) => mark.type.name !== "textStyle" && !excludedMarks.includes(mark.type.name)
|
|
7813
|
-
);
|
|
7814
|
-
const textStyleAttrs = {};
|
|
7815
|
-
if (blockFont) textStyleAttrs.fontFamily = blockFont;
|
|
7816
|
-
if (blockColor) textStyleAttrs.color = blockColor;
|
|
7817
|
-
const newMarks = [
|
|
7818
|
-
...filteredMarks,
|
|
7819
|
-
state.schema.marks.textStyle.create(textStyleAttrs)
|
|
7820
|
-
];
|
|
7821
|
-
editor.view.dispatch(
|
|
7822
|
-
state.tr.setStoredMarks(newMarks)
|
|
7823
|
-
);
|
|
7824
|
-
}
|
|
7825
7923
|
|
|
7826
7924
|
// src/components/tiptap-templates/simple/simple-editor.tsx
|
|
7827
7925
|
import { Fragment as Fragment12, jsx as jsx81, jsxs as jsxs48 } from "react/jsx-runtime";
|