https://www.mediawiki.org/wiki/Special:Code/MediaWiki/113286
Revision: 113286
Author: tparscal
Date: 2012-03-07 20:21:32 +0000 (Wed, 07 Mar 2012)
Log Message:
-----------
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.
Added Paths:
-----------
trunk/extensions/VisualEditor/modules/ve/dm/ve.dm.DocumentSyncronizer.js
Added: trunk/extensions/VisualEditor/modules/ve/dm/ve.dm.DocumentSyncronizer.js
===================================================================
--- trunk/extensions/VisualEditor/modules/ve/dm/ve.dm.DocumentSyncronizer.js
(rev 0)
+++ trunk/extensions/VisualEditor/modules/ve/dm/ve.dm.DocumentSyncronizer.js
2012-03-07 20:21:32 UTC (rev 113286)
@@ -0,0 +1,99 @@
+/**
+ * Creates an ve.dm.DocumentSynchronizer object.
+ *
+ * This object is a one-time use utilitiy for collecting actions to be
performed on the model tree
+ * in multiple steps and then processing those actions in a single step.
+ *
+ * @class
+ * @constructor
+ */
+ve.dm.DocumentSynchronizer = function( model, transaction ) {
+ // Properties
+ this.model = model;
+ this.transaction = transaction;
+ this.actions = [];
+};
+
+/* Methods */
+
+/**
+ * Adds an action to the synchronizer.
+ *
+ * @method
+ * @param {ve.dm.Node} node Node this action is related to
+ * @param {Integer} offset Offset of node, improves performance if this has
already been calculated
+ * @param {String} type Type of action, can be: "insert", "delete", "rebuild",
"resize" or "update"
+ * @param {Integer} adjustment Node length adjustment, if any
+ */
+ve.dm.DocumentSynchronizer.prototype.pushAction = function( node, offset,
type, adjustment ) {
+ if ( offset === undefined ) {
+ offset = this.model.getOffsetFromNode( node );
+ }
+ this.actions.push( {
+ 'type': type,
+ 'node': node,
+ 'offset': offset,
+ 'adjustment': adjustment || 0
+ } );
+};
+
+/**
+ * Applies queued actions to the model tree.
+ *
+ * @method
+ */
+ve.dm.DocumentSynchronizer.prototype.synchronize = function() {
+ // TODO: Normalize the actions list to clean up nested actions
+ // Perform all actions
+ var adjustment = 0,
+ action,
+ offset,
+ parent;
+ for ( var i = 0, len = this.actions.length; i < len; i++ ) {
+ action = this.actions[i];
+ offset = action.offset + adjustment;
+ switch ( action.type ) {
+ case 'insert':
+ // Insert the new node at the given offset
+ var target = this.model.getNodeFromOffset(
offset );
+ if ( target === this.model ) {
+ // Insert at the beginning of the
document
+ target.splice( 0, 0, action.node );
+ } else {
+ // Insert before the element currently
at the offset
+ parent = target.getParent();
+ parent.splice( parent.indexOf( target
), 0, action.node );
+ }
+ // Adjust proceeding offsets positively by the
length of the node being inserted
+ adjustment += action.node.getElementLength();
+ break;
+ case 'delete':
+ // Replace original node with new node
+ parent = action.node.getParent();
+ parentNode.splice( parentNode.indexOf(
action.node ), 1 );
+ // Adjust proceeding offsets negatively by the
length of the node being deleted
+ adjustment -= action.node.getElementLength();
+ break;
+ case 'rebuild':
+ // Replace original node with new node
+ var newNode =
ve.dm.DocumentNode.createNodesFromData( this.model.getData(
+ new ve.Range( offset,
action.node.getElementLength() + action.adjustment )
+ ) );
+ parent = action.node.getParent();
+ parentNode.splice( parentNode.indexOf(
action.node ), 1, newNode );
+ // Adjust proceeding offsets by the difference
between the original and new nodes
+ adjustment += newNode.getElementLength() -
action.node.getElementLength();
+ break;
+ case 'resize':
+ // Adjust node length - causes update events to
be emitted
+ node.adjustContentLength( adjustment );
+ // Adjust proceeding offsets by the amount the
node is being lengthened or shortened
+ adjustment += action.adjustment;
+ break;
+ case 'update':
+ // Emit update events
+ node.emit( 'update' );
+ break;
+ }
+ }
+};
_______________________________________________
MediaWiki-CVS mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-cvs