@mhamz.01/easyflow-texteditor 0.1.151 → 0.1.153
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 +363 -159
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +363 -159
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1338,6 +1338,80 @@ import Color from "@tiptap/extension-color";
|
|
|
1338
1338
|
import { TableKit } from "@tiptap/extension-table";
|
|
1339
1339
|
import { Dropcursor } from "@tiptap/extensions";
|
|
1340
1340
|
|
|
1341
|
+
// src/components/extensions/list-marker-color.tsx
|
|
1342
|
+
import { Extension } from "@tiptap/core";
|
|
1343
|
+
var ListMarkerColor = Extension.create({
|
|
1344
|
+
name: "listMarkerColor",
|
|
1345
|
+
addGlobalAttributes() {
|
|
1346
|
+
return [
|
|
1347
|
+
{
|
|
1348
|
+
types: ["listItem", "taskItem"],
|
|
1349
|
+
attributes: {
|
|
1350
|
+
// Inherit color attribute from ColorBlock extension
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
];
|
|
1354
|
+
},
|
|
1355
|
+
addProseMirrorPlugins() {
|
|
1356
|
+
return [];
|
|
1357
|
+
},
|
|
1358
|
+
// Add CSS to make markers inherit color
|
|
1359
|
+
addOptions() {
|
|
1360
|
+
return {
|
|
1361
|
+
// CSS will be injected into the editor
|
|
1362
|
+
};
|
|
1363
|
+
},
|
|
1364
|
+
onCreate() {
|
|
1365
|
+
if (typeof document !== "undefined") {
|
|
1366
|
+
const styleId = "tiptap-list-marker-color";
|
|
1367
|
+
if (!document.getElementById(styleId)) {
|
|
1368
|
+
const style = document.createElement("style");
|
|
1369
|
+
style.id = styleId;
|
|
1370
|
+
style.textContent = `
|
|
1371
|
+
/* Bullet list markers inherit color */
|
|
1372
|
+
.ProseMirror ul[data-type="bulletList"] > li[style*="color"]::marker,
|
|
1373
|
+
.ProseMirror ul li[style*="color"]::marker {
|
|
1374
|
+
color: inherit !important;
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
/* Ordered list numbers inherit color */
|
|
1378
|
+
.ProseMirror ol[data-type="orderedList"] > li[style*="color"]::marker,
|
|
1379
|
+
.ProseMirror ol li[style*="color"]::marker {
|
|
1380
|
+
color: inherit !important;
|
|
1381
|
+
}
|
|
1382
|
+
|
|
1383
|
+
/* Task list checkboxes inherit color */
|
|
1384
|
+
.ProseMirror ul[data-type="taskList"] > li[style*="color"] > label > input[type="checkbox"],
|
|
1385
|
+
.ProseMirror ul[data-type="taskList"] li[style*="color"] > label > input[type="checkbox"] {
|
|
1386
|
+
accent-color: currentColor;
|
|
1387
|
+
}
|
|
1388
|
+
|
|
1389
|
+
/* Alternative: Style the checkbox wrapper */
|
|
1390
|
+
.ProseMirror ul[data-type="taskList"] > li[style*="color"] > label,
|
|
1391
|
+
.ProseMirror ul[data-type="taskList"] li[style*="color"] > label {
|
|
1392
|
+
color: inherit;
|
|
1393
|
+
}
|
|
1394
|
+
|
|
1395
|
+
/* Ensure nested lists also inherit */
|
|
1396
|
+
.ProseMirror li[style*="color"] ul > li::marker,
|
|
1397
|
+
.ProseMirror li[style*="color"] ol > li::marker {
|
|
1398
|
+
color: inherit !important;
|
|
1399
|
+
}
|
|
1400
|
+
`;
|
|
1401
|
+
document.head.appendChild(style);
|
|
1402
|
+
}
|
|
1403
|
+
}
|
|
1404
|
+
},
|
|
1405
|
+
onDestroy() {
|
|
1406
|
+
if (typeof document !== "undefined") {
|
|
1407
|
+
const styleElement = document.getElementById("tiptap-list-marker-color");
|
|
1408
|
+
if (styleElement) {
|
|
1409
|
+
styleElement.remove();
|
|
1410
|
+
}
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
});
|
|
1414
|
+
|
|
1341
1415
|
// src/components/tiptap-ui-primitive/button/button.tsx
|
|
1342
1416
|
import { forwardRef as forwardRef2, Fragment as Fragment2, useMemo as useMemo4 } from "react";
|
|
1343
1417
|
|
|
@@ -1513,7 +1587,7 @@ import {
|
|
|
1513
1587
|
Selection,
|
|
1514
1588
|
TextSelection
|
|
1515
1589
|
} from "@tiptap/pm/state";
|
|
1516
|
-
import { Extension } from "@tiptap/core";
|
|
1590
|
+
import { Extension as Extension2 } from "@tiptap/core";
|
|
1517
1591
|
var MAX_FILE_SIZE = 5 * 1024 * 1024;
|
|
1518
1592
|
var MAC_SYMBOLS = {
|
|
1519
1593
|
mod: "\u2318",
|
|
@@ -1756,7 +1830,7 @@ var FONT_SIZES = [
|
|
|
1756
1830
|
"56px",
|
|
1757
1831
|
"64px"
|
|
1758
1832
|
];
|
|
1759
|
-
var FontSizeExtension =
|
|
1833
|
+
var FontSizeExtension = Extension2.create({
|
|
1760
1834
|
name: "fontSize",
|
|
1761
1835
|
addOptions() {
|
|
1762
1836
|
return {
|
|
@@ -2876,37 +2950,98 @@ function useTiptapEditor(providedEditor) {
|
|
|
2876
2950
|
|
|
2877
2951
|
// src/hooks/mark-preservers/mark-preserver.ts
|
|
2878
2952
|
var MarkPreserver = class {
|
|
2879
|
-
static
|
|
2953
|
+
static preservedStyles = /* @__PURE__ */ new Map();
|
|
2880
2954
|
/**
|
|
2881
|
-
* Preserve
|
|
2882
|
-
* Call this in onMouseDown or onPointerDown events
|
|
2955
|
+
* Preserve current font and color before blur or node change
|
|
2883
2956
|
*/
|
|
2884
2957
|
static preserve(editor) {
|
|
2885
2958
|
if (!editor) return;
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
|
|
2889
|
-
|
|
2890
|
-
|
|
2959
|
+
try {
|
|
2960
|
+
const { state } = editor;
|
|
2961
|
+
const { $from } = state.selection;
|
|
2962
|
+
const currentNode = $from.parent;
|
|
2963
|
+
let font = currentNode.attrs.fontFamily;
|
|
2964
|
+
let color = currentNode.attrs.color;
|
|
2965
|
+
const marks = state.storedMarks || $from.marks();
|
|
2966
|
+
const textStyleMark = marks.find((m) => m.type.name === "textStyle");
|
|
2967
|
+
if (!font && textStyleMark?.attrs.fontFamily) {
|
|
2968
|
+
font = textStyleMark.attrs.fontFamily;
|
|
2969
|
+
}
|
|
2970
|
+
if (!color && textStyleMark?.attrs.color) {
|
|
2971
|
+
color = textStyleMark.attrs.color;
|
|
2972
|
+
}
|
|
2973
|
+
if (font || color) {
|
|
2974
|
+
this.preservedStyles.set(editor, { font, color });
|
|
2975
|
+
}
|
|
2976
|
+
} catch (error) {
|
|
2977
|
+
console.debug("MarkPreserver.preserve error:", error);
|
|
2891
2978
|
}
|
|
2892
2979
|
}
|
|
2893
2980
|
/**
|
|
2894
|
-
* Restore
|
|
2895
|
-
* Call this after the editor action in onClick or in a setTimeout
|
|
2981
|
+
* Restore preserved styles to current node
|
|
2896
2982
|
*/
|
|
2897
2983
|
static restore(editor, delay = 0) {
|
|
2898
2984
|
if (!editor) return;
|
|
2899
|
-
const
|
|
2900
|
-
if (!
|
|
2985
|
+
const styles = this.preservedStyles.get(editor);
|
|
2986
|
+
if (!styles) return;
|
|
2901
2987
|
const restoreFn = () => {
|
|
2902
2988
|
if (editor.isDestroyed) {
|
|
2903
|
-
this.
|
|
2989
|
+
this.preservedStyles.delete(editor);
|
|
2904
2990
|
return;
|
|
2905
2991
|
}
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2992
|
+
try {
|
|
2993
|
+
const { state } = editor;
|
|
2994
|
+
const { $from } = state.selection;
|
|
2995
|
+
const depth = $from.depth;
|
|
2996
|
+
const pos = $from.before(depth);
|
|
2997
|
+
const node = $from.node(depth);
|
|
2998
|
+
const supportsAttributes = [
|
|
2999
|
+
"paragraph",
|
|
3000
|
+
"heading",
|
|
3001
|
+
"listItem",
|
|
3002
|
+
"taskItem",
|
|
3003
|
+
"blockquote"
|
|
3004
|
+
].includes(node.type.name);
|
|
3005
|
+
if (!supportsAttributes) {
|
|
3006
|
+
this.preservedStyles.delete(editor);
|
|
3007
|
+
editor.commands.focus();
|
|
3008
|
+
return;
|
|
3009
|
+
}
|
|
3010
|
+
const updates = {};
|
|
3011
|
+
if (styles.font && !node.attrs.fontFamily) {
|
|
3012
|
+
updates.fontFamily = styles.font;
|
|
3013
|
+
}
|
|
3014
|
+
if (styles.color && !node.attrs.color) {
|
|
3015
|
+
updates.color = styles.color;
|
|
3016
|
+
}
|
|
3017
|
+
if (Object.keys(updates).length > 0) {
|
|
3018
|
+
const newAttrs = { ...node.attrs, ...updates };
|
|
3019
|
+
editor.view.dispatch(
|
|
3020
|
+
state.tr.setNodeMarkup(pos, void 0, newAttrs)
|
|
3021
|
+
);
|
|
3022
|
+
}
|
|
3023
|
+
const marks = state.storedMarks || $from.marks();
|
|
3024
|
+
const filteredMarks = marks.filter((mark) => mark.type.name !== "textStyle");
|
|
3025
|
+
const textStyleAttrs = {};
|
|
3026
|
+
if (styles.font) textStyleAttrs.fontFamily = styles.font;
|
|
3027
|
+
if (styles.color) textStyleAttrs.color = styles.color;
|
|
3028
|
+
const newMarks = [
|
|
3029
|
+
...filteredMarks,
|
|
3030
|
+
state.schema.marks.textStyle.create(textStyleAttrs)
|
|
3031
|
+
];
|
|
3032
|
+
setTimeout(() => {
|
|
3033
|
+
if (!editor.isDestroyed) {
|
|
3034
|
+
editor.view.dispatch(
|
|
3035
|
+
editor.state.tr.setStoredMarks(newMarks)
|
|
3036
|
+
);
|
|
3037
|
+
editor.commands.focus();
|
|
3038
|
+
}
|
|
3039
|
+
}, 0);
|
|
3040
|
+
} catch (error) {
|
|
3041
|
+
console.debug("MarkPreserver.restore error:", error);
|
|
3042
|
+
} finally {
|
|
3043
|
+
this.preservedStyles.delete(editor);
|
|
3044
|
+
}
|
|
2910
3045
|
};
|
|
2911
3046
|
if (delay > 0) {
|
|
2912
3047
|
setTimeout(restoreFn, delay);
|
|
@@ -2915,10 +3050,10 @@ var MarkPreserver = class {
|
|
|
2915
3050
|
}
|
|
2916
3051
|
}
|
|
2917
3052
|
/**
|
|
2918
|
-
* Clear preserved
|
|
3053
|
+
* Clear preserved styles
|
|
2919
3054
|
*/
|
|
2920
3055
|
static clear(editor) {
|
|
2921
|
-
this.
|
|
3056
|
+
this.preservedStyles.delete(editor);
|
|
2922
3057
|
}
|
|
2923
3058
|
};
|
|
2924
3059
|
|
|
@@ -7633,8 +7768,9 @@ function useCursorVisibility({
|
|
|
7633
7768
|
}
|
|
7634
7769
|
|
|
7635
7770
|
// src/components/extensions/font-family-block.ts
|
|
7636
|
-
import { Extension as
|
|
7637
|
-
|
|
7771
|
+
import { Extension as Extension3 } from "@tiptap/core";
|
|
7772
|
+
import { Plugin, PluginKey } from "@tiptap/pm/state";
|
|
7773
|
+
var FontFamilyBlock = Extension3.create({
|
|
7638
7774
|
name: "fontFamilyBlock",
|
|
7639
7775
|
addGlobalAttributes() {
|
|
7640
7776
|
return [
|
|
@@ -7662,7 +7798,7 @@ var FontFamilyBlock = Extension2.create({
|
|
|
7662
7798
|
];
|
|
7663
7799
|
}
|
|
7664
7800
|
});
|
|
7665
|
-
var ColorBlock =
|
|
7801
|
+
var ColorBlock = Extension3.create({
|
|
7666
7802
|
name: "colorBlock",
|
|
7667
7803
|
addGlobalAttributes() {
|
|
7668
7804
|
return [
|
|
@@ -7690,150 +7826,217 @@ var ColorBlock = Extension2.create({
|
|
|
7690
7826
|
];
|
|
7691
7827
|
}
|
|
7692
7828
|
});
|
|
7693
|
-
var
|
|
7829
|
+
var ListMarkerColor2 = Extension3.create({
|
|
7830
|
+
name: "listMarkerColor",
|
|
7831
|
+
onCreate() {
|
|
7832
|
+
if (typeof document !== "undefined") {
|
|
7833
|
+
const styleId = "tiptap-list-marker-color";
|
|
7834
|
+
if (!document.getElementById(styleId)) {
|
|
7835
|
+
const style = document.createElement("style");
|
|
7836
|
+
style.id = styleId;
|
|
7837
|
+
style.textContent = `
|
|
7838
|
+
/* Bullet list markers inherit color */
|
|
7839
|
+
.ProseMirror ul > li[style*="color"]::marker {
|
|
7840
|
+
color: inherit !important;
|
|
7841
|
+
}
|
|
7842
|
+
|
|
7843
|
+
/* Ordered list numbers inherit color */
|
|
7844
|
+
.ProseMirror ol > li[style*="color"]::marker {
|
|
7845
|
+
color: inherit !important;
|
|
7846
|
+
}
|
|
7847
|
+
|
|
7848
|
+
/* Task list checkboxes inherit color */
|
|
7849
|
+
.ProseMirror ul[data-type="taskList"] > li[style*="color"] > label > input[type="checkbox"] {
|
|
7850
|
+
accent-color: currentColor;
|
|
7851
|
+
}
|
|
7852
|
+
|
|
7853
|
+
/* Ensure nested lists also inherit */
|
|
7854
|
+
.ProseMirror li[style*="color"] ul > li::marker,
|
|
7855
|
+
.ProseMirror li[style*="color"] ol > li::marker {
|
|
7856
|
+
color: inherit !important;
|
|
7857
|
+
}
|
|
7858
|
+
`;
|
|
7859
|
+
document.head.appendChild(style);
|
|
7860
|
+
}
|
|
7861
|
+
}
|
|
7862
|
+
},
|
|
7863
|
+
onDestroy() {
|
|
7864
|
+
if (typeof document !== "undefined") {
|
|
7865
|
+
const styleElement = document.getElementById("tiptap-list-marker-color");
|
|
7866
|
+
if (styleElement) {
|
|
7867
|
+
styleElement.remove();
|
|
7868
|
+
}
|
|
7869
|
+
}
|
|
7870
|
+
}
|
|
7871
|
+
});
|
|
7872
|
+
var stylePersistenceKey = new PluginKey("stylePersistence");
|
|
7873
|
+
var StylePersistence = Extension3.create({
|
|
7694
7874
|
name: "stylePersistence",
|
|
7695
7875
|
addOptions() {
|
|
7696
7876
|
return {
|
|
7697
|
-
// Marks that should NOT inherit font family or color
|
|
7698
7877
|
excludedMarks: ["code", "codeBlock"]
|
|
7699
7878
|
};
|
|
7700
7879
|
},
|
|
7701
|
-
|
|
7702
|
-
return {
|
|
7703
|
-
// Store marks temporarily when editor loses focus
|
|
7704
|
-
preservedMarks: null,
|
|
7705
|
-
// Store marks from the previous node (for Enter key handling)
|
|
7706
|
-
previousNodeMarks: null
|
|
7707
|
-
};
|
|
7708
|
-
},
|
|
7709
|
-
addKeyboardShortcuts() {
|
|
7710
|
-
return {
|
|
7711
|
-
// Handle Enter key to preserve marks when creating new paragraphs
|
|
7712
|
-
"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
|
-
// Handle Shift+Enter (soft break) - same logic
|
|
7724
|
-
"Shift-Enter": ({ editor }) => {
|
|
7725
|
-
const { state } = editor;
|
|
7726
|
-
const { $from } = state.selection;
|
|
7727
|
-
const currentNode = $from.parent;
|
|
7728
|
-
const blockFont = currentNode.attrs.fontFamily;
|
|
7729
|
-
const blockColor = currentNode.attrs.color;
|
|
7730
|
-
if (blockFont || blockColor) {
|
|
7731
|
-
this.storage.previousNodeMarks = { blockFont, blockColor };
|
|
7732
|
-
}
|
|
7733
|
-
return false;
|
|
7734
|
-
}
|
|
7735
|
-
};
|
|
7736
|
-
},
|
|
7737
|
-
onSelectionUpdate({ editor }) {
|
|
7738
|
-
const excludedMarks = this.options.excludedMarks;
|
|
7739
|
-
syncStoredMarks(editor, excludedMarks, this.storage);
|
|
7740
|
-
},
|
|
7741
|
-
onFocus({ editor }) {
|
|
7742
|
-
const excludedMarks = this.options.excludedMarks;
|
|
7743
|
-
if (this.storage.preservedMarks) {
|
|
7744
|
-
editor.view.dispatch(
|
|
7745
|
-
editor.state.tr.setStoredMarks(this.storage.preservedMarks)
|
|
7746
|
-
);
|
|
7747
|
-
this.storage.preservedMarks = null;
|
|
7748
|
-
}
|
|
7749
|
-
syncStoredMarks(editor, excludedMarks, this.storage);
|
|
7750
|
-
},
|
|
7751
|
-
onBlur({ editor }) {
|
|
7752
|
-
const { state } = editor;
|
|
7753
|
-
const { $from } = state.selection;
|
|
7754
|
-
const currentMarks = state.storedMarks || $from.marks();
|
|
7755
|
-
const hasTextStyle = currentMarks.some((mark) => mark.type.name === "textStyle");
|
|
7756
|
-
if (hasTextStyle) {
|
|
7757
|
-
this.storage.preservedMarks = currentMarks;
|
|
7758
|
-
}
|
|
7759
|
-
},
|
|
7760
|
-
onCreate({ editor }) {
|
|
7761
|
-
const excludedMarks = this.options.excludedMarks;
|
|
7762
|
-
syncStoredMarks(editor, excludedMarks, this.storage);
|
|
7763
|
-
},
|
|
7764
|
-
onTransaction({ editor, transaction }) {
|
|
7765
|
-
if (!transaction.selectionSet && !transaction.docChanged) return;
|
|
7880
|
+
addProseMirrorPlugins() {
|
|
7766
7881
|
const excludedMarks = this.options.excludedMarks;
|
|
7767
|
-
|
|
7768
|
-
|
|
7769
|
-
|
|
7770
|
-
|
|
7771
|
-
|
|
7882
|
+
return [
|
|
7883
|
+
new Plugin({
|
|
7884
|
+
key: stylePersistenceKey,
|
|
7885
|
+
state: {
|
|
7886
|
+
init() {
|
|
7887
|
+
return {
|
|
7888
|
+
lastFont: null,
|
|
7889
|
+
lastColor: null
|
|
7890
|
+
};
|
|
7891
|
+
},
|
|
7892
|
+
apply(tr, value, oldState, newState) {
|
|
7893
|
+
const { $from } = newState.selection;
|
|
7894
|
+
const marks = $from.marks();
|
|
7895
|
+
const hasExcludedMarks = marks.some(
|
|
7896
|
+
(mark) => excludedMarks.includes(mark.type.name)
|
|
7897
|
+
);
|
|
7898
|
+
let isInCodeBlock = false;
|
|
7899
|
+
for (let depth = $from.depth; depth > 0; depth--) {
|
|
7900
|
+
const node = $from.node(depth);
|
|
7901
|
+
if (node.type.name === "codeBlock") {
|
|
7902
|
+
isInCodeBlock = true;
|
|
7903
|
+
break;
|
|
7904
|
+
}
|
|
7905
|
+
}
|
|
7906
|
+
if (hasExcludedMarks || isInCodeBlock) {
|
|
7907
|
+
return value;
|
|
7908
|
+
}
|
|
7909
|
+
const parentNode = $from.parent;
|
|
7910
|
+
let font = parentNode.attrs.fontFamily;
|
|
7911
|
+
let color = parentNode.attrs.color;
|
|
7912
|
+
const textStyleMark = marks.find((m) => m.type.name === "textStyle");
|
|
7913
|
+
if (!font && textStyleMark?.attrs.fontFamily) {
|
|
7914
|
+
font = textStyleMark.attrs.fontFamily;
|
|
7915
|
+
}
|
|
7916
|
+
if (!color && textStyleMark?.attrs.color) {
|
|
7917
|
+
color = textStyleMark.attrs.color;
|
|
7918
|
+
}
|
|
7919
|
+
return {
|
|
7920
|
+
lastFont: font || value.lastFont,
|
|
7921
|
+
lastColor: color || value.lastColor
|
|
7922
|
+
};
|
|
7923
|
+
}
|
|
7924
|
+
},
|
|
7925
|
+
appendTransaction(transactions, oldState, newState) {
|
|
7926
|
+
if (!transactions.some((tr2) => tr2.docChanged)) {
|
|
7927
|
+
return null;
|
|
7928
|
+
}
|
|
7929
|
+
const pluginState = stylePersistenceKey.getState(newState);
|
|
7930
|
+
if (!pluginState.lastFont && !pluginState.lastColor) {
|
|
7931
|
+
return null;
|
|
7932
|
+
}
|
|
7933
|
+
const { $from } = newState.selection;
|
|
7934
|
+
const parentNode = $from.parent;
|
|
7935
|
+
const marks = $from.marks();
|
|
7936
|
+
const hasExcludedMarks = marks.some(
|
|
7937
|
+
(mark) => excludedMarks.includes(mark.type.name)
|
|
7938
|
+
);
|
|
7939
|
+
let isInCodeBlock = false;
|
|
7940
|
+
for (let depth = $from.depth; depth > 0; depth--) {
|
|
7941
|
+
const node = $from.node(depth);
|
|
7942
|
+
if (node.type.name === "codeBlock") {
|
|
7943
|
+
isInCodeBlock = true;
|
|
7944
|
+
break;
|
|
7945
|
+
}
|
|
7946
|
+
}
|
|
7947
|
+
if (hasExcludedMarks || isInCodeBlock) {
|
|
7948
|
+
return null;
|
|
7949
|
+
}
|
|
7950
|
+
const supportsAttributes = [
|
|
7951
|
+
"paragraph",
|
|
7952
|
+
"heading",
|
|
7953
|
+
"listItem",
|
|
7954
|
+
"taskItem",
|
|
7955
|
+
"blockquote"
|
|
7956
|
+
].includes(parentNode.type.name);
|
|
7957
|
+
if (!supportsAttributes) {
|
|
7958
|
+
return null;
|
|
7959
|
+
}
|
|
7960
|
+
const currentFont = parentNode.attrs.fontFamily;
|
|
7961
|
+
const currentColor = parentNode.attrs.color;
|
|
7962
|
+
const needsFont = !currentFont && pluginState.lastFont;
|
|
7963
|
+
const needsColor = !currentColor && pluginState.lastColor;
|
|
7964
|
+
if (!needsFont && !needsColor) {
|
|
7965
|
+
return null;
|
|
7966
|
+
}
|
|
7967
|
+
const tr = newState.tr;
|
|
7968
|
+
try {
|
|
7969
|
+
const depth = $from.depth;
|
|
7970
|
+
const pos = $from.before(depth);
|
|
7971
|
+
const node = $from.node(depth);
|
|
7972
|
+
const newAttrs = { ...node.attrs };
|
|
7973
|
+
if (needsFont) newAttrs.fontFamily = pluginState.lastFont;
|
|
7974
|
+
if (needsColor) newAttrs.color = pluginState.lastColor;
|
|
7975
|
+
tr.setNodeMarkup(pos, void 0, newAttrs);
|
|
7976
|
+
const storedMarks = newState.storedMarks || $from.marks();
|
|
7977
|
+
const filteredMarks = storedMarks.filter(
|
|
7978
|
+
(mark) => mark.type.name !== "textStyle" && !excludedMarks.includes(mark.type.name)
|
|
7979
|
+
);
|
|
7980
|
+
const textStyleAttrs = {};
|
|
7981
|
+
if (pluginState.lastFont) textStyleAttrs.fontFamily = pluginState.lastFont;
|
|
7982
|
+
if (pluginState.lastColor) textStyleAttrs.color = pluginState.lastColor;
|
|
7983
|
+
const newMarks = [
|
|
7984
|
+
...filteredMarks,
|
|
7985
|
+
newState.schema.marks.textStyle.create(textStyleAttrs)
|
|
7986
|
+
];
|
|
7987
|
+
tr.setStoredMarks(newMarks);
|
|
7988
|
+
return tr;
|
|
7989
|
+
} catch (error) {
|
|
7990
|
+
console.error("StylePersistence error:", error);
|
|
7991
|
+
return null;
|
|
7992
|
+
}
|
|
7993
|
+
},
|
|
7994
|
+
props: {
|
|
7995
|
+
handleKeyDown(view, event) {
|
|
7996
|
+
if (event.key === "Enter") {
|
|
7997
|
+
const { state } = view;
|
|
7998
|
+
const { $from } = state.selection;
|
|
7999
|
+
const marks = $from.marks();
|
|
8000
|
+
const hasExcludedMarks = marks.some(
|
|
8001
|
+
(mark) => excludedMarks.includes(mark.type.name)
|
|
8002
|
+
);
|
|
8003
|
+
if (hasExcludedMarks) {
|
|
8004
|
+
return false;
|
|
8005
|
+
}
|
|
8006
|
+
let isInCodeBlock = false;
|
|
8007
|
+
for (let depth = $from.depth; depth > 0; depth--) {
|
|
8008
|
+
const node = $from.node(depth);
|
|
8009
|
+
if (node.type.name === "codeBlock") {
|
|
8010
|
+
isInCodeBlock = true;
|
|
8011
|
+
break;
|
|
8012
|
+
}
|
|
8013
|
+
}
|
|
8014
|
+
if (isInCodeBlock) {
|
|
8015
|
+
return false;
|
|
8016
|
+
}
|
|
8017
|
+
const parentNode = $from.parent;
|
|
8018
|
+
let font = parentNode.attrs.fontFamily;
|
|
8019
|
+
let color = parentNode.attrs.color;
|
|
8020
|
+
const textStyleMark = marks.find((m) => m.type.name === "textStyle");
|
|
8021
|
+
if (!font && textStyleMark?.attrs.fontFamily) {
|
|
8022
|
+
font = textStyleMark.attrs.fontFamily;
|
|
8023
|
+
}
|
|
8024
|
+
if (!color && textStyleMark?.attrs.color) {
|
|
8025
|
+
color = textStyleMark.attrs.color;
|
|
8026
|
+
}
|
|
8027
|
+
if (font || color) {
|
|
8028
|
+
const pluginState = stylePersistenceKey.getState(state);
|
|
8029
|
+
pluginState.lastFont = font || pluginState.lastFont;
|
|
8030
|
+
pluginState.lastColor = color || pluginState.lastColor;
|
|
8031
|
+
}
|
|
8032
|
+
}
|
|
8033
|
+
return false;
|
|
8034
|
+
}
|
|
8035
|
+
}
|
|
8036
|
+
})
|
|
8037
|
+
];
|
|
7772
8038
|
}
|
|
7773
8039
|
});
|
|
7774
|
-
function syncStoredMarks(editor, excludedMarks, storage) {
|
|
7775
|
-
const { state } = editor;
|
|
7776
|
-
const { $from } = state.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;
|
|
7791
|
-
}
|
|
7792
|
-
const parentNode = $from.parent;
|
|
7793
|
-
let blockFont = parentNode.attrs.fontFamily;
|
|
7794
|
-
let blockColor = parentNode.attrs.color;
|
|
7795
|
-
if ((!blockFont || !blockColor) && storage?.previousNodeMarks) {
|
|
7796
|
-
if (!blockFont && storage.previousNodeMarks.blockFont) {
|
|
7797
|
-
blockFont = storage.previousNodeMarks.blockFont;
|
|
7798
|
-
}
|
|
7799
|
-
if (!blockColor && storage.previousNodeMarks.blockColor) {
|
|
7800
|
-
blockColor = storage.previousNodeMarks.blockColor;
|
|
7801
|
-
}
|
|
7802
|
-
if (blockFont || blockColor) {
|
|
7803
|
-
const depth = $from.depth;
|
|
7804
|
-
const nodePos = $from.before(depth);
|
|
7805
|
-
const node = $from.node(depth);
|
|
7806
|
-
const newAttrs = { ...node.attrs };
|
|
7807
|
-
if (blockFont) newAttrs.fontFamily = blockFont;
|
|
7808
|
-
if (blockColor) newAttrs.color = blockColor;
|
|
7809
|
-
const tr = state.tr.setNodeMarkup(nodePos, void 0, newAttrs);
|
|
7810
|
-
editor.view.dispatch(tr);
|
|
7811
|
-
}
|
|
7812
|
-
storage.previousNodeMarks = null;
|
|
7813
|
-
}
|
|
7814
|
-
if (!blockFont && !blockColor) {
|
|
7815
|
-
return;
|
|
7816
|
-
}
|
|
7817
|
-
const storedMarks = state.storedMarks || $from.marks();
|
|
7818
|
-
const existingTextStyle = storedMarks.find((mark) => mark.type.name === "textStyle");
|
|
7819
|
-
const needsUpdate = !existingTextStyle || blockFont && existingTextStyle.attrs.fontFamily !== blockFont || blockColor && existingTextStyle.attrs.color !== blockColor;
|
|
7820
|
-
if (!needsUpdate) {
|
|
7821
|
-
return;
|
|
7822
|
-
}
|
|
7823
|
-
const filteredMarks = storedMarks.filter(
|
|
7824
|
-
(mark) => mark.type.name !== "textStyle" && !excludedMarks.includes(mark.type.name)
|
|
7825
|
-
);
|
|
7826
|
-
const textStyleAttrs = {};
|
|
7827
|
-
if (blockFont) textStyleAttrs.fontFamily = blockFont;
|
|
7828
|
-
if (blockColor) textStyleAttrs.color = blockColor;
|
|
7829
|
-
const newMarks = [
|
|
7830
|
-
...filteredMarks,
|
|
7831
|
-
state.schema.marks.textStyle.create(textStyleAttrs)
|
|
7832
|
-
];
|
|
7833
|
-
editor.view.dispatch(
|
|
7834
|
-
state.tr.setStoredMarks(newMarks)
|
|
7835
|
-
);
|
|
7836
|
-
}
|
|
7837
8040
|
|
|
7838
8041
|
// src/components/tiptap-templates/simple/simple-editor.tsx
|
|
7839
8042
|
import { Fragment as Fragment12, jsx as jsx81, jsxs as jsxs48 } from "react/jsx-runtime";
|
|
@@ -7945,6 +8148,7 @@ function SimpleEditor() {
|
|
|
7945
8148
|
Superscript,
|
|
7946
8149
|
Subscript,
|
|
7947
8150
|
Selection2,
|
|
8151
|
+
ListMarkerColor,
|
|
7948
8152
|
FontFamilyBlock,
|
|
7949
8153
|
ColorBlock,
|
|
7950
8154
|
StylePersistence,
|