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