MediaWiki:Gadget-morebits.js: Difference between revisions

Content added Content deleted
imported>MusikAnimal
(v2.0 at 19598c4: Clean up, avoid unnecessary jQuery use (#399))
(v2.0 at 83fff83: Ignore file/category embeds when removing links (#239))
Line 1: Line 1:
// <nowiki>
//<nowiki>
/**
/**
* morebits.js
* morebits.js
Line 750: Line 750:
return element.parentNode.getElementsByTagName("label")[0];
return element.parentNode.getElementsByTagName("label")[0];
}
}

return null;
};
};


Line 1,360: Line 1,358:
if( Morebits.wiki.actionCompleted.redirect ) {
if( Morebits.wiki.actionCompleted.redirect ) {
// if it isn't a URL, make it one. TODO: This breaks on the articles 'http://', 'ftp://', and similar ones.
// if it isn't a URL, make it one. TODO: This breaks on the articles 'http://', 'ftp://', and similar ones.
if( !( (/^\w+\:\/\//).test( Morebits.wiki.actionCompleted.redirect ) ) ) {
if( !( (/^\w+:\/\//).test( Morebits.wiki.actionCompleted.redirect ) ) ) {
Morebits.wiki.actionCompleted.redirect = mw.util.getUrl( Morebits.wiki.actionCompleted.redirect );
Morebits.wiki.actionCompleted.redirect = mw.util.getUrl( Morebits.wiki.actionCompleted.redirect );
if( Morebits.wiki.actionCompleted.followRedirect === false ) {
if( Morebits.wiki.actionCompleted.followRedirect === false ) {
Line 1,442: Line 1,440:


return $.ajax( ajaxparams ).done(
return $.ajax( ajaxparams ).done(
function(xml, statusText, jqXHR) {
function(xml, statusText) {
this.statusText = statusText;
this.statusText = statusText;
this.responseXML = xml;
this.responseXML = xml;
Line 1,714: Line 1,712:
*/
*/
var ctx = {
var ctx = {
// backing fields for public properties
// backing fields for public properties
pageName: pageName,
pageName: pageName,
pageExists: false,
pageExists: false,
Line 1,720: Line 1,718:
callbackParameters: null,
callbackParameters: null,
statusElement: new Morebits.status(currentAction),
statusElement: new Morebits.status(currentAction),

// - edit
// - edit
pageText: null,
pageText: null,
editMode: 'all', // save() replaces entire contents of the page by default
editMode: 'all', // save() replaces entire contents of the page by default
Line 1,734: Line 1,733:
watchlistOption: 'nochange',
watchlistOption: 'nochange',
creator: null,
creator: null,

// - revert
// - revert
revertOldID: null,
revertOldID: null,

// - move
// - move
moveDestination: null,
moveDestination: null,
moveTalkPage: false,
moveTalkPage: false,
moveSubpages: false,
moveSubpages: false,
moveSuppressRedirect: false,
moveSuppressRedirect: false,

// - protect
// - protect
protectEdit: null,
protectEdit: null,
protectMove: null,
protectMove: null,
protectCreate: null,
protectCreate: null,
protectCascade: false,
protectCascade: false,

// - stabilize (FlaggedRevs)
// - stabilize (FlaggedRevs)
flaggedRevs: null,
flaggedRevs: null,

// internal status
// internal status
pageLoaded: false,
pageLoaded: false,
editToken: null,
editToken: null,
Line 1,759: Line 1,763:
conflictRetries: 0,
conflictRetries: 0,
retries: 0,
retries: 0,

// callbacks
// callbacks
onLoadSuccess: null,
onLoadSuccess: null,
onLoadFailure: null,
onLoadFailure: null,
Line 1,773: Line 1,778:
onStabilizeSuccess: null,
onStabilizeSuccess: null,
onStabilizeFailure: null,
onStabilizeFailure: null,

// internal objects
// internal objects
loadQuery: null,
loadQuery: null,
loadApi: null,
loadApi: null,
Line 2,526: Line 2,532:


var purgeApi = new Morebits.wiki.api("Edit conflict detected, purging server cache", purgeQuery, null, ctx.statusElement);
var purgeApi = new Morebits.wiki.api("Edit conflict detected, purging server cache", purgeQuery, null, ctx.statusElement);
var result = purgeApi.post( { async: false } ); // just wait for it, result is for debugging
purgeApi.post( { async: false } ); // just wait for it, result is for debugging


--Morebits.wiki.numberOfActionsLeft; // allow for normal completion if retry succeeds
--Morebits.wiki.numberOfActionsLeft; // allow for normal completion if retry succeeds
Line 3,019: Line 3,025:
var first_char = link_target.substr( 0, 1 );
var first_char = link_target.substr( 0, 1 );
var link_re_string = "[" + first_char.toUpperCase() + first_char.toLowerCase() + ']' + RegExp.escape( link_target.substr( 1 ), true );
var link_re_string = "[" + first_char.toUpperCase() + first_char.toLowerCase() + ']' + RegExp.escape( link_target.substr( 1 ), true );

var link_simple_re = new RegExp( "\\[\\[:?(" + link_re_string + ")\\]\\]", 'g' );
// Files and Categories become links with a leading colon.
var link_named_re = new RegExp( "\\[\\[:?" + link_re_string + "\\|(.+?)\\]\\]", 'g' );
// e.g. [[:File:Test.png]]
var special_ns_re = /^(?:[Ff]ile|[Ii]mage|[Cc]ategory):/;
var colon = special_ns_re.test( link_target ) ? ':' : '';

var link_simple_re = new RegExp( "\\[\\[" + colon + "(" + link_re_string + ")\\]\\]", 'g' );
var link_named_re = new RegExp( "\\[\\[" + colon + link_re_string + "\\|(.+?)\\]\\]", 'g' );
this.text = this.text.replace( link_simple_re, "$1" ).replace( link_named_re, "$1" );
this.text = this.text.replace( link_simple_re, "$1" ).replace( link_named_re, "$1" );
},
},
Line 3,306: Line 3,318:
// hack to force the page not to reload when an error is output - see also Morebits.status() above
// hack to force the page not to reload when an error is output - see also Morebits.status() above
Morebits.wiki.numberOfActionsLeft = 1000;
Morebits.wiki.numberOfActionsLeft = 1000;

// call error callback
// call error callback
if (Morebits.status.errorEvent) {
if (Morebits.status.errorEvent) {
Morebits.status.errorEvent();
Morebits.status.errorEvent();
}
}

// also log error messages in the browser console
// also log error messages in the browser console
console.error(this.textRaw + ": " + status); // eslint-disable-line no-console
if (console && console.error) {
console.error(this.textRaw + ": " + status);
}
}
}
}
}
Line 3,402: Line 3,414:


function clickHandler(event) {
function clickHandler(event) {
var cb = this;
var thisCb = this;
if (event.shiftKey && lastCheckbox!==null)
if (event.shiftKey && lastCheckbox !== null) {
{
var cbs = $(jQuerySelector, jQueryContext); //can't cache them, obviously, if we want to support resorting
var cbs = $(jQuerySelector, jQueryContext); //can't cache them, obviously, if we want to support resorting
var index=-1, lastIndex=-1;
var index = -1, lastIndex = -1, i;
for (var i=0; i<cbs.length; i++)
for (i = 0; i < cbs.length; i++) {
if (cbs[i] === thisCb) {
{
index = i;
if (cbs[i]==cb) { index=i; if (lastIndex>-1) break; }
if (cbs[i]==lastCheckbox) { lastIndex=i; if (index>-1) break; }
if (lastIndex > -1)
break;
}
if (cbs[i] === lastCheckbox) {
lastIndex = i;
if (index > -1)
break;
}
}
}

if (index>-1 && lastIndex>-1)
if (index > -1 && lastIndex > -1) {
{
//inspired by wikibits
//inspired by wikibits
var endState = cb.checked;
var endState = thisCb.checked;
var start, finish;
var start, finish;
if (index<lastIndex)
if (index < lastIndex) {
start = index + 1;
{
start = index+1;
finish = lastIndex;
finish = lastIndex;
}
} else {
else
{
start = lastIndex;
start = lastIndex;
finish = index-1;
finish = index - 1;
}

for (i = start; i <= finish; i++) {
cbs[i].checked = endState;
}
}
for (var i=start; i<=finish; i++) cbs[i].checked = endState;
}
}
}
}
lastCheckbox = cb;
lastCheckbox = thisCb;
return true;
return true;
}
}
Line 3,647: Line 3,665:
// to that of the old SimpleWindow
// to that of the old SimpleWindow
height: height + 20,
height: height + 20,
close: function(event, ui) {
close: function(event) {
// dialogs and their content can be destroyed once closed
// dialogs and their content can be destroyed once closed
$(event.target).dialog("destroy").remove();
$(event.target).dialog("destroy").remove();
},
},
resizeStart: function(event, ui) {
resizeStart: function() {
this.scrollbox = $(this).find(".morebits-scrollbox")[0];
this.scrollbox = $(this).find(".morebits-scrollbox")[0];
if (this.scrollbox) {
if (this.scrollbox) {
Line 3,657: Line 3,675:
}
}
},
},
resizeEnd: function(event, ui) {
resizeEnd: function() {
this.scrollbox = null;
this.scrollbox = null;
},
},
resize: function(event, ui) {
resize: function() {
this.style.maxHeight = "";
this.style.maxHeight = "";
if (this.scrollbox) {
if (this.scrollbox) {
Line 3,698: Line 3,716:


// Focuses the dialog. This might work, or on the contrary, it might not.
// Focuses the dialog. This might work, or on the contrary, it might not.
focus: function(event) {
focus: function() {
$(this.content).dialog("moveToTop");
$(this.content).dialog("moveToTop");


Line 3,726: Line 3,744:
if (window.setupTooltips && window.pg && window.pg.re && window.pg.re.diff) { // tie in with NAVPOP
if (window.setupTooltips && window.pg && window.pg.re && window.pg.re.diff) { // tie in with NAVPOP
dialog.parent()[0].ranSetupTooltipsAlready = false;
dialog.parent()[0].ranSetupTooltipsAlready = false;
setupTooltips(dialog.parent()[0]);
window.setupTooltips(dialog.parent()[0]);
}
}
this.setHeight( this.height ); // init height algorithm
this.setHeight( this.height ); // init height algorithm
Line 3,865: Line 3,883:


if ( typeof arguments === "undefined" ) { // typeof is here for a reason...
if ( typeof arguments === "undefined" ) { // typeof is here for a reason...
/* global Morebits */
window.SimpleWindow = Morebits.simpleWindow;
window.SimpleWindow = Morebits.simpleWindow;
window.QuickForm = Morebits.quickForm;
window.QuickForm = Morebits.quickForm;
Line 3,872: Line 3,891:
}
}


//</nowiki>

// </nowiki>