Share code between conflict resolution and the edit source switch

Each used their own implementation of building a form and submitting it.
The edit source one wasn't passing in the oldid, which caused edit
conflicts.

Also introduced a separation between form fields (for the action=edit UI)
and API options, building one from the other.

Bug: 56835
Change-Id: I38547b4ba1827f4028a2255109cba2a57cd59e8a
This commit is contained in:
Roan Kattouw 2013-11-15 12:30:57 -08:00 committed by Catrope
parent 72b0d2a19c
commit 35e20d954f
2 changed files with 63 additions and 68 deletions

View file

@ -841,30 +841,7 @@ ve.init.mw.ViewPageTarget.prototype.editSource = function () {
doc.getInternalList(),
doc.getInnerWhitespace()
),
ve.bind( function ( wikitext ) {
var $form,
options = this.getSaveOptions(),
action = new mw.Uri( mw.util.wikiScript() ).extend( { title: this.pageName, action: 'edit' } ).toString();
this.submitting = true;
$form = $( '<form method="post" enctype="multipart/form-data" style="display: none;"></form>' )
.attr( 'action', action )
.append( $( '<textarea name="wpTextbox1"></textarea>' ).val( wikitext ) )
.append( $( '<input type="checkbox" name="wpMinoredit" value="1">' ).prop( 'checked', options.minor ) )
.append( $( '<input type="checkbox" name="wpWatchthis" value="1">' ).prop( 'checked', options.watch ) )
.append( $( '<input type="hidden" name="wpSummary">' ).val( options.summary ) )
.append( $( '<input type="hidden" name="wpStarttime">' ).val( this.startTimeStamp ) )
.append( $( '<input type="hidden" name="wpEditToken">' ).val( this.editToken ) )
.append( $( '<input type="hidden" name="wpDiff" value="1">' ) )
.append( $( '<input type="hidden" name="model" value="wikitext">' ) )
.append( $( '<input type="hidden" name="format" value="text/x-wiki">' ) )
.append( $( '<input type="hidden" name="wpEdittime">' ) )
;
// Firefox requires the form to be attached
$( 'body' ).append( $form );
$form.submit();
}, this )
ve.bind( this.submitWithSaveFields, this, { 'wpDiff': 1 } )
);
};
@ -877,46 +854,68 @@ ve.init.mw.ViewPageTarget.prototype.onSaveDialogResolveConflict = function () {
// Get Wikitext from the DOM, and set up a submit call when it's done
this.serialize(
this.docToSave,
ve.bind( function ( wikitext ) {
this.submit( wikitext, this.getSaveOptions() );
}, this )
ve.bind( this.submitWithSaveFields, this, { 'wpSave': 1 } )
);
};
/**
* Get save options from the save dialog form.
*
* @method
* @returns {Object} Save options, including summary, minor and watch properties
* Get save form fields from the save dialog form.
* @returns {Object} Form data for submission to the MediaWiki action=edit UI
*/
ve.init.mw.ViewPageTarget.prototype.getSaveOptions = function () {
var options = {
'summary': this.saveDialog.editSummaryInput.$input.val(),
'captchaid': this.captcha && this.captcha.id,
'captchaword': this.captcha && this.captcha.input.getValue()
};
if ( this.sanityCheckPromise.state() === 'rejected' ) {
options.needcheck = 1;
}
if ( this.saveDialog.$saveOptions.find( '#wpMinoredit' ).prop( 'checked' ) ) {
options.minor = 1;
}
if ( this.saveDialog.$saveOptions.find( '#wpWatchthis' ).prop( 'checked' ) ) {
options.watch = 1;
} else {
// Firefox has Object.prototype.watch
options.watch = undefined;
}
ve.init.mw.ViewPageTarget.prototype.getSaveFields = function () {
var fields = {};
this.$checkboxes
.not( '#wpMinoredit, #wpWatchthis' )
.each( function () {
var $this = $( this );
// We can't just use $this.val() because .val() always returns the value attribute of
// a checkbox even when it's unchecked
if ( $this.prop( 'type') !== 'checkbox' || $this.prop( 'checked' ) ) {
options[$this.prop( 'name' )] = $this.val();
if ( $this.prop( 'type' ) !== 'checkbox' || $this.prop( 'checked' ) ) {
fields[$this.prop( 'name' )] = $this.val();
}
} );
$.extend( fields, {
'wpSummary': this.saveDialog.editSummaryInput.getValue(),
'wpCaptchaId': this.captcha && this.captcha.id,
'wpCaptchaWord': this.captcha && this.captcha.input.getValue()
} );
return fields;
};
/**
* Invoke #submit with the data from #getSaveFields
* @param {Object} fields Fields to add in addition to those from #getSaveFields
* @param {string} wikitext Wikitext to submit
* @returns {boolean} Whether submission was started
*/
ve.init.mw.ViewPageTarget.prototype.submitWithSaveFields = function ( fields, wikitext ) {
return this.submit( wikitext, $.extend( this.getSaveFields(), fields ) );
};
/**
* Get edit API options from the save dialog form.
* @returns {Object} Save options for submission to the MediaWiki API
*/
ve.init.mw.ViewPageTarget.prototype.getSaveOptions = function () {
var key, options = this.getSaveFields(),
fieldMap = {
'wpSummary': 'summary',
'wpMinoredit': 'minor',
'wpWatchthis': 'watch',
'wpCaptchaId': 'captchaid',
'wpCaptchaWord': 'captchaword'
};
for ( key in fieldMap ) {
if ( options[key] !== undefined ) {
options[fieldMap[key]] = options[key];
delete options[key];
}
}
if ( this.sanityCheckPromise.state() === 'rejected' ) {
options.needcheck = 1;
}
return options;
};

View file

@ -785,21 +785,19 @@ ve.init.mw.Target.prototype.showChanges = function ( doc ) {
};
/**
* Post DOM data to the Parsoid API.
* Post wikitext to MediaWiki.
*
* This method performs a synchronous action and will take the user to a new page when complete.
*
* target.submit( wikitext, { 'summary': 'test', 'minor': true, 'watch': false } );
* target.submit( wikitext, { 'wpSummary': 'test', 'wpMinorEdit': 1, 'wpSave': 1 } );
*
* @method
* @param {string} wikitext Wikitext to submit
* @param {Object} options Saving options
* - {string} summary Edit summary
* - {boolean} minor Edit is a minor edit
* - {boolean} watch Watch the page
* @param {Object} fields Other form fields to add (e.g. wpSummary, wpWatchthis, etc.). To actually
* save the wikitext, add { 'wpSave': 1 }. To go to the diff view, add { 'wpDiff': 1 }.
* @returns {boolean} Submitting has been started
*/
ve.init.mw.Target.prototype.submit = function ( wikitext, options ) {
ve.init.mw.Target.prototype.submit = function ( wikitext, fields ) {
// Prevent duplicate requests
if ( this.submitting ) {
return false;
@ -807,24 +805,22 @@ ve.init.mw.Target.prototype.submit = function ( wikitext, options ) {
// Save DOM
this.submitting = true;
var key,
$form = $( '<form method="post" enctype="multipart/form-data"></form>' ),
params = {
$form = $( '<form method="post" enctype="multipart/form-data" style="display: none;"></form>' ),
params = $.extend( {
'format': 'text/x-wiki',
'model': 'wikitext',
'oldid': this.revid,
'wpStarttime': this.baseTimeStamp,
'wpEdittime': this.startTimeStamp,
'wpTextbox1': wikitext,
'wpSummary': options.summary,
'wpWatchthis': Number( options.watch ),
'wpMinoredit': Number( options.minor ),
'wpEditToken': this.editToken,
'wpSave': 1
};
'wpEditToken': this.editToken
}, fields );
// Add params as hidden fields
for ( key in params ) {
$form.append( $( '<input type="hidden">' ).attr( { 'name': key, 'value': params[key] } ) );
$form.append( $( '<input>' ).attr( { 'type': 'hidden', 'name': key, 'value': params[key] } ) );
}
// Submit the form, mimicking a traditional edit
// Firefox requires the form to be attached
$form.attr( 'action', this.submitUrl ).appendTo( 'body' ).submit();
return true;
};