/*! * VisualEditor MediaWiki Initialization ViewPageTarget class. * * @copyright 2011-2013 VisualEditor Team and others; see AUTHORS.txt * @license The MIT License (MIT); see LICENSE.txt */ /*global mw, confirm, alert */ /** * Initialization MediaWiki view page target. * * @class * @extends ve.init.mw.Target * * @constructor */ ve.init.mw.ViewPageTarget = function VeInitMwViewPageTarget() { var browserWhitelisted, currentUri = new mw.Uri(); // Parent constructor ve.init.mw.Target.call( this, $( '#content' ), mw.config.get( 'wgRelevantPageName' ), currentUri.query.oldid ); // Properties this.$document = null; this.$spinner = $( '
' ); this.$toolbarTracker = $( '' ); this.toolbarTrackerFloating = null; this.toolbarOffset = null; this.toolbarCancelButton = null; this.toolbarSaveButton = null; this.saveDialogSlideHistory = []; this.saveDialogSaveButton = null; this.saveDialogReviewGoodButton = null; this.$toolbarEditNotices = $( '' ).append(
$( '' ).text( mw.msg( 'captcha-label' ) ),
document.createTextNode( mw.msg( 'colon-separator' ) ),
$( $.parseHTML( mw.message( 'fancycaptcha-edit' ).parse() ) )
.filter( 'a' ).attr( 'target', '_blank ' ).end()
),
$( '' ).attr( 'src', editApi.captcha.url ),
this.captcha.input.$
),
{
wrap: false
}
);
return;
}
// Handle (other) unknown and/or unrecoverable errors
this.showMessage(
'api-save-error',
document.createTextNode(
( editApi && editApi.info ) ||
( data.error && data.error.info ) ||
( editApi && editApi.code ) ||
( data.error && data.error.code ) ||
'Unknown error'
),
{
wrap: 'error'
}
);
this.saveDialogSaveButton.setDisabled( true );
};
/**
* Handle Show changes event.
*
* @method
* @param {string} diffHtml
*/
ve.init.mw.ViewPageTarget.prototype.onShowChanges = function ( diffHtml ) {
// Invalidate the viewer diff on next change
this.surface.getModel().connect( this, { 'transact': 'onSurfaceModelTransact' } );
mw.loader.using( 'mediawiki.action.history.diff', ve.bind( function () {
this.$saveDialog
.find( '.ve-init-mw-viewPageTarget-saveDialog-viewer' )
.empty().append( diffHtml );
this.$saveDialogLoadingIcon.hide();
this.saveDialogReviewGoodButton.setDisabled( false );
}, this ), ve.bind( function () {
this.onSaveError( null, 'Module load failed' );
}, this ) );
};
/**
* Handle Serialize event.
*
* @method
* @param {string} wikitext
*/
ve.init.mw.ViewPageTarget.prototype.onSerialize = function ( wikitext ) {
// Invalidate the viewer wikitext on next change
this.surface.getModel().connect( this, { 'transact': 'onSurfaceModelTransact' } );
this.$saveDialog
.find( '.ve-init-mw-viewPageTarget-saveDialog-viewer' )
.empty().append( $( '' ).text( wikitext ) );
this.$saveDialogLoadingIcon.hide();
this.saveDialogReviewGoodButton.setDisabled( false );
};
/**
* Handle failed show changes event.
*
* @method
* @param {Object} jqXHR
* @param {string} status Text status message
*/
ve.init.mw.ViewPageTarget.prototype.onShowChangesError = function ( jqXHR, status ) {
alert( ve.msg( 'visualeditor-differror', status ) );
this.$saveDialogLoadingIcon.hide();
};
/**
* Called if a call to target.serialize() failed.
*
* @method
* @param {jqXHR|null} jqXHR
* @param {string} status Text status message
*/
ve.init.mw.ViewPageTarget.prototype.onSerializeError = function ( jqXHR, status ) {
alert( ve.msg( 'visualeditor-serializeerror', status ) );
this.$saveDialogLoadingIcon.hide();
};
/**
* Handle edit conflict event.
*
* @method
*/
ve.init.mw.ViewPageTarget.prototype.onEditConflict = function () {
this.$saveDialogLoadingIcon.hide();
this.swapSaveDialog( 'conflict' );
};
/**
* Handle failed show changes event.
*
* @method
*/
ve.init.mw.ViewPageTarget.prototype.onNoChanges = function () {
this.$saveDialogLoadingIcon.hide();
this.swapSaveDialog( 'nochanges' );
};
/**
* Handle clicks on the view tab.
*
* @method
* @param {jQuery.Event} e Mouse click event
*/
ve.init.mw.ViewPageTarget.prototype.onViewTabClick = function ( e ) {
if ( ( e.which && e.which !== 1 ) || e.shiftKey || e.altKey || e.ctrlKey || e.metaKey ) {
return;
}
if ( this.active ) {
this.deactivate();
// Prevent the edit tab's normal behavior
e.preventDefault();
} else if ( this.activating ) {
this.deactivate( true );
this.activating = false;
e.preventDefault();
}
};
/**
* Handle clicks on the save button in the toolbar.
*
* @method
* @param {jQuery.Event} e Mouse click event
*/
ve.init.mw.ViewPageTarget.prototype.onToolbarSaveButtonClick = function () {
ve.track( 'Edit', { action: 'page-save-attempt' } );
if ( this.edited || this.restoring ) {
this.showSaveDialog();
}
};
/**
* Handle clicks on the save button in the toolbar.
*
* @method
* @param {jQuery.Event} e Mouse click event
*/
ve.init.mw.ViewPageTarget.prototype.onToolbarCancelButtonClick = function () {
this.deactivate();
};
/**
* Handle clicks on the MwMeta button in the toolbar.
*
* @method
* @param {jQuery.Event} e Mouse click event
*/
ve.init.mw.ViewPageTarget.prototype.onToolbarMwMetaButtonClick = function () {
this.surface.getDialogs().open( 'meta' );
};
/**
* Handle clicks on the edit notices tool in the toolbar.
*
* @method
* @param {jQuery.Event} e Mouse click event
*/
ve.init.mw.ViewPageTarget.prototype.onToolbarEditNoticesToolClick = function () {
this.$toolbarEditNotices.fadeToggle( 'fast' );
this.$toolbarBetaNotice.fadeOut( 'fast' );
this.$document[0].focus();
};
/**
* Handle clicks on the beta notices tool in the toolbar.
*
* @method
* @param {jQuery.Event} e Mouse click event
*/
ve.init.mw.ViewPageTarget.prototype.onToolbarBetaNoticeToolClick = function () {
this.$toolbarBetaNotice.fadeToggle( 'fast' );
this.$toolbarEditNotices.fadeOut( 'fast' );
this.$document[0].focus();
};
/**
* Handle clicks on the feedback tool in the toolbar.
*
* @method
* @param {jQuery.Event} e Mouse click event
*/
ve.init.mw.ViewPageTarget.prototype.onToolbarFeedbackToolClick = function () {
this.$toolbarEditNotices.fadeOut( 'fast' );
if ( !this.feedback ) {
// This can't be constructed until the editor has loaded as it uses special messages
this.feedback = new mw.Feedback( {
'title': new mw.Title( ve.msg( 'visualeditor-feedback-link' ) ),
'bugsLink': new mw.Uri( 'https://bugzilla.wikimedia.org/enter_bug.cgi?product=VisualEditor&component=General' ),
'bugsListLink': new mw.Uri( 'https://bugzilla.wikimedia.org/buglist.cgi?query_format=advanced&resolution=---&resolution=LATER&resolution=DUPLICATE&product=VisualEditor&list_id=166234' )
} );
}
this.feedback.launch();
};
/**
* Handle the first transaction in the surface model.
*
* This handler is removed the first time it's used, but added each time the surface is set up.
*
* @method
* @param {ve.dm.Transaction} tx Processed transaction
*/
ve.init.mw.ViewPageTarget.prototype.onSurfaceModelTransact = function () {
// Clear the diff
this.$saveDialog
.find( '.ve-init-mw-viewPageTarget-saveDialog-slide-review .ve-init-mw-viewPageTarget-saveDialog-viewer' )
.empty();
this.surface.getModel().disconnect( this, { 'transact': 'onSurfaceModelTransact' } );
};
/**
* Handle changes to the surface model.
*
* This is used to trigger notifications when the user starts entering wikitext
*
* @param {ve.dm.Transaction} tx
* @param {ve.Range} range
*/
ve.init.mw.ViewPageTarget.prototype.onSurfaceModelChange = function ( tx, range ) {
if ( !range ) {
return;
}
var text, doc = this.surface.getView().getDocument(),
node = doc.getNodeFromOffset( range.start );
if ( !( node instanceof ve.ce.ContentBranchNode ) ) {
return;
}
text = ve.ce.getDomText( node.$[0] );
if ( text.match( /\[\[|\{\{|''|