@@ -197,14 +197,10 @@ export class TreeHistoryImpl extends TreeHistory {
197197 }
198198
199199 public deleteFrom ( id : number ) : void {
200- // Cannot delete if keeping path
201- if ( this . keepPath ) {
202- return ;
203- }
204-
205200 const node = this . undoableNodes [ id ] ;
206201
207- if ( node === undefined ) {
202+ // Cannot delete if keeping path
203+ if ( this . keepPath || node === undefined ) {
208204 return ;
209205 }
210206
@@ -246,6 +242,26 @@ export class TreeHistoryImpl extends TreeHistory {
246242 return getModifiableCmdAttributes ( node . undoable ) ;
247243 }
248244
245+ public deleteNode ( id : number ) : void {
246+ const node = this . undoableNodes [ id ] ;
247+ const parent = node ?. parent ;
248+
249+ // Cannot delete if keeping path.
250+ // If the node to delete has no child, just a simple removal.
251+ if ( this . keepPath || parent === undefined || node === undefined || node . children . length === 0 ) {
252+ return ;
253+ }
254+
255+ const currentId = this . currentNode . id ;
256+ this . goTo ( parent . id ) ;
257+ // Cloning the child trees of the node to remove.
258+ // The goal is to create new branches at the parent level without the node to remove.
259+ const clonedTree = this . cloneSubtree ( node ) ;
260+ this . addClonedSubtree ( clonedTree ) ;
261+ // Going back to the original position
262+ this . goTo ( currentId ) ;
263+ }
264+
249265 public applyModifiedAttributesOn ( id : number , data : object ) : void {
250266 // not `at(i)` since at considers -1 as last one
251267 const node = this . undoableNodes [ id ] ;
@@ -279,19 +295,28 @@ export class TreeHistoryImpl extends TreeHistory {
279295 }
280296 }
281297
282- private proceedModifiedNode ( currentNode : UndoableTreeNode ) : void {
298+ /**
299+ * Takes a modified command and re-processes it within the history
300+ * @param node - The modified command to re-executed
301+ */
302+ private proceedModifiedNode ( node : UndoableTreeNode ) : void {
283303 // Executing the cloned undoable object
284- currentNode . undoable . redo ( ) ;
304+ node . undoable . redo ( ) ;
285305 // Must refresh the visual snapshot cache
286- if ( currentNode . undoable instanceof UndoableCommand ) {
287- currentNode . undoable . refreshCache ( ) ;
306+ if ( node . undoable instanceof UndoableCommand ) {
307+ node . undoable . refreshCache ( ) ;
288308 }
289309 // Adding the novel commands to the history
290- this . add ( currentNode . undoable ) ;
310+ this . add ( node . undoable ) ;
291311 }
292312
293- private addClonedSubtree ( currentNode : UndoableTreeNode ) : void {
294- for ( const child of currentNode . children ) {
313+ /**
314+ * Adds the given node and its child trees in the history.
315+ * Re-execute the added nodes.
316+ * @param node - The node to add (and its children)
317+ */
318+ private addClonedSubtree ( node : UndoableTreeNode ) : void {
319+ for ( const child of node . children ) {
295320 this . proceedModifiedNode ( child ) ;
296321 this . undo ( ) ;
297322 this . addClonedSubtree ( child ) ;
0 commit comments