@@ -3,6 +3,28 @@ import { crel } from "./utils.js"
3
3
4
4
const cssClass = ( c ) => ( typeof c === "string" ? { className : c , title : c } : c )
5
5
6
+ const getApplicableNodes = ( state , cssClasses ) => {
7
+ const { selection } = state
8
+ const { $from } = selection
9
+ const applicableNodes = [ ]
10
+
11
+ let depth = $from . depth
12
+ while ( depth > 0 ) {
13
+ const node = $from . node ( depth )
14
+ if ( cssClasses [ node . type . name ] ) {
15
+ applicableNodes . push ( {
16
+ nodeType : node . type . name ,
17
+ node : node ,
18
+ depth : depth ,
19
+ pos : $from . before ( depth ) ,
20
+ } )
21
+ }
22
+ depth --
23
+ }
24
+
25
+ return applicableNodes
26
+ }
27
+
6
28
export const NodeClass = Extension . create ( {
7
29
name : "nodeClass" ,
8
30
@@ -43,32 +65,11 @@ export const NodeClass = Extension.create({
43
65
} ,
44
66
45
67
addMenuItems ( { buttons, menu } ) {
46
- // Helper function to get all applicable node types in the current selection
47
- const getApplicableNodeTypes = ( editor ) => {
48
- const { selection } = editor . state
49
- const { $from } = selection
50
- const applicableNodes = [ ]
51
-
52
- let depth = $from . depth
53
- while ( depth > 0 ) {
54
- const node = $from . node ( depth )
55
- if ( this . options . cssClasses [ node . type . name ] ) {
56
- applicableNodes . push ( {
57
- nodeType : node . type . name ,
58
- node : node ,
59
- depth : depth ,
60
- pos : $from . before ( depth ) ,
61
- } )
62
- }
63
- depth --
64
- }
65
-
66
- return applicableNodes
67
- }
68
+ const cssClasses = this . options . cssClasses
68
69
69
70
// Helper function to get the display title for a node type
70
71
const getNodeTypeTitle = ( nodeType ) => {
71
- const nodeConfig = this . options . cssClasses [ nodeType ]
72
+ const nodeConfig = cssClasses [ nodeType ]
72
73
if (
73
74
typeof nodeConfig === "object" &&
74
75
nodeConfig . title &&
@@ -81,7 +82,7 @@ export const NodeClass = Extension.create({
81
82
82
83
// Helper function to get the classes for a node type
83
84
const getNodeTypeClasses = ( nodeType ) => {
84
- const nodeConfig = this . options . cssClasses [ nodeType ]
85
+ const nodeConfig = cssClasses [ nodeType ]
85
86
if (
86
87
typeof nodeConfig === "object" &&
87
88
nodeConfig . cssClasses &&
@@ -110,7 +111,7 @@ export const NodeClass = Extension.create({
110
111
} ,
111
112
command ( editor ) {
112
113
// Remove classes from all applicable ancestor nodes
113
- const applicableNodes = getApplicableNodeTypes ( editor )
114
+ const applicableNodes = getApplicableNodes ( editor . state , cssClasses )
114
115
editor
115
116
. chain ( )
116
117
. focus ( )
@@ -125,7 +126,7 @@ export const NodeClass = Extension.create({
125
126
} )
126
127
127
128
// Create separate menu items for each node type and its classes
128
- for ( const nodeType of Object . keys ( this . options . cssClasses ) ) {
129
+ for ( const nodeType of Object . keys ( cssClasses ) ) {
129
130
const classes = getNodeTypeClasses ( nodeType )
130
131
if ( ! classes || classes . length === 0 ) continue
131
132
@@ -144,25 +145,20 @@ export const NodeClass = Extension.create({
144
145
} ) ,
145
146
active ( editor ) {
146
147
// Active when this specific node type has this class
147
- const applicableNodes = getApplicableNodeTypes ( editor )
148
+ const applicableNodes = getApplicableNodes ( editor . state , cssClasses )
148
149
const targetNode = applicableNodes . find (
149
150
( n ) => n . nodeType === nodeType ,
150
151
)
151
152
return targetNode && targetNode . node . attrs . class === className
152
153
} ,
153
154
hidden ( editor ) {
154
- const applicableNodes = getApplicableNodeTypes ( editor )
155
+ const applicableNodes = getApplicableNodes ( editor . state , cssClasses )
155
156
return ! applicableNodes . some ( ( n ) => n . nodeType === nodeType )
156
157
} ,
157
158
command ( editor ) {
158
- const { selection } = editor . state
159
- const { $from } = selection
160
-
161
- let depth = $from . depth
162
- while ( depth > 0 ) {
163
- const node = $from . node ( depth )
159
+ const applicableNodes = getApplicableNodes ( editor . state , cssClasses )
160
+ for ( const { node, pos } of applicableNodes ) {
164
161
if ( node . type . name === nodeType ) {
165
- const pos = $from . before ( depth )
166
162
editor
167
163
. chain ( )
168
164
. focus ( )
@@ -173,7 +169,6 @@ export const NodeClass = Extension.create({
173
169
. run ( )
174
170
return
175
171
}
176
- depth --
177
172
}
178
173
} ,
179
174
} )
0 commit comments