/** * Edit page target. * * @class * @constructor * @extends {ve.init.Target} * @param {String} title Page title of target */ ve.init.EditPageTarget = function() { // Inheritance ve.init.Target.call( this, mw.config.get( 'wgPageName' ) ); // Properties this.$content = $( '#content' ); this.$view = this.$content.find( '#mw-content-text, #bodyContent' ); this.$heading = $( '#firstHeading' ); this.$surface = $( '
' ); this.$toolbar = null; this.surface = null; this.active = false; 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.EditPageTarget.saveDialogTemplate = '\
\
\
\
\
\ \
\
\ \ \
\ \ \
\
\ \
\
\
\
\
\

\
\
'; /* Methods */ /** * ... * * @method */ ve.init.EditPageTarget.prototype.onEditTabClick = function( e ) { // Ignore multiple clicks while editor is active if ( !this.active ) { // 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.EditPageTarget.prototype.onSaveDialogSaveButtonClick = function( e ) { this.showSpinner(); // Save this.save( ve.dm.converter.getDomFromData( this.surface.getDocumentModel().getData() ), { 'summary': $( '#ve-init-editPageTarget-saveDialog-editSummary' ).val(), 'minor': $( '#ve-init-editPageTarget-saveDialog-minorEdit' ).prop( 'checked' ), 'watch': $( '#ve-init-editPageTarget-saveDialog-watchList' ).prop( 'checked' ) }, ve.proxy( this.onSave, this ) ); }; /** * ... * * @method */ ve.init.EditPageTarget.prototype.onLoad = function( error, dom ) { if ( error ) { // TODO: Error handling in the UI } else { this.setUpSurface( dom ); this.$surface.find( '.ve-ce-documentNode' ).focus(); } }; /** * ... * * @method */ ve.init.EditPageTarget.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.EditPageTarget.prototype.setUpSurface = function( dom ) { // Initialize surface this.$surface.appendTo( this.$content ); this.surface = new ve.Surface( this.$surface, dom, this.surfaceOptions ); // Transplant the toolbar this.$toolbar = this.$surface.find( '.es-toolbar-wrapper' ).insertBefore( this.$heading ); this.$heading.animate( { 'margin-top': this.$toolbar.outerHeight() }, 'fast' ); // Update UI this.$spinner.remove(); this.$view.hide(); this.$spinner.hide(); this.$dialog = $( ve.init.EditPageTarget.saveDialogTemplate ); // Add save and close buttons this.$toolbar .find( '.es-modes' ) .append( $( '
' ) .addClass( 've-init-editPageTarget-button ve-init-editPageTarget-saveButton' ) .append( $( '' ) .text( mw.msg( 'savearticle' ) ) ) .click( ve.proxy( function() { $(this).fadeIn( 'fast' ); }, this.$dialog ) ) ); // Set up save dialog this.$dialog .find( '.ve-init-editPageTarget-saveDialog-title' ) .text( mw.msg( 'tooltip-save' ) ) .end() .find( '.ve-init-editPageTarget-saveDialog-closeButton' ) .click( ve.proxy( function() { $(this).fadeOut( 'fast' ); }, this.$dialog ) ) .end() .find( '.ve-init-editPageTarget-saveDialog-editSummary-label' ) .text( mw.msg( 'summary' ) ) .end() .find( '.ve-init-editPageTarget-saveDialog-minorEdit-label' ) .text( mw.msg( 'minoredit' ) ) .end() .find( '.ve-init-editPageTarget-saveDialog-watchList' ) .prop( 'checked', ve.config.isPageWatched ) .end() .find( '.ve-init-editPageTarget-saveDialog-watchList-label' ) .text( mw.msg( 'watchthis' ) ) .end() .find( '.ve-init-editPageTarget-saveDialog-saveButton' ) .click( ve.proxy( this.onSaveDialogSaveButtonClick, this ) ) .end() .find( '.ve-init-editPageTarget-saveDialog-saveButton-label' ) .text( mw.msg( 'savearticle' ) ) .end() .find( '.ve-init-editPageTarget-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-editPageTarget-saveButton' ) ); }; ve.init.EditPageTarget.prototype.tearDownSurface = function( content ) { // Reset tabs this.setSelectedTab( 'ca-view' ); // Update UI this.$view.show().fadeTo( 'fast', 1 ); this.$surface.remove(); this.$toolbar.remove(); this.$spinner.remove(); this.$heading.animate( { 'margin-top': 0, 'opacity': 1 }, 'fast' ); // Destroy editor this.surface = null; }; ve.init.EditPageTarget.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 ) ); }; /** * Shows a loading spinner. * * @method */ ve.init.EditPageTarget.prototype.showSpinner = function() { this.$spinner = $( '
' ) .addClass( 've-init-editPageTarget-loadingSpinner' ) .prependTo( this.$heading ); this.$heading.fadeTo( 'fast', 0.5 ); }; /** * 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.EditPageTarget.prototype.setSelectedTab = function( id ) { $( '#p-views' ).find( 'li.selected' ).removeClass( 'selected' ); $( '#' + id ).addClass( 'selected' ); }; /* Inheritance */ ve.extendClass( ve.init.EditPageTarget, ve.init.Target ); /* Initialization */ // TODO: Clean this stuff up ve.config = mw.config.get( 'wgVisualEditor' ); ve.init.current = new ve.init.EditPageTarget();