User:TolTest/Sparkle.js
Appearance
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump.
This code will be executed when previewing this page.
This code will be executed when previewing this page.
Documentation for this user script can be added at User:TolTest/Sparkle.
/*
This is a test version of Sparkle.
Use at your own risk. Or even better,
use the stable version at [[User:Tol/Sparkle.js]].
|
/#\
###
\- /###\ -/
\##\- /#####\ -/##/
\######\#######/######/
\###################/
\#################/
-/#################\-
/############ ############\
<############# Sparkle #############>
\############ ############/
-\#################/-
/#################\
/###################\
/######/#######\######\
/##/- \#####/ -\##\
/- \###/ -\
###
\#/
|
Version 0.1.0: Rewriting the whole thing (better, hopefully)
<syntaxhighlight lang="js">
*/
// Basic functions
function api_wikitext( title ) {
var params = {
action: 'parse',
page: title.getPrefixedDb(),
prop: 'wikitext',
format: 'json',
formatversion: '2'
};
return new Promise( function( resolve, reject ) {
mw.loader.using( 'mediawiki.api', function() {
api = new mw.Api();
api.get( params )
.done( function( data ) {
resolve( data.parse.wikitext );
} )
.fail( function( data ) {
resolve( '' );
} );
} );
} );
}
function api_templates( title ) {
var params = {
action: 'query',
prop: 'templates',
titles: title.getPrefixedDb(),
tllimit: 'max',
format: 'json',
formatversion: '2'
};
return new Promise( function( resolve, reject ) {
mw.loader.using( 'mediawiki.api', function() {
api = new mw.Api();
api.get( params ).done( function( data ) {
resolve( data.query.pages[0].templates );
} );
} );
} );
}
function api_edit_pre ( title, text, summary ) {
var params = {
action: 'edit',
title: title.getPrefixedDb(),
prependtext: text,
summary: summary,
format: 'json'
};
mw.loader.using( 'mediawiki.api', function () {
api = new mw.Api();
return api.postWithToken( 'csrf', params );
} );
}
function api_edit_app( title, text, summary ) {
var params = {
action: 'edit',
title: title.getPrefixedDb(),
appendtext: text,
summary: summary,
format: 'json'
};
mw.loader.using( 'mediawiki.api', function () {
api = new mw.Api();
return api.postWithToken( 'csrf', params );
} );
}
function api_creator( title ) {
var params = {
action: 'query',
prop: 'revisions',
titles: title.getPrefixedDb(),
rvprop: 'user',
rvlimit: '1',
rvdir: 'newer',
format: 'json',
formatversion: '2'
};
return new Promise( function( resolve, reject ) {
mw.loader.using( 'mediawiki.api', function() {
api = new mw.Api();
api.get( params ).done( function( data ) {
resolve( data.query.pages[0].revisions[0].user );
} );
} );
} );
}
// Module Del/Pr: Proposed deletion
function del_pr() {
mw.loader.using( [
'oojs-ui-core',
'oojs-ui-widgets',
'mediawiki.util'
], function () {
// Exit if already open; else add button
if ( $( '#sparkle-container-del-pr' ).length > 0 ) {
return;
} else {
$( '#content' ).prepend( `
<div id="sparkle-container-del-pr">
<h1 >
Sparkle: Proposed Deletion
<span id="sparkle-close-del-pr"
style="float: right; font-size:50%">
</span>
</h1>
<div id="sparkle-form-del-pr"></div>
<hr />
</div>
` );
}
// Variables
var pagename = mw.config.get( 'wgPageName' );
var title_page = new mw.Title( pagename );
var title_talk = title_page.getTalkPage();
var title_afd = new mw.Title(
'Wikipedia:Articles for deletion/' + pagename
);
var title_mfd = new mw.Title(
'Wikipedia:Miscellany for deletion/' + pagename
);
var username = mw.config.get( 'wgUserName' );
// Close button
var button_close = new OO.ui.ButtonWidget( {
framed: false,
flags: [ 'destructive' ],
icon: 'close'
} );
button_close.on( 'click', function () {
$( '#sparkle-container-del-pr' ).remove();
} );
$( '#sparkle-close-del-pr' ).append( button_close.$element );
// Index & Tabs
var index = new OO.ui.IndexLayout( { expanded: false } );
$( '#sparkle-form-del-pr' ).append( index.$element );
var fieldset_nominate = new OO.ui.FieldsetLayout();
var tab_nominate = new OO.ui.TabPanelLayout( 'nominate', {
label: 'Nominate',
content: [ fieldset_nominate ],
expanded: false
} );
var fieldset_endorse = new OO.ui.FieldsetLayout();
var tab_endorse = new OO.ui.TabPanelLayout( 'endorse', {
label: 'Endorse',
content: [ fieldset_endorse ],
expanded: false
} );
var fieldset_blp = new OO.ui.FieldsetLayout();
var tab_blp = new OO.ui.TabPanelLayout( 'blp', {
label: 'BLP',
content: [ fieldset_blp ],
expanded: false
} );
var fieldset_remove = new OO.ui.FieldsetLayout();
var tab_remove = new OO.ui.TabPanelLayout( 'remove', {
label: 'Remove',
content: [ fieldset_remove ],
expanded: false
} );
index.addTabPanels( [ tab_nominate, tab_blp ] );
// Tab "Nominate"
var textinput_nominate_rationale = new OO.ui.TextInputWidget( {
placeholder: 'Rationale'
} );
var button_nominate = new OO.ui.ButtonWidget( {
label: 'Nominate',
flags: [ 'primary', 'progressive' ]
} );
var field_nominate_rationale = new OO.ui.ActionFieldLayout(
textinput_nominate_rationale,
button_nominate
);
var checkbox_nominate_notify = new OO.ui.CheckboxInputWidget( {
selected: true
} );
var field_nominate_notify = new OO.ui.FieldLayout(
checkbox_nominate_notify,
{
label: 'Notify page creator?',
align: 'inline'
}
);
fieldset_nominate.addItems( [
field_nominate_rationale,
field_nominate_notify
] );
// Tab "Endorse"
var textinput_endorse_rationale = new OO.ui.TextInputWidget( {
placeholder: 'Rationale'
} );
var button_endorse = new OO.ui.ButtonWidget( {
label: 'Endorse',
flags: [ 'primary', 'progressive' ],
disabled: true
} );
var field_endorse_rationale = new OO.ui.ActionFieldLayout(
textinput_endorse_rationale,
button_endorse
);
fieldset_endorse.addItems( [ field_endorse_rationale ] );
// Tab "BLP"
var textinput_blp_rationale = new OO.ui.TextInputWidget( {
placeholder: 'Rationale'
} );
var button_blp = new OO.ui.ButtonWidget( {
label: 'Nominate',
flags: [ 'primary', 'progressive' ]
} );
var field_blp_rationale = new OO.ui.ActionFieldLayout(
textinput_blp_rationale,
button_blp
);
fieldset_blp.addItems( [ field_blp_rationale ] );
// Tab "Remove"
var textinput_remove_rationale = new OO.ui.TextInputWidget( {
placeholder: 'Rationale'
} );
var button_remove = new OO.ui.ButtonWidget( {
label: 'Remove',
flags: [ 'primary', 'progressive' ]
} );
var field_remove_rationale = new OO.ui.ActionFieldLayout(
textinput_remove_rationale,
button_remove
);
fieldset_remove.addItems( [ field_remove_rationale ] );
// Progress bar & success message
var progressbar = new OO.ui.ProgressBarWidget();
var field_progressbar = new OO.ui.FieldLayout(
progressbar,
{
align: 'top',
label: 'Nominating...'
}
);
var fieldset_progressbar = new OO.ui.FieldsetLayout();
fieldset_progressbar.addItems( field_progressbar );
var notice_success = new OO.ui.MessageWidget( {
type: 'success',
icon: 'trash',
label: 'This page has been nominated for proposed deletion.'
+ ' Reloading...'
} );
// Check page for existing deletion templates
var checkbox_speedy = new OO.ui.CheckboxInputWidget( {
selected: false,
disabled: true // Doesn't currently do anything
} );
var field_speedy = new OO.ui.FieldLayout(
checkbox_speedy,
{
label: 'Remove speedy deletion tag(s)?',
align: 'inline'
}
);
var notice_discussion = new OO.ui.MessageWidget( {
type: 'error',
label: `
This page is being discussed for deletion,
so it may not be proposed for deletion.
`
} );
api_templates( title_page )
.then( function( templates ) {
for ( let template of templates ) {
// Speedy: Add checkbox to remove speedy
if ( template.title == 'Template:Db-meta' ) {
fieldset_nominate.addItems( [ field_speedy ] );
}
// Proposed: Add "Endorse" & "Remove", remove other tabs
if (
[
'Template:Proposed deletion/dated',
'Template:Proposed deletion/dated files',
'Template:Prod blp/dated'
].includes( template.title )
) {
index
.addTabPanels( [
tab_endorse,
tab_remove
] )
.removeTabPanels( [
tab_nominate,
tab_blp
] );
}
// Discussion: Disable module
if (
[
'Template:Article for deletion/dated',
'Template:Ffd',
'Template:Mfd'
].includes( template.title )
) {
$( '#' + index.getElementId() ).remove();
$( '#sparkle-form-del-pr' ).append(
notice_discussion.$element
);
}
}
} );
// Core for "Nominate" tab
function nominate() {
// Replace index with progress bar
$( '#' + index.getElementId() ).remove();
$( '#sparkle-form-del-pr' ).append(
fieldset_progressbar.$element
);
// Edits and summaries
var page_edit = '{{subst:Prod|concern=' + textinput_nominate_rationale.value + '|help=off}}\n';
var page_summary = 'Nominate for [[WP:PRD|proposed deletion]] | [[WP:✨|✨]]';
var talk_edit = '{{Old prod|nom=' + username + '|nomdate={{subst:#time:Y-m-d}}|nomreason=' + textinput_nominate_rationale.value + '}}\n';
var talk_summary = 'Add notice of [[WP:PRD|proposed deletion]] nomination | [[WP:✨|✨]]';
var usertalk_edit = '\n\n{{subst:Prodnote|1=' + title_page.getPrefixedText() + '|concern=' + textinput_nominate_rationale.value + '}} ~~~~';
var usertalk_summary = 'Add note of [[WP:PRD|proposed deletion]] nomination of [[' + title_page.getPrefixedText() + ']] | [[WP:✨|✨]]';
// Functions to do edits
function edit_page() {
// TODO: Add functionality for removing speedy tags
return api_edit_pre( title_page, page_edit, page_summary );
}
function edit_talk() {
return api_edit_pre( title_talk, talk_edit, talk_summary );
}
function edit_usertalk() {
if ( checkbox_nominate_notify.selected ) {
return new Promise( function( resolve, reject ) {
api_creator( title_page )
.then( function ( creator ) {
var title_usertalk = new mw.Title(
'User talk:' + creator
);
api_edit_app(
title_usertalk,
usertalk_edit,
usertalk_summary
);
} )
.then( function() {
resolve();
} );
} );
} else {
return null;
}
}
// Do edits
Promise.all( [
edit_page(),
edit_talk(),
edit_usertalk()
] ).then( function() {
$( '#' + fieldset_progressbar.getElementId() ).remove();
$( '#sparkle-form-del-pr' ).append(
notice_success.$element
);
setTimeout( function() {
window.location.reload();
}, 1000 );
} );
}
// Core for "Endorse" tab
function endorse() {
alert('Endorse does not yet work.');
}
// Core for "BLP" tab
function blp_nominate() {
// Replace index with progress bar
$( '#' + index.getElementId() ).remove();
$( '#sparkle-form-del-pr' ).append(
fieldset_progressbar.$element
);
// Edits and summaries
var page_edit = '{{subst:Prod blp|concern='
+ textinput_blp_rationale.value
+ '|help=off}}\n';
var page_summary = 'Nominate for [[WP:BLPPROD|proposed deletion '
+ 'of unsourced biography of living person]] '
+ '| [[WP:✨|✨]]';
var usertalk_edit = '\n\n{{subst:ProdwarningBLP|1='
+ title_page.getPrefixedText()
+ '|concern='
+ textinput_blp_rationale.value
+ '}} ~~~~';
var usertalk_summary = 'Add note of '
+ '[[WP:BLPPROD|proposed deletion of unsourced '
+ 'biography of living person]] nomination of [['
+ title_page.getPrefixedText()
+ ']] | [[WP:✨|✨]]';
// Functions to do edits
function edit_page() {
return api_edit_pre( title_page, page_edit, page_summary );
}
function edit_usertalk() {
return new Promise( function( resolve, reject ) {
api_creator( title_page )
.then( function ( creator ) {
var title_usertalk = new mw.Title(
'User talk:' + creator
);
api_edit_app(
title_usertalk,
usertalk_edit,
usertalk_summary
);
} )
.then( function() {
resolve();
} );
} );
}
// Do edits
Promise.all( [
edit_page(),
edit_usertalk()
] ).then( function() {
$( '#' + fieldset_progressbar.getElementId() ).remove();
$( '#sparkle-form-del-pr' ).append(
notice_success.$element
);
setTimeout( function() {
window.location.reload();
}, 1000 );
} );
}
// Core for "Remove" tab
function remove() {
alert('Remove');
Promise.all( [
api_wikitext( title_page ),
api_wikitext( title_talk )
] ).then( function( texts ) {
var re_article = new RegExp(
'\{\{Proposed deletion\/dated\n' +
' \|concern = (.*?)\n' +
' \|timestamp = (\d*?)\n' +
' \|nom = (.*?)\n' +
'(?:.*?)\n' +
'\}\}'
);
var re_file = new RegExp(
'\{\{Proposed deletion\/dated files\n' +
' \|concern = (.*?)\n' +
' \|timestamp = (\d*?)\n' +
'(?:.*?)\n' +
'\}\}'
);
var re_blp = new RegExp(
'\{\{Prod blp\/dated\n' +
' \|concern = (.*?)\n' +
' \|user = (.*?)\n' +
' \|timestamp = (\d*?)\n' +
'(?:.*?)\n' +
'\}\}'
);
var match_article = texts[0].match( re_article );
var match_file = texts[0].match( re_file );
var match_blp = texts[0].match( re_blp );
} );
}
// Hooks/links
textinput_nominate_rationale.focus();
textinput_nominate_rationale.on( 'enter', function () {
nominate();
} );
button_nominate.on( 'click', function() {
nominate();
} );
textinput_endorse_rationale.on( 'enter', function() {
endorse();
} );
button_endorse.on( 'click', function() {
endorse();
} );
textinput_blp_rationale.on( 'enter', function() {
blp_nominate();
} );
button_blp.on( 'click', function() {
blp_nominate();
} );
textinput_remove_rationale.on( 'enter', function() {
remove();
} );
button_remove.on( 'click', function() {
remove();
} );
} );
}
// Loads modules
function load() {
// Dropdown
$( '#p-cactions' ).after( `
<nav class="mw-portlet vector-menu-dropdown" id="sparkle-actions">
<input type="checkbox" class="vector-menu-checkbox" />
<h3>✨</h3>
<div class="vector-menu-content">
<ul id="sparkle-actions-list"></ul>
</div>
</nav>
` );
// Del/Pr
if (
mw.config.get( 'wgIsProbablyEditable' ) &&
[ 0, 2, 6, 108 ].includes( mw.config.get( 'wgNamespaceNumber' ) )
) {
$( '#sparkle-actions-list' ).append( `
<li>
<a id="sparkle-action-del-pr"
title="Nominate for proposed deletion">
Del/Pr
</a>
</li>
` );
$( '#sparkle-action-del-pr' ).click( function() { del_pr(); } );
}
// Load modules
mw.loader.load( [
'mediawiki.api',
'mediawiki.util',
'oojs-ui-core',
'oojs-ui-widgets'
] );
}
jQuery( load );
// </syntaxhighlight>