Esanders has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/170014

Change subject: Refactor and fix table cell editing code
......................................................................

Refactor and fix table cell editing code

Instead of storing a fragment in the surface and a selection
in the table node, just store a fragment in the table node and
a pointer to the active table node in the surface.

Change-Id: Ie2f4aea0ca166c9e35d6a56930054c8d8155d257
---
M src/ce/nodes/ve.ce.TableNode.js
M src/ce/ve.ce.Surface.js
2 files changed, 49 insertions(+), 38 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/VisualEditor/VisualEditor 
refs/changes/14/170014/1

diff --git a/src/ce/nodes/ve.ce.TableNode.js b/src/ce/nodes/ve.ce.TableNode.js
index 297c916..a1c62e3 100644
--- a/src/ce/nodes/ve.ce.TableNode.js
+++ b/src/ce/nodes/ve.ce.TableNode.js
@@ -20,7 +20,7 @@
        this.surface = null;
        this.active = false;
        this.startCell = null;
-       this.editingSelection = null;
+       this.editingFragment = null;
 };
 
 /* Inheritance */
@@ -156,12 +156,12 @@
                endCell.row,
                true
        );
-       if ( this.editingSelection ) {
-               if ( newSelection.equals( this.editingSelection ) ) {
+       if ( this.editingFragment ) {
+               if ( newSelection.equals( this.editingFragment ) ) {
                        // Clicking on the editing cell, don't prevent default
                        return;
                } else {
-                       this.setEditing( false );
+                       this.setEditing( false, true );
                }
        }
        this.surface.getModel().setSelection( newSelection );
@@ -229,26 +229,40 @@
  * Set the editing state of the table
  *
  * @param {boolean} isEditing The table is being edited
+ * @param {boolean} noSelect Don't change the selection
  */
-ve.ce.TableNode.prototype.setEditing = function ( isEditing ) {
+ve.ce.TableNode.prototype.setEditing = function ( isEditing, noSelect ) {
        if ( isEditing ) {
                var cell, selection = this.surface.getModel().getSelection();
                if ( !selection.isSingleCell() ) {
                        selection = selection.collapseToFrom();
                        this.surface.getModel().setSelection( selection );
                }
-               this.editingSelection = selection;
+               this.editingFragment = this.surface.getModel().getFragment( 
selection );
                cell = this.getCellNodesFromSelection( selection )[0];
                cell.setEditing( true );
+               if ( !noSelect ) {
                // TODO: Find content offset/slug offset within cell
-               this.surface.getModel().setLinearSelection( new ve.Range( 
cell.getModel().getRange().end - 1 ) );
-       } else if ( this.editingSelection ) {
-               this.getCellNodesFromSelection( this.editingSelection 
)[0].setEditing( false );
-               this.editingSelection = null;
+                       this.surface.getModel().setLinearSelection( new 
ve.Range( cell.getModel().getRange().end - 1 ) );
+               }
+       } else if ( this.editingFragment ) {
+               this.getCellNodesFromSelection( 
this.editingFragment.getSelection() )[0].setEditing( false );
+               if ( !noSelect ) {
+                       this.surface.getModel().setSelection( 
this.editingFragment.getSelection() );
+               }
+               this.editingFragment = null;
        }
        this.$element.toggleClass( 've-ce-tableNode-editing', isEditing );
        this.$overlay.toggleClass( 've-ce-tableNodeOverlay-editing', isEditing 
);
-       this.surface.setTableEditing( this.editingSelection );
+};
+
+ve.ce.TableNode.prototype.getEditingFragment = function () {
+       return this.editingFragment;
+};
+
+ve.ce.TableNode.prototype.getEditingRange = function () {
+       var fragment = this.getEditingFragment();
+       return fragment ? fragment.getSelection().getRanges()[0] : null;
 };
 
 /**
@@ -260,7 +274,7 @@
        // The table is active if it is a linear selection inside a cell being 
edited
        // or a table selection matching this table.
        var active = (
-                       this.editingSelection !== null &&
+                       this.editingFragment !== null &&
                        selection instanceof ve.dm.LinearSelection &&
                        this.getModel().getOuterRange().containsRange( 
selection.getRange() )
                ) ||
@@ -271,17 +285,20 @@
 
        if ( active ) {
                if ( !this.active ) {
-                       this.active = true;
                        this.$overlay.show();
                        // Only register touchstart event after table has 
become active to prevent
                        // accidental focusing of the table while scrolling
                        this.$element.on( 'touchstart.ve-ce-tableNode', 
this.onTableMouseDown.bind( this ) );
                }
+               this.surface.setActiveTableNode( this );
                this.updateOverlayDebounced();
        } else if ( !active && this.active ) {
                this.$overlay.hide();
-               if ( this.editingSelection ) {
-                       this.setEditing( false );
+               if ( this.editingFragment ) {
+                       this.setEditing( false, true );
+               }
+               if ( this.surface.getActiveTableNode() === this ) {
+                       this.surface.setActiveTableNode( null );
                }
                this.$element.off( 'touchstart.ve-ce-tableNode' );
        }
@@ -299,7 +316,9 @@
 
        var i, l, nodes, cellOffset, anchorNode, anchorOffset, selectionOffset,
                top, left, bottom, right,
-               selection = this.editingSelection || 
this.surface.getModel().getSelection(),
+               selection = this.editingFragment ?
+                       this.editingFragment.getSelection() :
+                       this.surface.getModel().getSelection(),
                // getBoundingClientRect is more accurate but must be used 
consistently
                // due to the iOS7 bug where it is relative to the document.
                tableOffset = this.$element[0].getBoundingClientRect(),
diff --git a/src/ce/ve.ce.Surface.js b/src/ce/ve.ce.Surface.js
index a27d83c..50c81d0 100644
--- a/src/ce/ve.ce.Surface.js
+++ b/src/ce/ve.ce.Surface.js
@@ -50,7 +50,7 @@
        this.selecting = false;
        this.resizing = false;
        this.focused = false;
-       this.tableEditingFragment = null;
+       this.activeTableNode = null;
        this.contentBranchNodeChanged = false;
        this.$highlightsFocused = this.$( '<div>' );
        this.$highlightsBlurred = this.$( '<div>' );
@@ -1037,7 +1037,7 @@
                        }
                        break;
                case OO.ui.Keys.ESCAPE:
-                       if ( this.tableEditingFragment ) {
+                       if ( this.getActiveTableNode() ) {
                                this.handleTableEditingEscape( e );
                        }
                        break;
@@ -2262,24 +2262,21 @@
 };
 
 /**
- * Set the table editing surface fragment from a linear selection covering the 
cell currently being edited
+ * Set the active table node
  *
- * @param {ve.dm.LinearSelection} tableEditingSelection Selection covering a 
table cell
+ * @param {ve.ce.TableNode|null} tableNode Table node
  */
-ve.ce.Surface.prototype.setTableEditing = function ( tableEditingSelection ) {
-       this.tableEditingFragment = tableEditingSelection ? 
this.getModel().getFragment( tableEditingSelection ) : null;
+ve.ce.Surface.prototype.setActiveTableNode = function ( tableNode ) {
+       this.activeTableNode = tableNode;
 };
 
 /**
- * Get the range of the table cell currently being edited, or null if none
+ * Get the active table node
  *
- * @return {ve.Range|null} Range of table cell being edited
+ * @return {ve.ce.TableNode|null} Table node
  */
-ve.ce.Surface.prototype.getTableEditingRange = function () {
-       if ( !this.tableEditingFragment ) {
-               return null;
-       }
-       return this.tableEditingFragment.getSelection().getRanges()[0];
+ve.ce.Surface.prototype.getActiveTableNode = function () {
+       return this.activeTableNode;
 };
 
 /*! Utilities */
@@ -2356,7 +2353,7 @@
                direction,
                ( e.altKey === true || e.ctrlKey === true ) ? 'word' : 
'character',
                e.shiftKey,
-               this.getTableEditingRange()
+               this.getActiveTableNode() ? 
this.getActiveTableNode().getEditingRange() : null
        );
        this.model.setLinearSelection( range );
        // TODO: onDocumentKeyDown does this anyway
@@ -2372,7 +2369,7 @@
 ve.ce.Surface.prototype.handleLinearUpOrDownArrowKey = function ( e ) {
        var nativeRange, slug, $cursorHolder, endNode, endOffset,
                range = this.model.getSelection().getRange(),
-               tableEditingRange = this.getTableEditingRange(),
+               tableEditingRange = this.getActiveTableNode() ? 
this.getActiveTableNode().getEditingRange() : null,
                direction = e.keyCode === OO.ui.Keys.DOWN ? 1 : -1,
                surface = this;
 
@@ -2816,7 +2813,7 @@
                // 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 = documentModel.getRelativeRange( rangeToRemove, 
direction, unit, true );
-               tableEditingRange = this.getTableEditingRange();
+               tableEditingRange = this.getActiveTableNode() ? 
this.getActiveTableNode().getEditingRange() : null;
                if ( tableEditingRange && !tableEditingRange.containsRange( 
rangeToRemove ) ) {
                        return;
                }
@@ -2880,13 +2877,8 @@
  * @param {jQuery.Event} e Delete key down event
  */
 ve.ce.Surface.prototype.handleTableEditingEscape = function ( e ) {
-       var selection = this.tableEditingFragment.getSelection(),
-               tableNode = this.documentView.getBranchNodeFromOffset( 
selection.tableRange.start + 1 );
-
        e.preventDefault();
-
-       tableNode.setEditing( false );
-       this.getModel().setSelection( selection );
+       this.getActiveTableNode().setEditing( false );
 };
 
 /**

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ie2f4aea0ca166c9e35d6a56930054c8d8155d257
Gerrit-PatchSet: 1
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Esanders <[email protected]>

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

Reply via email to