' );
this.$toolbar = null;
this.surface = null;
this.active = false;
this.edited = false;
this.activating = false;
this.proxiedOnSurfaceModelTransact = ve.proxy( this.onSurfaceModelTransact, this );
this.surfaceOptions = {
'toolbars': {
'top': {
// If mobile device, float false
'float': !this.isMobileDevice,
// Toolbar modes
'modes': ['wikitext']
}
}
};
// Initialization
if ( mw.config.get('wgCanonicalNamespace') === 'VisualEditor' ) {
// Clicking the edit tab is the only way any other code gets run, and this sets that up
this.setupTabs();
}
};
/* Static Members */
/*jshint multistr: true*/
ve.init.ViewPageTarget.saveDialogTemplate = '\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
\
';
/* Methods */
/**
* ...
*
* @method
*/
ve.init.ViewPageTarget.prototype.onEditTabClick = function( e ) {
// Ignore multiple clicks while editor is active
if ( !this.active && !this.activating ) {
this.activating = true;
// UI updates
this.setSelectedTab( 'ca-edit' );
this.showSpinner();
// Asynchronous initialization - load ve modules at the same time as the content
this.load( ve.proxy( this.onLoad, this ) );
}
// Prevent the edit tab's normal behavior
e.preventDefault();
return false;
};
/**
* ...
*
* @method
*/
ve.init.ViewPageTarget.prototype.onViewTabClick = function( e ) {
// Don't do anything special unless we are in editing mode
if ( this.active ) {
if (
!this.surface.getModel().getHistory().length ||
confirm( 'Are you sure you want to go back to view mode without saving first?' )
) {
this.tearDownSurface();
}
// Prevent the edit tab's normal behavior
e.preventDefault();
return false;
}
};
/**
* ...
*
* @method
*/
ve.init.ViewPageTarget.prototype.onSaveDialogSaveButtonClick = function( e ) {
this.showSpinner();
// Save
this.save(
ve.dm.converter.getDomFromData( this.surface.getDocumentModel().getData() ),
{
'summary': $( '#ve-init-viewPageTarget-saveDialog-editSummary' ).val(),
'minor': $( '#ve-init-viewPageTarget-saveDialog-minorEdit' ).prop( 'checked' ),
'watch': $( '#ve-init-viewPageTarget-saveDialog-watchList' ).prop( 'checked' )
},
ve.proxy( this.onSave, this )
);
};
/**
* ...
*
* @method
*/
ve.init.ViewPageTarget.prototype.onSurfaceModelTransact = function() {
if ( !this.edited ) {
this.edited = true;
this.$toolbar.find( '.ve-init-viewPageTarget-saveButton ' )
.removeClass( 've-init-viewPageTarget-button-disabled' );
this.surface.getModel().removeListener( 'transact', this.proxiedOnSurfaceModelTransact );
}
};
/**
* ...
*
* @method
*/
ve.init.ViewPageTarget.prototype.onSaveButtonClick = function( e ) {
if ( this.edited ) {
this.$dialog.fadeIn( 'fast' );
this.$dialog.find( 'input:first' ).focus();
}
};
/**
* ...
*
* @method
*/
ve.init.ViewPageTarget.prototype.onSaveDialogCloseButtonClick = function( e ) {
this.$dialog.fadeOut( 'fast' );
this.$surface.find( '.ve-ce-documentNode' ).focus();
};
/**
* ...
*
* @method
*/
ve.init.ViewPageTarget.prototype.onLoad = function( error, dom ) {
this.activating = false;
if ( error ) {
// TODO: Error handling in the UI
} else {
this.edited = false;
this.setUpSurface( dom );
this.$surface.find( '.ve-ce-documentNode' ).focus();
}
};
/**
* ...
*
* @method
*/
ve.init.ViewPageTarget.prototype.onSave = function( error, content ) {
if ( error ) {
// TODO: Handle error in UI
} else {
// Hide the save dialog
this.$dialog.fadeOut();
// Refresh page with changed content
this.$content.find( '#mw-content-text' ).html( content );
// Restore the page to how it used to be
this.tearDownSurface();
}
};
/**
* ...
*
* @method
*/
ve.init.ViewPageTarget.prototype.setUpSurface = function( dom ) {
// Initialize surface
this.$surface.appendTo( this.$content );
this.surface = new ve.Surface( this.$surface, dom, this.surfaceOptions );
this.surface.getModel().on( 'transact', this.proxiedOnSurfaceModelTransact );
// Transplant the toolbar
this.$toolbar = this.$surface.find( '.es-toolbar-wrapper' );
this.$toolbar.find( '.es-toolbar' ).slideDown( 'fast' );
this.$heading
.before( this.$toolbar )
.addClass( 've-init-viewPageTarget-pageTitle' )
.fadeTo( 'fast', 0.5 );
// Update UI
this.$view.hide();
this.$spinner.remove();
this.$dialog = $( ve.init.ViewPageTarget.saveDialogTemplate );
// Add save and close buttons
this.$toolbar
.find( '.es-modes' )
.append(
$( '' )
.addClass(
've-init-viewPageTarget-button ' +
've-init-viewPageTarget-button-disabled ' +
've-init-viewPageTarget-saveButton'
)
.append(
$( '' )
.text( mw.msg( 'savearticle' ) )
)
.append( $( '' ) )
.mousedown( function( e ) {
e.preventDefault();
return false;
} )
.click( ve.proxy( this.onSaveButtonClick, this ) )
);
// Set up save dialog
this.$dialog
.find( '.ve-init-viewPageTarget-saveDialog-title' )
.text( mw.msg( 'tooltip-save' ) )
.end()
.find( '.ve-init-viewPageTarget-saveDialog-closeButton' )
.click( ve.proxy( this.onSaveDialogCloseButtonClick, this ) )
.end()
.find( '.ve-init-viewPageTarget-saveDialog-editSummary-label' )
.text( mw.msg( 'summary' ) )
.end()
.find( '.ve-init-viewPageTarget-saveDialog-minorEdit-label' )
.text( mw.msg( 'minoredit' ) )
.end()
.find( '.ve-init-viewPageTarget-saveDialog-watchList' )
.prop( 'checked', ve.config.isPageWatched )
.end()
.find( '.ve-init-viewPageTarget-saveDialog-watchList-label' )
.text( mw.msg( 'watchthis' ) )
.end()
.find( '.ve-init-viewPageTarget-saveDialog-saveButton' )
.click( ve.proxy( this.onSaveDialogSaveButtonClick, this ) )
.end()
.find( '.ve-init-viewPageTarget-saveDialog-saveButton-label' )
.text( mw.msg( 'savearticle' ) )
.end()
.find( '.ve-init-viewPageTarget-saveDialog-license' )
.html(
"By editing this page, you agree to irrevocably release your \
contributions under the CC-By-SA 3.0 License. If you don't want your \
writing to be editied mercilessly and redistrubuted at will, then \
don't submit it here.
You are also confirming that you \
wrote this yourself, or copied it from a public domain or similar free \
resource. See Project:Copyright for full details of the licenses \
used on this site.\
DO NOT SUBMIT COPYRIGHTED WORK WITHOUT PERMISSION!"
)
.end()
.insertAfter( this.$toolbar.find( '.ve-init-viewPageTarget-saveButton' ) );
this.active = true;
};
ve.init.ViewPageTarget.prototype.tearDownSurface = function( content ) {
// Reset tabs
this.setSelectedTab( 'ca-view' );
// Update UI
this.$surface.empty().detach();
this.$toolbar.find( '.es-toolbar' ).slideUp( 'fast', function() {
$(this).parent().remove();
} );
this.$spinner.remove();
$( '.es-contextView' ).remove();
this.$view.show().fadeTo( 'fast', 1 );
this.$heading.fadeTo( 'fast', 1 );
setTimeout( ve.proxy( function() {
$(this).removeClass( 've-init-viewPageTarget-pageTitle' );
}, this.$heading ), 1000 );
// Destroy editor
this.surface = null;
this.active = false;
};
ve.init.ViewPageTarget.prototype.setupTabs = function(){
// Only sysop users will have an edit tab in this namespace, so we might need to add one
if ( $( '#ca-edit' ).length === 0 ) {
// Add edit tab
mw.util.addPortletLink(
'p-views',
'#',
mw.msg( 'edit' ),
'ca-edit',
mw.msg( 'tooltip-ca-edit' ),
mw.msg( 'accesskey-ca-edit' ),
'#ca-history'
);
// If there isn't an edit tab, there's a view source tab we need to replace with edit source
var $viewSource = $( '#ca-viewsource' );
if ( $viewSource.length > 0 ) {
// "Move" the view source link to p-actions
mw.util.addPortletLink(
'p-cactions',
$viewSource.find( 'a' ).attr( 'href' ),
$viewSource.find( 'a' ).text(),
$viewSource.attr( 'id' )
);
// Remove the view original source link
$viewSource.remove();
}
} else {
// Sysop users will need a new edit source tab since we are highjacking the edit tab
mw.util.addPortletLink(
'p-cactions',
mw.util.wikiGetlink() + '?action=edit',
'Edit Source', // TODO: i18n
'ca-editsource'
);
}
$( '#ca-edit > span > a' ).click( ve.proxy( this.onEditTabClick, this ) );
$( '#ca-view > span > a' ).click( ve.proxy( this.onViewTabClick, this ) );
};
/**
* Shows a loading spinner.
*
* @method
*/
ve.init.ViewPageTarget.prototype.showSpinner = function() {
this.$spinner = $( '' )
.addClass( 've-init-viewPageTarget-loadingSpinner' )
.prependTo( this.$heading );
};
/**
* Resets all tabs in the UI and selects a specific one.
*
* If no ID is given, or no ID matches the given ID, all tabs will be unselected.
*
* @method
* @param {String} id HTML ID of tab to select
*/
ve.init.ViewPageTarget.prototype.setSelectedTab = function( id ) {
$( '#p-views' ).find( 'li.selected' ).removeClass( 'selected' );
$( '#' + id ).addClass( 'selected' );
};
/* Inheritance */
ve.extendClass( ve.init.ViewPageTarget, ve.init.Target );
/* Initialization */
// TODO: Clean this stuff up
ve.config = mw.config.get( 'wgVisualEditor' );
ve.init.current = new ve.init.ViewPageTarget();