367 lines
11 KiB
JavaScript
367 lines
11 KiB
JavaScript
//<nowiki>
|
|
// Script should be located at [[MediaWiki:Gadget-afchelper.js/core.js]]
|
|
( function ( AFCH, $, mw ) {
|
|
AFCH = $.extend( AFCH, {
|
|
|
|
/**
|
|
* Prepares the AFCH gadget by setting constants and checking environment
|
|
* @return {bool} Whether or not all setup functions executed successfully
|
|
*/
|
|
beforeLoad: function () {
|
|
// Check requirements
|
|
if ( 'ajax' in $.support && !$.support.ajax ) {
|
|
AFCH.error = 'AFCH requires AJAX';
|
|
return false;
|
|
}
|
|
|
|
if ( AFCH.consts.baseurl.indexOf( 'MediaWiki:' + 'Gadget-afchelper.js' ) === -1 ) {
|
|
AFCH.consts.beta = true;
|
|
}
|
|
|
|
return true;
|
|
},
|
|
|
|
/**
|
|
* Loads the subscript
|
|
* @param {string} type Which type of script to load:
|
|
* 'redirects' or 'ffu' or 'submissions'
|
|
* @return {bool} Whether or not a subscript was loaded
|
|
*/
|
|
load: function ( type ) {
|
|
// Run setup function
|
|
AFCH.beforeLoad();
|
|
|
|
if ( AFCH.consts.beta ) {
|
|
// Load css
|
|
mw.loader.load( AFCH.consts.scriptpath + '?action=raw&ctype=text/css&title=MediaWiki:Gadget-afchelper.css', 'text/css' );
|
|
// Load dependencies
|
|
mw.loader.load( [ 'mediawiki.feedback', 'mediawiki.api', 'jquery.chosen' ] );
|
|
}
|
|
|
|
// Set up all the other good things
|
|
AFCH.afterLoad();
|
|
|
|
// And finally load the subscript
|
|
$.getScript( AFCH.consts.baseurl + '/' + type + '.js' );
|
|
},
|
|
|
|
/**
|
|
* Loads a bunch of necessary thingies, like prefs and the api and constants and unicorns!
|
|
*/
|
|
afterLoad: function () {
|
|
// FIXME: Add real pref code
|
|
AFCH.prefs = {};
|
|
AFCH.api = new mw.Api();
|
|
|
|
// Add more constants
|
|
$.extend( AFCH.consts, {
|
|
// Edit token used in api requests
|
|
editToken: mw.user.tokens.get('editToken'),
|
|
// Full page name, "Wikipedia talk:Articles for creation/sandbox"
|
|
pagename: mw.config.get( 'wgPageName' ).replace( '_', ' ' ),
|
|
// Link to the current page, "/wiki/Wikipedia talk:Articles for creation/sandbox"
|
|
pagelink: mw.util.getUrl(),
|
|
// Used when status is disabled
|
|
nullstatus: { update: function () { return; } }
|
|
} );
|
|
},
|
|
|
|
/**
|
|
* Appends a feedback link to the given element
|
|
* @param {object} $element The jQuery element to which the link should be appended
|
|
* @param {string} type (optional) The part of AFCH that feedback is being given for, e.g. "files for upload"
|
|
*/
|
|
initFeedback: function ( $element, type ) {
|
|
var feedback = new mw.Feedback( {
|
|
title: new mw.Title( 'Wikipedia talk:Articles for creation/Helper script/Feedback' ),
|
|
bugsLink: 'https://github.com/WPAFC/afch/issues/new',
|
|
bugsListLink: 'https://github.com/WPAFC/afch/issues?labels=REWRITE&state=open'
|
|
} );
|
|
$( '<span>' )
|
|
.text( 'Give feedback!' )
|
|
.addClass( 'afch-feedbackLink' )
|
|
.click( function () {
|
|
feedback.launch( {
|
|
subject: type ? 'Feedback about ' + type : 'AFCH feedback',
|
|
contents: 'Replace this with your error report or feedback, positive or negative. Please be as detailed as possible!'
|
|
} );
|
|
} )
|
|
.appendTo( $element );
|
|
},
|
|
|
|
|
|
/**
|
|
* Represents a page, mainly a wrapper for various actions
|
|
*/
|
|
Page: function ( name ) {
|
|
var pg = this;
|
|
|
|
this.Title = new mw.Title( name );
|
|
this.additionalData = {}
|
|
|
|
this.getText = function ( usecache ) {
|
|
if ( usecache && this.pageText ) {
|
|
return this.pageText;
|
|
}
|
|
$.when( AFCH.action.getPageText( this.Title.getPrefixedText(), { hide: true, moreProps: 'timestamp' } ).done(
|
|
function ( pagetext, data ) {
|
|
pg.pageText = pagetext;
|
|
// Teehee, let's use this opportunity to get some data for later
|
|
pg.additionalData.lastModified = new Date( data.timestamp );
|
|
} );
|
|
|
|
return this.pageText;
|
|
};
|
|
|
|
this.getLastModifiedDate = function () {
|
|
// FIXME: I guess the nice thing to do would be to make an API call if necessary.
|
|
// But that seems like a huge pain and would require some more functionality.
|
|
// For now we just get the text first. Stupid, I know.
|
|
this.getText();
|
|
return this.additionalData.lastModified;
|
|
};
|
|
},
|
|
|
|
/**
|
|
* Perform a specific action
|
|
* FIXME: callback functions? Or else return $.Promise()?
|
|
*/
|
|
action: {
|
|
/**
|
|
* Gets the full wikicode content of a page
|
|
* @param {string} pagename The page to get the contents of, namespace included
|
|
* @param {object} options Object with properties:
|
|
* hide: {bool} set to true to hide the API request in the status log
|
|
* moreProps: {string} additional properties to request
|
|
* @return {string} Page text or false if error
|
|
*/
|
|
getPageText: function ( pagename, options ) {
|
|
var status, request, rvprop = 'content',
|
|
deferred = $.Deferred();
|
|
|
|
if ( !options.hide ) {
|
|
status = new AFCH.status.Element( 'Getting $1...',
|
|
{ '$1': $( '<a>' )
|
|
.attr( 'href', mw.util.getUrl( pagename ) )
|
|
.text( pagename )
|
|
} );
|
|
} else {
|
|
status = AFCH.consts.nullstatus;
|
|
}
|
|
|
|
if ( options.moreProps ) {
|
|
rvprop += '|' + options.moreProps;
|
|
}
|
|
|
|
request = {
|
|
action: 'query',
|
|
prop: 'revisions',
|
|
rvprop: rvprop,
|
|
format: 'json',
|
|
indexpageids: true,
|
|
titles: pagename
|
|
};
|
|
|
|
$.when( AFCH.api.post( request ) )
|
|
.done( function ( data ) {
|
|
var rev, id = data.query.pageids[0];
|
|
if ( id && data.query.pages ) {
|
|
rev = data.query.pages[id].revisions[0];
|
|
deferred.resolve( rev['*'], rev );
|
|
status.update( 'Got $1' );
|
|
} else {
|
|
deferred.reject( data );
|
|
// FIXME: get detailed error info from API result
|
|
status.update( 'Error getting $1: ' + JSON.stringify( data ) );
|
|
}
|
|
} )
|
|
.fail( function ( err ) {
|
|
deferred.reject( err );
|
|
status.update( 'Error getting $1: ' + JSON.stringify( err ) );
|
|
} );
|
|
|
|
return deferred;
|
|
},
|
|
|
|
/**
|
|
* Modifies a page's content
|
|
* @param {string} pagename The page to be modified, namespace included
|
|
* @param {object} options Object with properties:
|
|
* contents: {string} the text to add to/replace the page,
|
|
* summary: {string} edit summary, will have the edit summary ad at the end,
|
|
* createonly: {bool} set to true to only edit the page if it doesn't exist,
|
|
* mode: {string} 'appendtext' or 'prependtext'; default: (replace everything)
|
|
* patrol: {bool} by default true; set to false to not patrol the page
|
|
* hide: {bool} Set to true to supress logging in statusWindow
|
|
* @return {jQuery.Deferred} Page was saved successfully
|
|
*/
|
|
editPage: function ( pagename, options ) {
|
|
var status, request, deferred = $.Deferred();
|
|
|
|
if ( !options ) {
|
|
options = {};
|
|
}
|
|
|
|
if ( !options.hide ) {
|
|
status = new AFCH.status.Element( 'Editing $1...',
|
|
{ '$1': $( '<a>' )
|
|
.attr( 'href', mw.util.getUrl( pagename ) ),
|
|
.text( pagename )
|
|
} );
|
|
} else {
|
|
status = AFCH.consts.nullstatus;
|
|
}
|
|
|
|
request = {
|
|
action: 'edit',
|
|
text: options.contents,
|
|
title: pagename,
|
|
summary: options.summary + AFCH.prefs.summaryAd
|
|
}
|
|
|
|
if ( options.mode ) {
|
|
request[mode] = true;
|
|
}
|
|
|
|
AFCH.api.post( request )
|
|
.done( function ( data ) {
|
|
if ( data && data.edit && data.edit.result && data.edit.result == 'Success' ) {
|
|
deferred.resolve( data );
|
|
status.update( 'Saved $1' );
|
|
} else {
|
|
deferred.reject( data );
|
|
// FIXME: get detailed error info from API result??
|
|
status.update( 'Error saving $1: ' + JSON.stringify( data ) );
|
|
}
|
|
} )
|
|
.fail( function ( err ) {
|
|
deferred.reject( err );
|
|
status.update( 'Error saving $1: ' + JSON.stringify( err ) );
|
|
} );
|
|
|
|
return deferred;
|
|
},
|
|
|
|
/**
|
|
* Deletes a page
|
|
* @param {string} pagename Page to delete
|
|
* @param {string} reason Reason for deletion; shown in deletion log
|
|
* @return {bool} Page deleted successfully
|
|
*/
|
|
deletePage: function ( pagename, reason ) {
|
|
// FIXME: implement
|
|
return true;
|
|
}
|
|
},
|
|
|
|
/**
|
|
* Series of functions for logging statuses and whatnot
|
|
*/
|
|
status: {
|
|
|
|
/**
|
|
* Represents the status container, created ub init()
|
|
*/
|
|
container: false,
|
|
|
|
/**
|
|
* Creates the status container
|
|
* @param {selector} location String/jQuery selector for where the
|
|
* status container should be prepended
|
|
*/
|
|
init: function ( location ) {
|
|
AFCH.status.container = $( '<div>' )
|
|
.attr( 'id', 'afchStatus' )
|
|
.addClass( 'afchStatus' )
|
|
.prependTo( location ? location : '#mw-content-text' );
|
|
},
|
|
|
|
/**
|
|
* Represents an element in the status container
|
|
* @param {string} initialText Initial text of the element
|
|
* @param {object} substitutions key-value pairs of strings that should be replaced by something
|
|
* else. For example, { '$2': mw.user.getUser() }. If not redefined, $1
|
|
* will be equal to the current page name.
|
|
*/
|
|
Element: function ( initialText, substitutions ) {
|
|
/**
|
|
* Replace the status element with new html content
|
|
* @param {string} html Content of the element
|
|
* Can use $1 to represent the page name
|
|
*/
|
|
this.update = function ( html ) {
|
|
// First run the substutions
|
|
$.each( this.substitutions, function ( key, value ) {
|
|
html = html.replace( key, value );
|
|
} );
|
|
// Then update the element
|
|
this.element.html( html );
|
|
};
|
|
|
|
/**
|
|
* Remove the element from the status container
|
|
*/
|
|
this.remove = function () {
|
|
this.update( '' );
|
|
};
|
|
|
|
// Sanity check, there better be a status container
|
|
if ( !AFCH.status.container ) {
|
|
AFCH.status.init();
|
|
}
|
|
|
|
if ( !substitutions ) {
|
|
substitutions = { '$1': AFCH.consts.pagelink };
|
|
} else {
|
|
substitutions = $.extend( {}, { '$1': AFCH.consts.pagelink }, substitutions );
|
|
}
|
|
|
|
this.substitutions = substitutions;
|
|
|
|
this.element = $( '<li>' )
|
|
.appendTo( AFCH.status.container );
|
|
|
|
this.update( initialText );
|
|
}
|
|
},
|
|
|
|
/**
|
|
* A simple framework for getting/setting interface messages.
|
|
* Not every message necessarily needs to go through here. But
|
|
* it's nice to separate long messages from the code itself.
|
|
* @type {Object}
|
|
*/
|
|
msg: {
|
|
/**
|
|
* AFCH messages loaded by default for all subscripts.
|
|
* @type {Object}
|
|
*/
|
|
store: {},
|
|
|
|
/**
|
|
* Retrieve the text of a message, or a placeholder if the
|
|
* message is not set
|
|
* @param {string} key Message key
|
|
* @return {string} Message value
|
|
*/
|
|
get: function ( key ) {
|
|
return AFCH.msg.store[key] || '<' + key + '>';
|
|
},
|
|
|
|
/**
|
|
* Set a new message or messages
|
|
* @param {string|object} key
|
|
* @param {string} value if key is a string, value
|
|
*/
|
|
set: function ( key, value ) {
|
|
if ( typeof key === 'object' ) {
|
|
$.extend( AFCH.msg.store, key );
|
|
} else {
|
|
AFCH.msg.store[key] = value;
|
|
}
|
|
}
|
|
}
|
|
} );
|
|
}( AFCH, jQuery, mediaWiki ) );
|
|
//</nowiki>
|