@@ -13,6 +13,8 @@ import { insertSelectPointInteraction } from '@qti-editor/interaction-select-poi
1313import { insertInlineChoiceInteraction } from '@qti-editor/interaction-inline-choice' ;
1414import { insertAssociateInteraction } from '@qti-editor/interaction-associate' ;
1515import { insertHottextInteraction } from '@qti-editor/interaction-hottext' ;
16+ import { insertGap , insertGapMatchInteraction } from '../../../vendor/interaction-gap-match/dist/index.js' ;
17+ import { insertItemDivider } from '../../../vendor/qti-item-divider/dist/index.js' ;
1618
1719import type { EditorView } from 'prosekit/pm/view' ;
1820
@@ -43,6 +45,20 @@ function canInsert(view: EditorView, nodeType: any): boolean {
4345 return false ;
4446}
4547
48+ function canInsertInline ( view : EditorView , nodeType : any ) : boolean {
49+ const { $from } = view . state . selection ;
50+ for ( let depth = $from . depth ; depth >= 0 ; depth -= 1 ) {
51+ const node = $from . node ( depth ) ;
52+ if ( ! node . type . inlineContent ) continue ;
53+
54+ const index = $from . index ( depth ) ;
55+ if ( node . canReplaceWith ( index , index , nodeType ) ) {
56+ return true ;
57+ }
58+ }
59+ return false ;
60+ }
61+
4662function isSelectionInsideNodeType ( view : EditorView , nodeType : any ) : boolean {
4763 const { $from } = view . state . selection ;
4864 for ( let depth = $from . depth ; depth >= 0 ; depth -= 1 ) {
@@ -57,6 +73,18 @@ function getInteractionInsertItems(view: EditorView): InteractionInsertItem[] {
5773 const schema : any = view . state . schema ;
5874 const items : InteractionInsertItem [ ] = [ ] ;
5975
76+ if ( schema . nodes . qtiAssociateInteraction && schema . nodes . qtiSimpleAssociableChoice ) {
77+ const nodeType = schema . nodes . qtiAssociateInteraction ;
78+ items . push ( {
79+ label : translateQti ( 'interactionInsert.associate' , { target : view . dom } ) ,
80+ canInsert : canInsert ( view , nodeType ) ,
81+ command : ( ) => {
82+ insertAssociateInteraction ( view . state , view . dispatch , view ) ;
83+ view . focus ( ) ;
84+ } ,
85+ } ) ;
86+ }
87+
6088 if (
6189 schema . nodes . qtiChoiceInteraction &&
6290 schema . nodes . qtiPrompt &&
@@ -75,27 +103,45 @@ function getInteractionInsertItems(view: EditorView): InteractionInsertItem[] {
75103 } ) ;
76104 }
77105
78- if ( schema . nodes . qtiTextEntryInteraction ) {
79- const nodeType = schema . nodes . qtiTextEntryInteraction ;
106+ if ( schema . nodes . qtiExtendedTextInteraction ) {
107+ const nodeType = schema . nodes . qtiExtendedTextInteraction ;
80108 items . push ( {
81- label : translateQti ( 'interactionInsert.textEntry ' , { target : view . dom } ) ,
109+ label : translateQti ( 'interactionInsert.extendedText ' , { target : view . dom } ) ,
82110 canInsert : canInsert ( view , nodeType ) ,
83111 command : ( ) => {
84- const node = nodeType . createAndFill ( { responseIdentifier : `RESPONSE_${ crypto . randomUUID ( ) } ` } ) ;
85- if ( ! node ) return ;
86- view . dispatch ( view . state . tr . replaceSelectionWith ( node ) ) ;
112+ insertExtendedTextInteraction ( view . state , view . dispatch , view ) ;
87113 view . focus ( ) ;
88114 } ,
89115 } ) ;
90116 }
91117
92- if ( schema . nodes . qtiSelectPointInteraction ) {
93- const nodeType = schema . nodes . qtiSelectPointInteraction ;
118+ if ( schema . nodes . qtiGapMatchInteraction && schema . nodes . qtiGapText && schema . nodes . qtiGap ) {
119+ const nodeType = schema . nodes . qtiGapMatchInteraction ;
94120 items . push ( {
95- label : translateQti ( 'interactionInsert.selectPoint ' , { target : view . dom } ) ,
121+ label : translateQti ( 'interactionInsert.gapMatch ' , { target : view . dom } ) ,
96122 canInsert : canInsert ( view , nodeType ) ,
97123 command : ( ) => {
98- insertSelectPointInteraction ( view . state , view . dispatch , view ) ;
124+ insertGapMatchInteraction ( view . state , view . dispatch , view ) ;
125+ view . focus ( ) ;
126+ } ,
127+ } ) ;
128+ items . push ( {
129+ label : translateQti ( 'interactionInsert.gap' , { target : view . dom } ) ,
130+ canInsert : insertGap ( view . state ) ,
131+ command : ( ) => {
132+ insertGap ( view . state , view . dispatch ) ;
133+ view . focus ( ) ;
134+ } ,
135+ } ) ;
136+ }
137+
138+ if ( schema . nodes . qtiHottextInteraction && schema . nodes . qtiHottext ) {
139+ const nodeType = schema . nodes . qtiHottextInteraction ;
140+ items . push ( {
141+ label : translateQti ( 'interactionInsert.hottext' , { target : view . dom } ) ,
142+ canInsert : canInsert ( view , nodeType ) ,
143+ command : ( ) => {
144+ insertHottextInteraction ( view . state , view . dispatch , view ) ;
99145 view . focus ( ) ;
100146 } ,
101147 } ) ;
@@ -105,7 +151,7 @@ function getInteractionInsertItems(view: EditorView): InteractionInsertItem[] {
105151 const nodeType = schema . nodes . qtiInlineChoiceInteraction ;
106152 items . push ( {
107153 label : translateQti ( 'interactionInsert.inlineChoice' , { target : view . dom } ) ,
108- canInsert : ! isSelectionInsideNodeType ( view , nodeType ) && canInsert ( view , nodeType ) ,
154+ canInsert : ! isSelectionInsideNodeType ( view , nodeType ) && canInsertInline ( view , nodeType ) ,
109155 command : ( ) => {
110156 insertInlineChoiceInteraction ( view . state , view . dispatch , view ) ;
111157 view . focus ( ) ;
@@ -125,52 +171,51 @@ function getInteractionInsertItems(view: EditorView): InteractionInsertItem[] {
125171 } ) ;
126172 }
127173
128- if (
129- schema . nodes . qtiAssociateInteraction &&
130- schema . nodes . qtiSimpleAssociableChoice
131- ) {
132- const nodeType = schema . nodes . qtiAssociateInteraction ;
174+ if ( schema . nodes . qtiOrderInteraction && schema . nodes . qtiSimpleChoice ) {
175+ const nodeType = schema . nodes . qtiOrderInteraction ;
133176 items . push ( {
134- label : translateQti ( 'interactionInsert.associate ' , { target : view . dom } ) ,
177+ label : translateQti ( 'interactionInsert.order ' , { target : view . dom } ) ,
135178 canInsert : canInsert ( view , nodeType ) ,
136179 command : ( ) => {
137- insertAssociateInteraction ( view . state , view . dispatch , view ) ;
180+ insertOrderInteraction ( view . state , view . dispatch , view ) ;
138181 view . focus ( ) ;
139182 } ,
140183 } ) ;
141184 }
142185
143- if ( schema . nodes . qtiOrderInteraction && schema . nodes . qtiSimpleChoice ) {
144- const nodeType = schema . nodes . qtiOrderInteraction ;
186+ if ( schema . nodes . qtiSelectPointInteraction ) {
187+ const nodeType = schema . nodes . qtiSelectPointInteraction ;
145188 items . push ( {
146- label : translateQti ( 'interactionInsert.order ' , { target : view . dom } ) ,
189+ label : translateQti ( 'interactionInsert.selectPoint ' , { target : view . dom } ) ,
147190 canInsert : canInsert ( view , nodeType ) ,
148191 command : ( ) => {
149- insertOrderInteraction ( view . state , view . dispatch , view ) ;
192+ insertSelectPointInteraction ( view . state , view . dispatch , view ) ;
150193 view . focus ( ) ;
151194 } ,
152195 } ) ;
153196 }
154197
155- if ( schema . nodes . qtiHottextInteraction && schema . nodes . qtiHottext ) {
156- const nodeType = schema . nodes . qtiHottextInteraction ;
198+ if ( schema . nodes . qtiTextEntryInteraction ) {
199+ const nodeType = schema . nodes . qtiTextEntryInteraction ;
157200 items . push ( {
158- label : translateQti ( 'interactionInsert.hottext ' , { target : view . dom } ) ,
159- canInsert : canInsert ( view , nodeType ) ,
201+ label : translateQti ( 'interactionInsert.textEntry ' , { target : view . dom } ) ,
202+ canInsert : canInsertInline ( view , nodeType ) ,
160203 command : ( ) => {
161- insertHottextInteraction ( view . state , view . dispatch , view ) ;
204+ const node = nodeType . createAndFill ( { responseIdentifier : `RESPONSE_${ crypto . randomUUID ( ) } ` } ) ;
205+ if ( ! node ) return ;
206+ view . dispatch ( view . state . tr . replaceSelectionWith ( node ) ) ;
162207 view . focus ( ) ;
163208 } ,
164209 } ) ;
165210 }
166211
167- if ( schema . nodes . qtiExtendedTextInteraction ) {
168- const nodeType = schema . nodes . qtiExtendedTextInteraction ;
212+ if ( schema . nodes . qtiItemDivider ) {
213+ const nodeType = schema . nodes . qtiItemDivider ;
169214 items . push ( {
170- label : translateQti ( 'interactionInsert.extendedText ' , { target : view . dom } ) ,
215+ label : translateQti ( 'interactionInsert.itemDivider ' , { target : view . dom } ) ,
171216 canInsert : canInsert ( view , nodeType ) ,
172217 command : ( ) => {
173- insertExtendedTextInteraction ( view . state , view . dispatch , view ) ;
218+ insertItemDivider ( view . state , view . dispatch ) ;
174219 view . focus ( ) ;
175220 } ,
176221 } ) ;
0 commit comments