r113286 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r113285‎ | r113286 | r113287 >
Date:20:21, 7 March 2012
Author:tparscal
Status:deferred
Tags:
Comment:
Added sketch for ve.dm.DocumentSynchronizer which is a utility object for queueing up actions to be performed on the model tree such as deletion, insertion, rebuilding, resizing and updating of node. Using this approach, we can collect actions across multiple steps, and then normalize them to avoid duplicate work and mutate the model tree in a single step.
Modified paths:
  • /trunk/extensions/VisualEditor/modules/ve/dm/ve.dm.DocumentSyncronizer.js (added) (history)

Diff [purge]

Index: trunk/extensions/VisualEditor/modules/ve/dm/ve.dm.DocumentSyncronizer.js
@@ -0,0 +1,99 @@
 2+/**
 3+ * Creates an ve.dm.DocumentSynchronizer object.
 4+ *
 5+ * This object is a one-time use utilitiy for collecting actions to be performed on the model tree
 6+ * in multiple steps and then processing those actions in a single step.
 7+ *
 8+ * @class
 9+ * @constructor
 10+ */
 11+ve.dm.DocumentSynchronizer = function( model, transaction ) {
 12+ // Properties
 13+ this.model = model;
 14+ this.transaction = transaction;
 15+ this.actions = [];
 16+};
 17+
 18+/* Methods */
 19+
 20+/**
 21+ * Adds an action to the synchronizer.
 22+ *
 23+ * @method
 24+ * @param {ve.dm.Node} node Node this action is related to
 25+ * @param {Integer} offset Offset of node, improves performance if this has already been calculated
 26+ * @param {String} type Type of action, can be: "insert", "delete", "rebuild", "resize" or "update"
 27+ * @param {Integer} adjustment Node length adjustment, if any
 28+ */
 29+ve.dm.DocumentSynchronizer.prototype.pushAction = function( node, offset, type, adjustment ) {
 30+ if ( offset === undefined ) {
 31+ offset = this.model.getOffsetFromNode( node );
 32+ }
 33+ this.actions.push( {
 34+ 'type': type,
 35+ 'node': node,
 36+ 'offset': offset,
 37+ 'adjustment': adjustment || 0
 38+ } );
 39+};
 40+
 41+/**
 42+ * Applies queued actions to the model tree.
 43+ *
 44+ * @method
 45+ */
 46+ve.dm.DocumentSynchronizer.prototype.synchronize = function() {
 47+ // TODO: Normalize the actions list to clean up nested actions
 48+ // Perform all actions
 49+ var adjustment = 0,
 50+ action,
 51+ offset,
 52+ parent;
 53+ for ( var i = 0, len = this.actions.length; i < len; i++ ) {
 54+ action = this.actions[i];
 55+ offset = action.offset + adjustment;
 56+ switch ( action.type ) {
 57+ case 'insert':
 58+ // Insert the new node at the given offset
 59+ var target = this.model.getNodeFromOffset( offset );
 60+ if ( target === this.model ) {
 61+ // Insert at the beginning of the document
 62+ target.splice( 0, 0, action.node );
 63+ } else {
 64+ // Insert before the element currently at the offset
 65+ parent = target.getParent();
 66+ parent.splice( parent.indexOf( target ), 0, action.node );
 67+ }
 68+ // Adjust proceeding offsets positively by the length of the node being inserted
 69+ adjustment += action.node.getElementLength();
 70+ break;
 71+ case 'delete':
 72+ // Replace original node with new node
 73+ parent = action.node.getParent();
 74+ parentNode.splice( parentNode.indexOf( action.node ), 1 );
 75+ // Adjust proceeding offsets negatively by the length of the node being deleted
 76+ adjustment -= action.node.getElementLength();
 77+ break;
 78+ case 'rebuild':
 79+ // Replace original node with new node
 80+ var newNode = ve.dm.DocumentNode.createNodesFromData( this.model.getData(
 81+ new ve.Range( offset, action.node.getElementLength() + action.adjustment )
 82+ ) );
 83+ parent = action.node.getParent();
 84+ parentNode.splice( parentNode.indexOf( action.node ), 1, newNode );
 85+ // Adjust proceeding offsets by the difference between the original and new nodes
 86+ adjustment += newNode.getElementLength() - action.node.getElementLength();
 87+ break;
 88+ case 'resize':
 89+ // Adjust node length - causes update events to be emitted
 90+ node.adjustContentLength( adjustment );
 91+ // Adjust proceeding offsets by the amount the node is being lengthened or shortened
 92+ adjustment += action.adjustment;
 93+ break;
 94+ case 'update':
 95+ // Emit update events
 96+ node.emit( 'update' );
 97+ break;
 98+ }
 99+ }
 100+};

Status & tagging log