jenkins-bot has submitted this change and it was merged.

Change subject: Handle deletion programmatically always
......................................................................


Handle deletion programmatically always

Change-Id: Ic68f80d92d32169ff60258b81a438e342b136128
---
M modules/ve/ce/ve.ce.Surface.js
M modules/ve/dm/ve.dm.Surface.js
2 files changed, 51 insertions(+), 135 deletions(-)

Approvals:
  Catrope: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/modules/ve/ce/ve.ce.Surface.js b/modules/ve/ce/ve.ce.Surface.js
index c45e8b7..4680273 100644
--- a/modules/ve/ce/ve.ce.Surface.js
+++ b/modules/ve/ce/ve.ce.Surface.js
@@ -449,9 +449,11 @@
                        this.handleEnter( e );
                        break;
                case ve.Keys.BACKSPACE:
+                       e.preventDefault();
                        this.handleDelete( e, true );
                        break;
                case ve.Keys.DELETE:
+                       e.preventDefault();
                        this.handleDelete( e, false );
                        break;
                default:
@@ -1195,147 +1197,56 @@
  * @param {boolean} backspace Key was a backspace
  */
 ve.ce.Surface.prototype.handleDelete = function ( e, backspace ) {
-       var sourceOffset, targetOffset, sourceSplitableNode, 
targetSplitableNode, tx, cursorAt,
-               sourceNode, targetNode, sourceData, nodeToDelete, adjacentData, 
adjacentText, adjacentChar,
-               adjacentTextAfterMatch, endOffset, i, containsComplexElements = 
false,
-               selection = this.model.getSelection();
+       var rangeToRemove = this.model.getSelection(),
+               tx, endNode, endNodeData, nodeToDelete;
 
-       if ( selection.isCollapsed() ) {
-               // Set source and target linmod offsets
-               if ( backspace ) {
-                       sourceOffset = selection.to;
-                       targetOffset = this.getNearestCorrectOffset( 
sourceOffset - 1, -1 );
-
-                       // At the beginning of the document - don't do anything 
and preventDefault
-                       if ( sourceOffset === targetOffset ) {
-                               e.preventDefault();
-                               return;
+       if ( rangeToRemove.isCollapsed() ) {
+               // In case when the range is collapsed use the same logic that 
is used for cursor left and
+               // right movement in order to figure out range to remove.
+               rangeToRemove = this.getDocument().getRelativeRange(
+                       rangeToRemove,
+                       backspace ? -1 : 1,
+                       ( e.altKey === true || e.ctrlKey === true ) ? 'word' : 
'character',
+                       true
+               );
+               if ( rangeToRemove.isCollapsed() ) {
+                       // For instance beginning or end of the document.
+                       return;
+               }
+       }
+       tx = ve.dm.Transaction.newFromRemoval( this.documentView.model, 
rangeToRemove );
+       this.model.change( tx );
+       rangeToRemove = tx.translateRange( rangeToRemove );
+       if ( !rangeToRemove.isCollapsed() ) {
+               // If after processing removal transaction range is not 
collapsed it means that not
+               // everything got merged nicely (at this moment transaction 
processor is capable of merging
+               // nodes of the same type and at the same depth level only), so 
we process with another 
+               // merging that takes remaing data from "endNode" and inserts 
it at the end of "startNode",
+               // "endNode" or recrusivly its parent (if have only one child) 
gets removed.
+               endNode = this.documentView.getNodeFromOffset( 
rangeToRemove.end, false );
+               endNodeData = this.documentView.model.getData( 
endNode.model.getRange() );
+               nodeToDelete = endNode;
+               nodeToDelete.traverseUpstream( function ( node ) {
+                       if ( node.getParent().children.length === 1 ) {
+                               nodeToDelete = node.getParent();
+                               return true;
+                       } else {
+                               return false;
                        }
-
-               } else {
-                       sourceOffset = 
this.model.getDocument().data.getRelativeContentOffset( selection.to, 1 );
-                       targetOffset = selection.to;
-
-                       // At the end of the document - don't do anything and 
preventDefault
-                       if ( sourceOffset <= targetOffset ) {
-                               e.preventDefault();
-                               return;
-                       }
-               }
-
-               // Set source and target nodes
-               sourceNode = this.documentView.getNodeFromOffset( sourceOffset, 
false ),
-               targetNode = this.documentView.getNodeFromOffset( targetOffset, 
false );
-
-               if ( sourceNode.type === targetNode.type ) {
-                       sourceSplitableNode = ve.ce.Node.getSplitableNode( 
sourceNode );
-                       targetSplitableNode = ve.ce.Node.getSplitableNode( 
targetNode );
-               }
-               //ve.log(sourceSplitableNode, targetSplitableNode);
-
-               // Save target location of cursor
-               cursorAt = targetOffset;
-
-               // Get text from cursor location to end of node in the proper 
direction
-               adjacentData = null;
-               adjacentText = '';
-
-               if ( backspace ) {
-                       adjacentData = sourceNode.model.doc.data.slice(
-                               sourceNode.model.getOffset() + ( 
sourceNode.model.isWrapped() ? 1 : 0 ) ,
-                               sourceOffset
-                       );
-               } else {
-                       endOffset = targetNode.model.getOffset() +
-                               targetNode.model.getLength() +
-                               ( targetNode.model.isWrapped() ? 1 : 0 );
-                       adjacentData = targetNode.model.doc.data.slice( 
targetOffset, endOffset );
-               }
-
-               for ( i = 0; i < adjacentData.length; i++ ) {
-                       if ( adjacentData[i].type !== undefined ) {
-                               containsComplexElements = true;
-                               break;
-                       }
-                       adjacentChar = ve.isArray( adjacentData[i] ) ? 
adjacentData[i][0] : adjacentData[i];
-                       if ( adjacentChar.length > 1 ) {
-                               containsComplexElements = true;
-                               break;
-                       }
-                       adjacentText += adjacentChar;
-               }
-
-               if ( !containsComplexElements ) {
-                       adjacentTextAfterMatch = adjacentText.match( 
this.constructor.static.textPattern );
-                       // If there are "normal" characters in the adjacent 
text let the browser handle natively
-                       if ( adjacentTextAfterMatch !== null && 
adjacentTextAfterMatch.length ) {
-                               return;
-                       }
-               }
-
-               ve.log('handleDelete programatically');
-               e.preventDefault();
-               this.surfaceObserver.stop();
-
-               if (
-                       // Source and target are the same node
-                       sourceNode === targetNode ||
-                       (
-                               // Source and target have the same parent (list 
items)
-                               sourceSplitableNode !== undefined &&
-                               sourceSplitableNode.getParent() === 
targetSplitableNode.getParent()
-                       )
-               ) {
-                       // Simple removal
-                       tx = ve.dm.Transaction.newFromRemoval(
-                               this.documentView.model, new ve.Range( 
targetOffset, sourceOffset )
-                       );
-                       this.model.change( tx, new ve.Range( cursorAt ) );
-               } else if ( sourceNode.getType() === 'document' ) {
-                       // Source is a slug - move the cursor somewhere useful
-                       this.model.change( null, new ve.Range( cursorAt ) );
-               } else {
-                       // Source and target are different nodes or do not 
share a parent, perform tricky merge
-                       // Get the data for the source node
-                       sourceData = this.documentView.model.getData( 
sourceNode.model.getRange() );
-
-                       // Find the node that should be completely removed
-                       nodeToDelete = sourceNode;
-                       nodeToDelete.traverseUpstream( function ( node ) {
-                               if ( node.getParent().children.length === 1 ) {
-                                       nodeToDelete = node.getParent();
-                                       return true;
-                               } else {
-                                       return false;
-                               }
-                       } );
-
-                       this.model.change(
-                               [
-                                       // Remove source node or source node 
ancestor
-                                       ve.dm.Transaction.newFromRemoval(
-                                               this.documentView.model, 
nodeToDelete.getModel().getOuterRange()
-                                       ),
-                                       // Append source data to target
-                                       ve.dm.Transaction.newFromInsertion(
-                                               this.documentView.model, 
targetOffset, sourceData
-                                       )
-                               ],
-                               new ve.Range( cursorAt )
-                       );
-               }
-       } else {
-               // Selection removal
-               ve.log('selection removal - handle programatically');
-               e.preventDefault();
+               } );
                this.model.change(
-                       ve.dm.Transaction.newFromRemoval( 
this.documentView.model, selection ),
-                       new ve.Range( selection.start )
+                       [
+                               ve.dm.Transaction.newFromRemoval(
+                                       this.documentView.model, 
nodeToDelete.getModel().getOuterRange()
+                               ),
+                               ve.dm.Transaction.newFromInsertion(
+                                       this.documentView.model, 
rangeToRemove.start, endNodeData
+                               )
+                       ]
                );
        }
-
+       this.model.change( null, new ve.Range( rangeToRemove.start ) );
        this.surfaceObserver.clear();
-       this.surfaceObserver.start();
 };
 
 /**
diff --git a/modules/ve/dm/ve.dm.Surface.js b/modules/ve/dm/ve.dm.Surface.js
index 9b3f779..bb71756 100644
--- a/modules/ve/dm/ve.dm.Surface.js
+++ b/modules/ve/dm/ve.dm.Surface.js
@@ -315,6 +315,11 @@
                                this.truncateUndoStack();
                                this.smallStack.push( transactions[i] );
                                this.documentModel.commit( transactions[i] );
+                               if ( !selection ) {
+                                       // translateRange only if selection is 
not provided because otherwise we are
+                                       // going to overwrite it
+                                       this.selection = 
transactions[i].translateRange( this.selection );
+                               }
                        }
                }
        }

-- 
To view, visit https://gerrit.wikimedia.org/r/68332
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: merged
Gerrit-Change-Id: Ic68f80d92d32169ff60258b81a438e342b136128
Gerrit-PatchSet: 6
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Inez <[email protected]>
Gerrit-Reviewer: Catrope <[email protected]>
Gerrit-Reviewer: Trevor Parscal <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to