Trevor Parscal has uploaded a new change for review.

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


Change subject: Preserve unused parsoid template properties
......................................................................

Preserve unused parsoid template properties

Problem:

Parsoid has a property called "i" which we don't use, but they need for round 
tripping purposes. Since we were generating a structure from parsoid data and 
then generating data from the structure without preserving properties we didn't 
use, it was getting lost.

Solution:

Abstract creating a template from data vs. creating it from name. Make only 
templates have an origin argument in their constructors, so and set it within a 
set of static constructors that create a template for either data or a template 
name. Store the original data in the former case, and use it as a base when 
serializing.

Changes:

ve.ui.MWTranslcusionDialog.js
* Remove no-longer-needed mw global declaration
* Move most of the addTemplate function to a static constructor in the template 
model class

ve.dm.MWTransclusionPartModel.js,
ve.dm.MWTransclusionContentModel.js,
ve.dm.MWTemplatePlaceholder
* Remove unused origin argument/property/getter
* Add serialize method (if needed)

ve.dm.MWTranclusionModel.js
* Move template/parameter generation from data into static constructor of 
template model
* Move serialization to part classes

ve.dm.MWTemplateModel.js
* Add mw global declaration
* Stop passing origin to parent constructor, store it locally instead
* Add original data property/setter for preserving unused properties when round 
tripping
* Add static constructors for generating a template from data or by name
* Add serialize method

Change-Id: Ide596a0ca0ae8f93ffce6e79b7234a1db7e0586c
---
M modules/ve-mw/dm/models/ve.dm.MWTemplateModel.js
M modules/ve-mw/dm/models/ve.dm.MWTemplatePlaceholderModel.js
M modules/ve-mw/dm/models/ve.dm.MWTransclusionContentModel.js
M modules/ve-mw/dm/models/ve.dm.MWTransclusionModel.js
M modules/ve-mw/dm/models/ve.dm.MWTransclusionPartModel.js
M modules/ve-mw/ui/dialogs/ve.ui.MWTransclusionDialog.js
6 files changed, 125 insertions(+), 55 deletions(-)


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

diff --git a/modules/ve-mw/dm/models/ve.dm.MWTemplateModel.js 
b/modules/ve-mw/dm/models/ve.dm.MWTemplateModel.js
index a0b013a..de44b16 100644
--- a/modules/ve-mw/dm/models/ve.dm.MWTemplateModel.js
+++ b/modules/ve-mw/dm/models/ve.dm.MWTemplateModel.js
@@ -5,6 +5,8 @@
  * @license The MIT License (MIT); see LICENSE.txt
  */
 
+/*global mw*/
+
 /**
  * MediaWiki template model.
  *
@@ -20,14 +22,16 @@
  */
 ve.dm.MWTemplateModel = function VeDmMWTemplateModel( transclusion, target, 
origin ) {
        // Parent constructor
-       ve.dm.MWTransclusionPartModel.call( this, transclusion, origin );
+       ve.dm.MWTransclusionPartModel.call( this, transclusion );
 
        // Properties
        this.target = target;
+       this.origin = origin;
        this.title = ( target.href && target.href.replace( /^(\.\.?\/)*/, '' ) 
) || null;
        this.sequence = null;
        this.params = {};
        this.spec = new ve.dm.MWTemplateSpecModel( this );
+       this.originalData = null;
 };
 
 /* Inheritance */
@@ -46,6 +50,53 @@
  * @param {ve.dm.MWTemplateParameterModel} param Removed param
  */
 
+/* Static Methods */
+
+/**
+ * Create from data.
+ *
+ * Data is in the format provided by Parsoid.
+ *
+ * @param {ve.dm.MWTransclusionModel} transclusion Transclusion template is in
+ * @param {Object} data Template data
+ * @returns {ve.dm.MWTemplateModel} New template model
+ */
+ve.dm.MWTemplateModel.newFromData = function ( transclusion, data ) {
+       var key,
+               template = new ve.dm.MWTemplateModel( transclusion, 
data.target, 'data' );
+
+       for ( key in data.params ) {
+               template.addParameter(
+                       new ve.dm.MWTemplateParameterModel( template, key, 
data.params[key].wt, 'data' )
+               );
+       }
+
+       template.setOriginalData( data );
+
+       return template;
+};
+
+/**
+ * Create from name.
+ *
+ * Name is equivilent to what would be entered between double brackets, 
defaulting to the Template
+ * namespace, using a leading colon to access other namespaces.
+ *
+ * @param {ve.dm.MWTransclusionModel} transclusion Transclusion template is in
+ * @param {string} name Template name
+ * @returns {ve.dm.MWTemplateModel} New template model
+ */
+ve.dm.MWTemplateModel.newFromName = function ( transclusion, name ) {
+       var href = name;
+
+       if ( href.charAt( 0 ) !== ':' ) {
+               href = mw.config.get( 'wgFormattedNamespaces' )[10] + ':' + 
href;
+       }
+       href = new mw.Title( href ).getPrefixedText();
+
+       return new ve.dm.MWTemplateModel( transclusion, { 'href': href, 'wt': 
name }, 'user' );
+};
+
 /* Methods */
 
 /**
@@ -56,6 +107,15 @@
  */
 ve.dm.MWTemplateModel.prototype.getTarget = function () {
        return this.target;
+};
+
+/**
+ * Get template origin, e.g. 'user' or 'data'.
+ *
+ * @returns {string} Origin
+ */
+ve.dm.MWTemplateModel.prototype.getOrigin = function () {
+       return this.origin;
 };
 
 /**
@@ -195,3 +255,30 @@
                this.emit( 'remove', param );
        }
 };
+
+/**
+ * Set original data, to be used as a base for serialization.
+ *
+ * @method
+ * @returns {Object} Template data
+ */
+ve.dm.MWTemplateModel.prototype.setOriginalData = function ( data ) {
+       this.originalData = data;
+};
+
+/**
+ * @inheritdoc
+ */
+ve.dm.MWTemplateModel.prototype.serialize = function () {
+       var name,
+               template = ve.extendObject(
+                       this.originalData || {}, { 'target': this.getTarget(), 
'params': {} }
+               ),
+               params = this.getParameters();
+
+       for ( name in params ) {
+               template.params[params[name].getOriginalName()] = { 'wt': 
params[name].getValue() };
+       }
+
+       return { 'template': template };
+};
diff --git a/modules/ve-mw/dm/models/ve.dm.MWTemplatePlaceholderModel.js 
b/modules/ve-mw/dm/models/ve.dm.MWTemplatePlaceholderModel.js
index e54d7ba..4f3250c 100644
--- a/modules/ve-mw/dm/models/ve.dm.MWTemplatePlaceholderModel.js
+++ b/modules/ve-mw/dm/models/ve.dm.MWTemplatePlaceholderModel.js
@@ -13,11 +13,10 @@
  *
  * @constructor
  * @param {ve.dm.MWTransclusionModel} transclusion Transclusion
- * @param {string} [origin] Origin of part, e.g. 'data' or 'user'
  */
-ve.dm.MWTemplatePlaceholderModel = function VeDmMWTemplatePlaceholderModel( 
transclusion, origin ) {
+ve.dm.MWTemplatePlaceholderModel = function VeDmMWTemplatePlaceholderModel( 
transclusion ) {
        // Parent constructor
-       ve.dm.MWTransclusionPartModel.call( this, transclusion, origin );
+       ve.dm.MWTransclusionPartModel.call( this, transclusion );
 };
 
 /* Inheritance */
diff --git a/modules/ve-mw/dm/models/ve.dm.MWTransclusionContentModel.js 
b/modules/ve-mw/dm/models/ve.dm.MWTransclusionContentModel.js
index f8b8240..a517a81 100644
--- a/modules/ve-mw/dm/models/ve.dm.MWTransclusionContentModel.js
+++ b/modules/ve-mw/dm/models/ve.dm.MWTransclusionContentModel.js
@@ -14,12 +14,10 @@
  * @constructor
  * @param {ve.dm.MWTransclusionModel} transclusion Transclusion
  * @param {string} [value] Content value
- * @param {string} [origin] Origin of part, e.g. 'data' or 'user'
  */
-ve.dm.MWTransclusionContentModel =
-       function VeDmMWTransclusionContentModel( transclusion, value, origin ) {
+ve.dm.MWTransclusionContentModel = function VeDmMWTransclusionContentModel( 
transclusion, value ) {
        // Parent constructor
-       ve.dm.MWTransclusionPartModel.call( this, transclusion, origin );
+       ve.dm.MWTransclusionPartModel.call( this, transclusion );
 
        // Properties
        this.value = value || '';
@@ -50,3 +48,10 @@
 ve.dm.MWTransclusionContentModel.prototype.setValue = function ( value ) {
        this.value = value;
 };
+
+/**
+ * @inheritdoc
+ */
+ve.dm.MWTransclusionContentModel.prototype.serialize = function () {
+       return this.getValue();
+};
diff --git a/modules/ve-mw/dm/models/ve.dm.MWTransclusionModel.js 
b/modules/ve-mw/dm/models/ve.dm.MWTransclusionModel.js
index 9c82ee7..17b662d 100644
--- a/modules/ve-mw/dm/models/ve.dm.MWTransclusionModel.js
+++ b/modules/ve-mw/dm/models/ve.dm.MWTransclusionModel.js
@@ -56,7 +56,7 @@
  * @returns {jQuery.Promise} Promise, resolved when spec is loaded
  */
 ve.dm.MWTransclusionModel.prototype.load = function ( data ) {
-       var i, len, key, part, template;
+       var i, len, part;
 
        // Convert single part format to multi-part format
        if ( data.params && data.target ) {
@@ -67,19 +67,13 @@
                for ( i = 0, len = data.parts.length; i < len; i++ ) {
                        part = data.parts[i];
                        if ( part.template ) {
-                               template = new ve.dm.MWTemplateModel( this, 
part.template.target, 'data' );
-                               for ( key in part.template.params ) {
-                                       template.addParameter(
-                                               new 
ve.dm.MWTemplateParameterModel(
-                                                       template, key, 
part.template.params[key].wt, 'data'
-                                               )
-                                       );
-                               }
-                               this.queue.push( { 'part': template } );
+                               this.queue.push(
+                                       { 'part': 
ve.dm.MWTemplateModel.newFromData( this, part.template ) }
+                               );
                        } else if ( typeof part === 'string' ) {
-                               this.queue.push( {
-                                       'part': new 
ve.dm.MWTransclusionContentModel( this, part, 'data' )
-                               } );
+                               this.queue.push(
+                                       { 'part': new 
ve.dm.MWTransclusionContentModel( this, part, 'data' ) }
+                               );
                        }
                }
                setTimeout( ve.bind( this.fetch, this ) );
@@ -223,20 +217,14 @@
  * @returns {Object|null} Plain object representation, or null if empty
  */
 ve.dm.MWTransclusionModel.prototype.getPlainObject = function () {
-       var i, len, part, template, name, params,
+       var i, len, part, serialization,
                obj = { 'parts': [] };
 
        for ( i = 0, len = this.parts.length; i < len; i++ ) {
                part = this.parts[i];
-               if ( part instanceof ve.dm.MWTemplateModel ) {
-                       template = { 'target': part.getTarget(), 'params': {} };
-                       params = part.getParameters();
-                       for ( name in params ) {
-                               template.params[params[name].getOriginalName()] 
= { 'wt': params[name].getValue() };
-                       }
-                       obj.parts.push( { 'template': template } );
-               } else if ( part instanceof ve.dm.MWTransclusionContentModel ) {
-                       obj.parts.push( part.getValue() );
+               serialization = part.serialize();
+               if ( serialization !== undefined ) {
+                       obj.parts.push( serialization );
                }
        }
 
diff --git a/modules/ve-mw/dm/models/ve.dm.MWTransclusionPartModel.js 
b/modules/ve-mw/dm/models/ve.dm.MWTransclusionPartModel.js
index d03fb55..fca9552 100644
--- a/modules/ve-mw/dm/models/ve.dm.MWTransclusionPartModel.js
+++ b/modules/ve-mw/dm/models/ve.dm.MWTransclusionPartModel.js
@@ -13,15 +13,13 @@
  *
  * @constructor
  * @param {ve.dm.MWTransclusionModel} transclusion Transclusion
- * @param {string} [origin] Origin of part, e.g. 'data' or 'user'
  */
-ve.dm.MWTransclusionPartModel = function VeDmMWTransclusionPartModel( 
transclusion, origin ) {
+ve.dm.MWTransclusionPartModel = function VeDmMWTransclusionPartModel( 
transclusion ) {
        // Mixin constructors
        ve.EventEmitter.call( this );
 
        // Properties
        this.transclusion = transclusion;
-       this.origin = origin;
        this.id = 'part_' + this.transclusion.getUniquePartId();
 };
 
@@ -42,15 +40,6 @@
 };
 
 /**
- * Get part origin.
- *
- * @returns {string} Origin
- */
-ve.dm.MWTransclusionPartModel.prototype.getOrigin = function () {
-       return this.origin;
-};
-
-/**
  * Get a unique part ID within the transclusion.
  *
  * @returns {string} Unique ID
@@ -67,3 +56,13 @@
 ve.dm.MWTransclusionPartModel.prototype.remove = function () {
        this.transclusion.removePart( this );
 };
+
+/**
+ * Get serialized representation of transclusion part.
+ *
+ * @method
+ * @returns {mixed} Serialized representation, or undefined if empty
+ */
+ve.dm.MWTransclusionPartModel.prototype.serialize = function () {
+       return undefined;
+};
diff --git a/modules/ve-mw/ui/dialogs/ve.ui.MWTransclusionDialog.js 
b/modules/ve-mw/ui/dialogs/ve.ui.MWTransclusionDialog.js
index caa28d4..aadf512 100644
--- a/modules/ve-mw/ui/dialogs/ve.ui.MWTransclusionDialog.js
+++ b/modules/ve-mw/ui/dialogs/ve.ui.MWTransclusionDialog.js
@@ -5,8 +5,6 @@
  * @license The MIT License (MIT); see LICENSE.txt
  */
 
-/*global mw */
-
 /**
  * Dialog for editing a MediaWiki transclusion.
  *
@@ -551,17 +549,11 @@
                label = ve.msg( 'visualeditor-dialog-transclusion-placeholder' 
);
 
        function addTemplate() {
-               var target, part,
-                       parts = placeholder.getTransclusion().getParts(),
-                       value = addTemplateInput.getValue(),
-                       href = value;
+               var parts = placeholder.getTransclusion().getParts(),
+                       part = ve.dm.MWTemplateModel.newFromName(
+                               this.transclusion, addTemplateInput.getValue()
+                       );
 
-               if ( href.charAt( 0 ) !== ':' ) {
-                       href = mw.config.get( 'wgFormattedNamespaces' )[10] + 
':' + href;
-               }
-
-               target = { 'href': new mw.Title( href ).getPrefixedText(), 
'wt': value };
-               part = new ve.dm.MWTemplateModel( this.transclusion, target, 
'user' );
                this.transclusion.addPart( part, ve.indexOf( placeholder, parts 
) );
                this.pending.push( { 'part': part, 'placeholder': placeholder } 
);
                addTemplateInput.pushPending();

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

Gerrit-MessageType: newchange
Gerrit-Change-Id: Ide596a0ca0ae8f93ffce6e79b7234a1db7e0586c
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/VisualEditor
Gerrit-Branch: master
Gerrit-Owner: Trevor Parscal <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to