Catrope has uploaded a new change for review.

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


Change subject: Merging and remapping
......................................................................

Merging and remapping

Add merge() methods to IndexValueStore and InternalList, which merge
another store/list in to the current one and return a mapping
translating old indexes to new ones.

Also add functions that, given such a mapping, traverse a linear
model data array and remap store/list indexes using simple logic for
annotations and node type-specific functions for node attributes.

Change-Id: I1e90755ced1a87c190947c037cf151c4d17cf8b7
---
M modules/ve/dm/lineardata/ve.dm.ElementLinearData.js
M modules/ve/dm/nodes/ve.dm.MWReferenceNode.js
M modules/ve/dm/ve.dm.IndexValueStore.js
M modules/ve/dm/ve.dm.InternalList.js
M modules/ve/dm/ve.dm.Node.js
5 files changed, 119 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/VisualEditor 
refs/changes/59/64959/1

diff --git a/modules/ve/dm/lineardata/ve.dm.ElementLinearData.js 
b/modules/ve/dm/lineardata/ve.dm.ElementLinearData.js
index c6c83de..6fc8631 100644
--- a/modules/ve/dm/lineardata/ve.dm.ElementLinearData.js
+++ b/modules/ve/dm/lineardata/ve.dm.ElementLinearData.js
@@ -741,4 +741,44 @@
                valueStore[i] = this.getStore().value( i );
        }
        return valueStore;
+};
+
+/**
+ * Remap the store indexes used in this linear data.
+ *
+ * Remaps annotations and calls remapStoreIndexes() on each node.
+ *
+ * @method
+ * @param {Object} mapping Mapping from store indexes to store indexes
+ */
+ve.dm.ElementLinearData.prototype.remapStoreIndexes = function ( mapping ) {
+       var i, ilen, j, jlen, indexes, nodeClass;
+       for ( i = 0, ilen = this.data.length; i < ilen; i++ ) {
+               indexes = this.getAnnotationIndexesFromOffset( i ); // returns 
by reference
+               for ( j = 0, jlen = indexes.length; j < jlen; j++ ) {
+                       indexes[j] = mapping[indexes[j]];
+               }
+               if ( this.isOpenElementData( i ) ) {
+                       nodeClass = ve.dm.nodeFactory.lookup( this.getType( i ) 
);
+                       nodeClass.static.remapStoreIndexes( this.data[i], 
mapping );
+               }
+       }
+};
+
+/**
+ * Remap the internal list indexes used in this linear data.
+ *
+ * Calls remapInternalListIndexes() for each node.
+ *
+ * @method
+ * @param {Object} mapping Mapping from internal list indexes to internal list 
indexes
+ */
+ve.dm.ElementLinearData.prototype.remapInteralListIndexes = function ( mapping 
) {
+       var i, ilen, nodeClass;
+       for ( i = 0, ilen = this.data.length; i < ilen; i++ ) {
+               if ( this.isOpenElementData( i ) ) {
+                       nodeClass = ve.dm.nodeFactory.lookup( this.getType( i ) 
);
+                       nodeClass.static.remapInternalListIndexes( 
this.data[i], mapping );
+               }
+       }
 };
\ No newline at end of file
diff --git a/modules/ve/dm/nodes/ve.dm.MWReferenceNode.js 
b/modules/ve/dm/nodes/ve.dm.MWReferenceNode.js
index eebdc72..9855603 100644
--- a/modules/ve/dm/nodes/ve.dm.MWReferenceNode.js
+++ b/modules/ve/dm/nodes/ve.dm.MWReferenceNode.js
@@ -80,6 +80,10 @@
        return [ span ];
 };
 
+ve.dm.MWReferenceNode.static.remapInternalListIndexes = function ( 
dataElement, mapping ) {
+       dataElement.attributes.listIndex = 
mapping[dataElement.attributes.listIndex];
+};
+
 /* Methods */
 
 /**
diff --git a/modules/ve/dm/ve.dm.IndexValueStore.js 
b/modules/ve/dm/ve.dm.IndexValueStore.js
index 513766c..da940ce 100644
--- a/modules/ve/dm/ve.dm.IndexValueStore.js
+++ b/modules/ve/dm/ve.dm.IndexValueStore.js
@@ -123,4 +123,28 @@
                clone.hashStore[key] = this.hashStore[key];
        }
        return clone;
+};
+
+/**
+ * Merge another store into this store.
+ *
+ * Objects that are in other but not in this are added to this, possibly with 
a different index.
+ * Objects present in both stores may have different indexes in each store. An 
object is returned
+ * mapping each index in other to the corresponding index in this.
+ *
+ * Objects added to the store are added by reference, not cloned like in 
.index()
+ *
+ * @param {ve.dm.IndexValueStore} other Store to merge into this one
+ * @returns {Object} Object mapping store indexes in other to store indexes in 
this store
+ */
+ve.dm.IndexValueStore.prototype.merge = function ( other ) {
+       var key, index, mapping = {};
+       for ( key in other.hashStore ) {
+               if ( !( key in this.hashStore ) ) {
+                       index = this.valueStore.push( 
other.valueStore[other.hashStore[key]] ) - 1;
+                       this.hashStore[key] = index;
+               }
+               mapping[other.hashStore[key]] = this.hashStore[key];
+       }
+       return mapping;
 };
\ No newline at end of file
diff --git a/modules/ve/dm/ve.dm.InternalList.js 
b/modules/ve/dm/ve.dm.InternalList.js
index 7e80005..fdd772c 100644
--- a/modules/ve/dm/ve.dm.InternalList.js
+++ b/modules/ve/dm/ve.dm.InternalList.js
@@ -142,3 +142,24 @@
        clone.itemsHtml = this.itemsHtml.slice();
        return clone;
 };
+
+/**
+ * Merge another document's internal list into this one.
+ *
+ * Objects that are in other but not in this are added to this, possibly with 
a different index.
+ *
+ * @param {ve.dm.InternalList} other List to merge into this one
+ * @returns {Object} Object mapping indexes in other to indexes in this
+ */
+ve.dm.InternalList.prototype.merge = function ( other ) {
+       var i, len, index, storeMapping = this.store.merge( other.store ), 
mapping = {};
+       for ( i = 0, len = other.itemsHtml.length; i < len; i++ ) {
+               other.itemsHtml[i] = storeMapping[other.itemsHtml[i]];
+               index = ve.indexOf( other.itemsHtml[i], this.itemsHtml );
+               if ( index === -1 ) {
+                       index = this.itemsHtml.push( other.itemsHtml[i] ) - 1;
+               }
+               mapping[i] = index;
+       }
+       return mapping;
+};
diff --git a/modules/ve/dm/ve.dm.Node.js b/modules/ve/dm/ve.dm.Node.js
index ca2b2ac..637802b 100644
--- a/modules/ve/dm/ve.dm.Node.js
+++ b/modules/ve/dm/ve.dm.Node.js
@@ -173,6 +173,36 @@
 ve.dm.Node.static.defaultAttributes = {};
 
 /**
+ * Remap the store indexes stored in a linear model data element.
+ *
+ * The default implementation is empty. Nodes should override this if they 
store store indexes in
+.* attributes. To remap, do something like
+ * dataElement.attributes.foo = mapping[dataElement.attributes.foo];
+ *
+ * @static
+ * @inheritable
+ * @param {Object} dataElement Data element (opening) to remap. Will be 
modified.
+ * @param {Object} mapping Object mapping old store indexes to new store 
indexes
+ */
+ve.dm.Node.static.remapStoreIndexes = function ( /*dataElement, mapping*/ ) {
+};
+
+/**
+ * Remap the internal list indexes stored in a linear model data element.
+ *
+ * The default implementation is empty. Nodes should override this if they 
store internal list
+ * indexes in attributes. To remap, do something like
+ * dataElement.attributes.foo = mapping[dataElement.attributes.foo];
+ *
+ * @static
+ * @inheritable
+ * @param {Object} dataElement Data element (opening) to remap. Will be 
modified.
+ * @param {Object} mapping Object mapping old internal list indexes to new 
internal list indexes
+ */
+ve.dm.Node.static.remapInternalListIndexes = function ( /*dataElement, 
mapping*/ ) {
+};
+
+/**
  * Get hash object of a linear model data element
  *
  * @static

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: I1e90755ced1a87c190947c037cf151c4d17cf8b7
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Catrope <roan.katt...@gmail.com>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to