Divec has uploaded a new change for review. (
https://gerrit.wikimedia.org/r/344812 )
Change subject: Serialize/deserialize for Transaction and IndexValueStore
......................................................................
Serialize/deserialize for Transaction and IndexValueStore
Change-Id: I565c9a4e3de5af2cb46501ab84e08a71b0636929
---
M src/dm/ve.dm.Change.js
M src/dm/ve.dm.IndexValueStore.js
M src/dm/ve.dm.Transaction.js
3 files changed, 103 insertions(+), 55 deletions(-)
git pull ssh://gerrit.wikimedia.org:29418/VisualEditor/VisualEditor
refs/changes/12/344812/1
diff --git a/src/dm/ve.dm.Change.js b/src/dm/ve.dm.Change.js
index 48aff04..3eb521c 100644
--- a/src/dm/ve.dm.Change.js
+++ b/src/dm/ve.dm.Change.js
@@ -86,19 +86,18 @@
ve.dm.Change.static = {};
/**
- * Deserialize a JSON-serialized change
+ * Deserialize a change from a JSONable object
*
* Store values can be deserialized, or kept verbatim; the latter is an
optimization if the
* Change object will be rebased and reserialized without ever being applied
to a document.
*
- * @param {Object} data JSON-serialized change
+ * @param {Object} data Change serialized as a JSONable object
* @param {ve.dm.Document} [doc] Document, used for creating proper selections
if deserializing in the client
* @param {boolean} [preserveStoreValues] Keep store values verbatim instead
of deserializing
- * @return {ve.dm.Change} Deserialized Change object
+ * @return {ve.dm.Change} Deserialized change
*/
ve.dm.Change.static.deserialize = function ( data, doc, preserveStoreValues ) {
- var author,
- staticChange = this,
+ var author, deserializeStore,
selections = {};
for ( author in data.selections ) {
@@ -107,27 +106,16 @@
data.selections[ author ]
);
}
+ deserializeStore = ve.dm.IndexValueStore.static.deserialize.bind(
+ null,
+ preserveStoreValues ? function noop( x ) {
+ return x;
+ } : this.deserializeValue
+ );
return new ve.dm.Change(
data.start,
- data.transactions.map( function ( tx ) {
- var newTx = new ve.dm.Transaction( tx.operations );
- newTx.author = tx.author;
- return newTx;
- } ),
- data.stores.map( function ( serializedStore ) {
- var hash, value,
- store = new ve.dm.IndexValueStore();
- store.hashes = serializedStore.hashes;
- store.hashStore = {};
- for ( hash in serializedStore.hashStore ) {
- value = serializedStore.hashStore[ hash ];
- if ( !preserveStoreValues ) {
- value = staticChange.deserializeValue(
value );
- }
- store.hashStore[ hash ] = value;
- }
- return store;
- } ),
+ data.transactions.map( ve.dm.Transaction.static.deserialize ),
+ data.stores.map( deserializeStore ),
selections
);
};
@@ -733,39 +721,27 @@
* already, i.e. the Change object was created by #deserialize without
deserializing store values).
*
* @param {boolean} [preserveStoreValues] If true, keep store values verbatim
instead of serializing
- * @return {ve.dm.Change} Deserialized Change object
+ * @return {ve.dm.Change} Deserialized change
*/
ve.dm.Change.prototype.serialize = function ( preserveStoreValues ) {
- var author,
- selections = {},
- change = this;
+ var author, serializeStoreValues, serializeStore,
+ selections = {};
for ( author in this.selections ) {
selections[ author ] = this.selections[ author ].toJSON();
}
+ serializeStoreValues = preserveStoreValues ? function noop( x ) {
+ return x;
+ } : this.constructor.static.serializeValue;
+ serializeStore = function ( store ) {
+ return store.serialize( serializeStoreValues );
+ };
return {
start: this.start,
- transactions: this.transactions.map( function ( transaction ) {
- return {
- operations: transaction.operations,
- author: transaction.author
- };
+ transactions: this.transactions.map( function ( tx ) {
+ return tx.serialize();
} ),
- stores: this.stores.map( function ( store ) {
- var hash, value,
- serialized = {};
- for ( hash in store.hashStore ) {
- value = store.hashStore[ hash ];
- if ( !preserveStoreValues ) {
- value =
change.constructor.static.serializeValue( value );
- }
- serialized[ hash ] = value;
- }
- return {
- hashes: store.hashes.slice(),
- hashStore: serialized
- };
- } ),
+ stores: this.stores.map( serializeStore ),
selections: selections
};
};
diff --git a/src/dm/ve.dm.IndexValueStore.js b/src/dm/ve.dm.IndexValueStore.js
index cd1168f..08bf153 100644
--- a/src/dm/ve.dm.IndexValueStore.js
+++ b/src/dm/ve.dm.IndexValueStore.js
@@ -35,9 +35,53 @@
}
};
+/* Inheritance */
+
+OO.initClass( ve.dm.IndexValueStore );
+
+/* Static Methods */
+
+/**
+ * Deserialize a store from a JSONable object
+ *
+ * @param {Function} deserializeValue Deserializer for arbitrary store values
+ * @param {Object} data Store serialized as a JSONable object
+ * @return {ve.dm.IndexValueStore} Deserialized store
+ */
+ve.dm.IndexValueStore.static.deserialize = function ( deserializeValue, data )
{
+ var hash,
+ store = new ve.dm.IndexValueStore();
+
+ store.hashes = data.hashes.slice();
+ store.hashStore = {};
+ for ( hash in data.hashStore ) {
+ store.hashStore[ hash ] = deserializeValue( data.hashStore[
hash ] );
+ }
+ return store;
+};
+
/* Methods */
/**
+ * Serialize the store into a JSONable object
+ *
+ * @param {Function} serializeValue Serializer for arbitrary store values
+ * @return {Object} Serialized store
+ */
+ve.dm.IndexValueStore.prototype.serialize = function ( serializeValue ) {
+ var hash,
+ serialized = {};
+
+ for ( hash in this.hashStore ) {
+ serialized[ hash ] = serializeValue( this.hashStore[ hash ] );
+ }
+ return {
+ hashes: this.hashes.slice(),
+ hashStore: serialized
+ };
+};
+
+/**
* Get the number of values in the store
*
* @return {number} Number of values in the store
diff --git a/src/dm/ve.dm.Transaction.js b/src/dm/ve.dm.Transaction.js
index e638581..604db67 100644
--- a/src/dm/ve.dm.Transaction.js
+++ b/src/dm/ve.dm.Transaction.js
@@ -21,11 +21,12 @@
* @class
* @constructor
* @param {Object[]} [operations] Operations preserving tree validity as a
whole; default []
+ * @param {Number|null} [author] Positive integer author ID; default null
*/
-ve.dm.Transaction = function VeDmTransaction( operations ) {
+ve.dm.Transaction = function VeDmTransaction( operations, author ) {
this.operations = operations || [];
this.applied = false;
- this.author = null;
+ this.author = author || null;
};
/* Inheritance */
@@ -65,7 +66,34 @@
// ve.dm.Transaction.newFrom* methods are added by ve.dm.TransactionBuilder
for legacy support.
+/**
+ * Deserialize a transaction from a JSONable object
+ *
+ * @param {Object} data Transaction serialized as a JSONable object
+ * @return {ve.dm.Transaction} Deserialized transaction
+ */
+ve.dm.Transaction.static.deserialize = function ( data ) {
+ return new ve.dm.Transaction(
+ // For this plain, serializable array, stringify+parse profiles
faster than ve.copy
+ JSON.parse( JSON.stringify( data.operations ) ),
+ data.author
+ );
+};
+
/* Methods */
+
+/**
+ * Serialize the transaction into a JSONable object
+ *
+ * Values are not necessarily deep copied
+ * @return {Object} Serialized transaction
+ */
+ve.dm.Transaction.prototype.serialize = function () {
+ return {
+ operations: this.operations,
+ author: this.author
+ };
+};
/**
* Push a retain operation
@@ -156,11 +184,11 @@
* @return {ve.dm.Transaction} Clone of this transaction
*/
ve.dm.Transaction.prototype.clone = function () {
- var tx = new this.constructor();
- // For this plain, serializable array, stringify+parse profiles faster
than ve.copy
- tx.operations = JSON.parse( JSON.stringify( this.operations ) );
- tx.author = this.author;
- return tx;
+ return new this.constructor(
+ // For this plain, serializable array, stringify+parse profiles
faster than ve.copy
+ JSON.parse( JSON.stringify( this.operations ) ),
+ this.author
+ );
};
/**
--
To view, visit https://gerrit.wikimedia.org/r/344812
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I565c9a4e3de5af2cb46501ab84e08a71b0636929
Gerrit-PatchSet: 1
Gerrit-Project: VisualEditor/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Divec <[email protected]>
_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits