r113851 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r113850‎ | r113851 | r113852 >
Date:21:02, 14 March 2012
Author:catrope
Status:deferred
Tags:
Comment:
Rewrite the rebuild action to take two ranges rather than a node and some data.
Modified paths:
  • /trunk/extensions/VisualEditor/modules/ve/dm/ve.dm.DocumentSynchronizer.js (modified) (history)
  • /trunk/extensions/VisualEditor/tests/ve/ve.dm.DocumentSynchronizer.test.js (modified) (history)

Diff [purge]

Index: trunk/extensions/VisualEditor/tests/ve/ve.dm.DocumentSynchronizer.test.js
@@ -119,7 +119,7 @@
120120 model.data[0].attributes = { 'level': 1 };
121121 model.data[4].type = '/heading';
122122 // Push rebuild action
123 - sync.pushRebuild( node, 0 );
 123+ sync.pushRebuild( new ve.Range( 0, 5 ), new ve.Range( 0, 5 ) );
124124 // Sync
125125 sync.synchronize();
126126 return model.getChildren()[0].getElementType();
@@ -135,7 +135,7 @@
136136 // Insert element after first paragraph
137137 ve.insertIntoArray( model.data, 5, data );
138138 // Push rebuild action with a length adustment of 3 to account for the new element
139 - sync.pushRebuild( node, 3 );
 139+ sync.pushRebuild( new ve.Range( 0, 5 ), new ve.Range( 0, 8 ) );
140140 // Sync
141141 sync.synchronize();
142142 return model.getChildren()[1].getContentData();
Index: trunk/extensions/VisualEditor/modules/ve/dm/ve.dm.DocumentSynchronizer.js
@@ -44,18 +44,20 @@
4545 };
4646
4747 /**
48 - * Add a rebuild action to the queue. This rebuilds a node from data
 48+ * Add a rebuild action to the queue. This rebuilds one or more nodes from data
4949 * found in the linear model.
50 - * @param {ve.dm.BranchNode} node Node to rebuild
51 - * @param {Integer} adjustment Length adjustment to apply to the node
52 - * @param {Integer} offset Offset of the node, if known
 50+ * @param {ve.Range} oldRange Range that the old nodes used to span. This is
 51+ * used to find the old nodes in the model tree.
 52+ * @param {ve.Range} newRange Range that contains the new nodes. This is used
 53+ * to get the new node data from the linear model.
5354 */
54 -ve.dm.DocumentSynchronizer.prototype.pushRebuild = function( node, adjustment, offset ) {
 55+ve.dm.DocumentSynchronizer.prototype.pushRebuild = function( oldRange, newRange ) {
 56+ oldRange.normalize();
 57+ newRange.normalize();
5558 this.actions.push( {
5659 'type': 'rebuild',
57 - 'node': node,
58 - 'adjustment': adjustment,
59 - 'offset': offset || null
 60+ 'oldRange': oldRange,
 61+ 'newRange': newRange
6062 } );
6163 };
6264
@@ -124,16 +126,44 @@
125127 parent.splice( parent.indexOf( action.node ), 1 );
126128 break;
127129 case 'rebuild':
128 - // Compute the offset if it wasn't provided
129 - if ( offset === null ) {
130 - offset = this.model.getOffsetFromNode( action.node );
 130+ // Generate the new nodes
 131+ var newNodes = ve.dm.DocumentNode.createNodesFromData(
 132+ this.model.getData( action.newRange )
 133+ );
 134+
 135+ // Find the node(s) contained by oldRange. This is done by repeatedly
 136+ // invoking selectNodes() in shallow mode until we find the right node(s).
 137+ // TODO this traversal could be made more efficient once we have an offset map
 138+ // TODO I need to add this recursive shallow stuff to selectNodes() as a 'siblings' mode
 139+ var selection, node = this.model, range = action.oldRange;
 140+ while ( true ) {
 141+ selection = node.selectNodes( range, true );
 142+ // We stop descending if:
 143+ // * we got more than one node, OR
 144+ // * we got a leaf node, OR
 145+ // * we got no range, which means the entire node is covered, OR
 146+ // * we got the same node back, which means we'd get in an infinite loop
 147+ if ( selection.length != 1 ||
 148+ !selection[0].node.hasChildren() ||
 149+ !selection[0].range ||
 150+ selection[0].node == node
 151+ ) {
 152+ break;
 153+ }
 154+ // Descend into this node
 155+ node = selection[0].node;
 156+ range = selection[0].range;
131157 }
132 - // Replace original node with new node
133 - var newNodes = ve.dm.DocumentNode.createNodesFromData( this.model.getData(
134 - new ve.Range( offset, action.node.getElementLength() + action.adjustment )
135 - ) );
136 - parent = action.node.getParent();
137 - ve.batchedSplice( parent, parent.indexOf( action.node ), 1, newNodes );
 158+ if ( selection[0].node == this.model ) {
 159+ // We got some sort of weird input, ignore it
 160+ break;
 161+ }
 162+
 163+ // The first node we're removing is selection[0].node , and we're removing
 164+ // selection.length adjacent nodes
 165+ parent = selection[0].node.getParent();
 166+ // TODO selectNodes() output knows the index of selection[0].node in its parent, should expose it
 167+ ve.batchedSplice( parent, parent.indexOf( selection[0].node ), selection.length, newNodes );
138168 break;
139169 case 'resize':
140170 // Adjust node length - causes update events to be emitted

Status & tagging log