MediaWiki:Gadget-WikiSign.js
Jump to navigation
Jump to search
Note: After publishing, you may have to bypass your browser's cache to see the changes.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
- Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Press Ctrl-F5.
/**
* WikiSign is a tool for easy signing and voting in Wikipedia and other wikis
* Authors: User:Sophivorus & User:Leoncastro
* License: https://creativecommons.org/licenses/by-sa/3.0/
*/
window.WikiSign = {
/**
* Internationalized messages
*
* @type {Object} Map from message key to value
*/
i18n: {
dialogTitle: 'Add your signature',
commentLabel: 'Comment (optional)',
commentPlaceholder: 'Your comment will be shown next to your signature',
nameLabel: 'Real name (optional)',
watchLabel: 'Watch this page',
signAction: 'Sign',
signManuallyAction: 'Sign manually',
cancelAction: 'Cancel',
summary: 'Add my signature',
error: 'There was an error while signing automatically.'
},
/**
* Configuration options
*
* @type {Object} Map from option key to value
*/
options: {
buttonClassName: '.sign-button',
validNamespaces: [ 0, 2, 4, 10, 102 ],
signaturePrefix: '#',
signatureSuffix: ''
},
/**
* Initialization script
*/
init: function () {
var namespace = mw.config.get( 'wgNamespaceNumber' );
if ( !WikiSign.options.validNamespaces.includes( namespace ) ) {
return;
}
var $buttons = $( WikiSign.options.buttonClassName );
if ( !$buttons.length ) {
return;
}
var action = mw.config.get( 'wgAction' );
if ( action !== 'view' ) {
return;
}
mw.loader.using( [
'mediawiki.api',
'mediawiki.user',
'oojs-ui-core',
'oojs-ui-widgets',
'oojs-ui-windows'
] ).then( function () {
$buttons.on( 'click', WikiSign.dialog );
} );
},
/**
* Build the dialog
*
* @param {jQuery.Event} Click event
* @return {bool} false
*/
dialog: function ( event ) {
var $button = $( this );
var sectionCount;
var sectionTitle;
var $section = WikiSign.findClosestSection( $button );
if ( $section ) {
var sectionID = $section.find( '.mw-headline' ).attr( 'id' );
$( '.mw-headline' ).each( function ( index ) {
if ( $( this ).attr( 'id' ) === sectionID ) {
sectionCount = index + 1;
return false;
}
} );
sectionTitle = $section.children( '.mw-headline' ).text();
}
var signaturePrefix = $button.data( 'sign-prefix' ) ? $button.data( 'sign-prefix' ) : WikiSign.options.signaturePrefix;
var signatureSuffix = $button.data( 'sign-suffix' ) ? $button.data( 'sign-suffix' ) : WikiSign.options.signatureSuffix;
var signature = '\n' + signaturePrefix + signatureSuffix + '~~' + '~~';
// If commenting is disabled, sign immediately
if ( $button.data( 'sign-no-comment' ) ) {
WikiSign.sign( signature, sectionCount, sectionTitle );
event.preventDefault();
return false;
}
// Build the dialog
var windowManager = new OO.ui.WindowManager();
var messageDialog = new OO.ui.MessageDialog();
$( 'body' ).append( windowManager.$element );
windowManager.addWindows( [ messageDialog ] );
var commentInput = new OO.ui.MultilineTextInputWidget( {
placeholder: WikiSign.i18n.commentPlaceholder,
required: $button.data( 'sign-comment-required' ) ? true : false,
rows: 3
} );
var commentLayout = new OO.ui.FieldLayout( commentInput, { label: WikiSign.i18n.commentLabel, align: 'top' } );
var nameInput = new OO.ui.TextInputWidget();
var nameLayout = new OO.ui.FieldLayout( nameInput, { label: WikiSign.i18n.nameLabel, align: 'top' } );
var fieldset = new OO.ui.FieldsetLayout( { classes: [ 'container' ], items: [ commentLayout, nameLayout ] } );
if ( !mw.user.isAnon() ) {
var watchCheckbox = new OO.ui.CheckboxInputWidget( { name: 'watch', selected: true } );
var watchLayout = new OO.ui.FieldLayout( watchCheckbox, { label: WikiSign.i18n.watchLabel, align: 'inline' } );
fieldset.addItems( watchLayout );
}
var form = new OO.ui.FormLayout( { items: [ fieldset ] } );
var dialog = windowManager.openWindow( messageDialog, {
title: WikiSign.i18n.dialogTitle,
message: form.$element,
actions: [
{ label: WikiSign.i18n.signAction, action: 'sign', flags: 'progressive' },
{ label: WikiSign.i18n.cancelAction },
],
size: 'medium',
} );
// Submit the data
dialog.closed.then( function ( data ) {
if ( data && data.action === 'sign' ) {
var comment = commentInput.getValue().trim();
var name = nameInput.getValue().trim();
var signature = [ '\n' + signaturePrefix, comment, name, signatureSuffix, '~~' + '~~' ];
signature = signature.filter( n => n ); // Remove empty elements
signature = signature.join( ' ' );
var watch = mw.user.isAnon() ? null : watchCheckbox.isSelected();
WikiSign.sign( signature, sectionCount, sectionTitle, watch );
}
windowManager.destroy();
} );
event.preventDefault();
return false;
},
/**
* Append the signature to the section or page
* @todo What if the button or some text is AFTER the list of signatures
*
* @param {string} Full signature to append
* @param {number} Section number where to append the signature
* @param {string} Section title where to append the signature
*/
sign: function ( signature, sectionCount, sectionTitle, watch ) {
var api = new mw.Api();
api.get( {
format: 'json',
formatversion: 2,
action: 'parse',
prop: 'wikitext',
page: mw.config.get( 'wgPageName' ),
section: sectionCount
} ).then( function ( result ) {
var wikitext = result.parse.wikitext;
var summary = sectionTitle ? '/' + '* ' + sectionTitle + ' *' + '/ ' + WikiSign.i18n.summary : WikiSign.i18n.summary;
api.postWithEditToken( {
action: 'edit',
title: mw.config.get( 'wgPageName' ),
text: wikitext + signature,
summary: summary,
watchlist: watch ? 'watch' : 'nochange',
section: sectionCount,
} ).then( function ( data ) {
// If we reach this point, all went well
// so reload the page to show the signature to the user
window.location.reload( true );
} ).fail( function ( errorCode ) {
// If we reach this point, something went wrong
// but rather than show an unhelpful error code
// prompt the user to sign manually
var windowManager = new OO.ui.WindowManager();
var messageDialog = new OO.ui.MessageDialog();
$( 'body' ).append( windowManager.$element );
windowManager.addWindows( [ messageDialog ] );
var errorDialog = windowManager.openWindow( messageDialog, {
message: WikiSign.i18n.error,
actions: [
{ label: WikiSign.i18n.signManuallyAction, action: 'signManually', flags: 'progressive' },
{ label: WikiSign.i18n.cancelAction }
]
} );
errorDialog.closed.then( function ( data ) {
if ( data && data.action === 'signManually' ) {
window.location.href = mw.util.getUrl( null, {
action: 'edit',
section: sectionCount ? sectionCount : null
} );
}
windowManager.destroy();
} );
} );
} );
},
/**
* Helper function to find the closest section
* by traversing back and up the DOM tree
*
* @param {jQuery object} Starting element
* @return {jQuery object} Closest section
*/
findClosestSection: function ( $element ) {
if ( $element.attr( 'id' ) === 'mw-content-text' ) {
return;
}
if ( $element.is( ':header' ) ) {
return $element;
}
var $previous = $element.prevAll( ':header' ).first();
if ( $previous.length ) {
return $previous;
}
var $parent = $element.parent();
return WikiSign.findClosestSection( $parent );
}
};
$( WikiSign.init );