Note: After saving, changes may not occur immediately. Click here to learn how to bypass your browser's cache.
- Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Cmd-R on a Mac)
- Google Chrome: Press Ctrl-Shift-R (Cmd-Shift-R on a Mac)
- Internet Explorer: Hold Ctrl while clicking Refresh, or press Ctrl-F5
- Opera: Clear the cache in Tools → Preferences
For details and instructions about other browsers, see Wikipedia:Bypass your cache.
Code that you insert on this page could contain malicious content capable of compromising your account. If you are unsure whether code you are adding to this page is safe, you can ask at the central discussion page, Scriptorium. The code will be executed when previewing this page under some skins, including Monobook. You can in the interim if you wish to refresh the content sooner under another skin. |
Documentation for this script can be added at User:Inductiveload/Running header. |
/*
* Does a lookup two previous Page:* from the current, extract the rh from
* its content, insert it in the header after trying to increase the rh page
* number. See the FIXME comment(s) for caveats.
*
* Originally at User:Phe/Running header.js
*
* To use this script, add the following to your .js:
* importScript('User:Inductiveload/Running header.js');
*/
(function($, mw) {
"use strict";
// Roman numeral functions
// From http://blog.stevenlevithan.com/archives/javascript-roman-numeral-converter
function int_to_roman(num) {
if (Number(num) === 0) {
return false;
}
var digits = String(Number(num)).split(""),
key = ["", "C", "CC", "CCC", "CD", "D", "DC", "DCC", "DCCC", "CM",
"", "X", "XX", "XXX", "XL", "L", "LX", "LXX", "LXXX", "XC",
"", "I", "II", "III", "IV", "V", "VI", "VII", "VIII", "IX"
],
roman = "",
i = 3;
while (i--) {
roman = (key[+digits.pop() + (i * 10)] || "") + roman;
}
return Array(+digits.join("") + 1).join("M") + roman;
}
function roman_to_int(in_str) {
var str = in_str.toUpperCase(),
validator =
/^M*(?:D?C{0,3}|C[MD])(?:L?X{0,3}|X[CL])(?:V?I{0,3}|I[XV])$/,
token = /[MDLV]|C[MD]?|X[CL]?|I[XV]?/g,
key = {
M: 1000,
CM: 900,
D: 500,
CD: 400,
C: 100,
XC: 90,
L: 50,
XL: 40,
X: 10,
IX: 9,
V: 5,
IV: 4,
I: 1
},
num = 0,
m;
if (!(str && validator.test(str)))
return false;
while ((m = token.exec(str)))
num += key[m[0]];
return num;
}
var RunningHeaderAutoComplete = function() {
this.offsets = [-2, -4, 2, 4, -1, 1]; //offsets to try, in order
this.offset = 0;
// swap the header around if the offset is odd
this.recto_verso_swap_sides = true;
this.flash_textbox = true;
this.header = document.getElementsByName('wpHeaderTextbox')[0];
};
RunningHeaderAutoComplete.prototype.increment_arabic = function(rh, inc) {
try {
// now attempt to increment the number
var r = new RegExp(
"^(.*[\\|][\\[\\( ]*)(\\d+)([\\]\\)\\. ]*[\\|}].*)$");
var regex_res = r.exec(rh);
var page = Number(r.exec(rh)[2]) + inc;
rh = regex_res[1] + String(page) + regex_res[3];
this.add_rh(rh);
return true;
} catch (err) {
return false;
}
};
RunningHeaderAutoComplete.prototype.increment_roman = function(rh, inc) {
try {
// now attempt to increment a roman numeral
var r = new RegExp(
"^(.*[\\|] *)([ivxlcm]+|[IVXLCM]+)(\\.? *[\\|}].*)$");
var regex_res = r.exec(rh);
var numeral = regex_res[2];
var lower_case = false;
if (numeral.charCodeAt(0) > 96 && numeral.charCodeAt(0) < 123) {
lower_case = true;
}
var number = roman_to_int(numeral) + inc;
numeral = int_to_roman(number);
if (lower_case) {
numeral = numeral.toLowerCase();
}
//insert the numeral back into the RH
rh = regex_res[1] + numeral + regex_res[3];
this.add_rh(rh);
return true;
} catch (err) {
return false;
}
};
RunningHeaderAutoComplete.prototype.swap_rh = function(rh) {
rh = rh.replace(/\{\{ *([Rr]h|[Rr]unning header|[[Rr]unningHeader) *\|(.*?)\|(.*?)(?:\|(.*?))?\}\}/,
"{{running header|$4|$3|$2}}");
return rh;
}
RunningHeaderAutoComplete.prototype.add_rh = function(rh) {
//remove existing RH
this.header.value = this.header.value.replace(
/{{([Rr]h|[Rr]unning ?[Hh]eader) *\|.*}}\n?/, '');
// swap sides if the offset is odd
if (this.recto_verso_swap_sides && (this.offsets[this.offset] % 2) !== 0) {
rh = this.swap_rh(rh);
} else {
// normalise the template name
rh = rh.replace(/\{\{ *([Rr]h|[Rr]unning header|[[Rr]unningHeader) */, "{{running header");
}
var r = new RegExp(/^\s*$/);
if (r.test(this.header.value)) {
this.header.value = rh;
} else {
this.header.value = rh + '\n' + this.header.value;
}
// flash the textbox
if (this.flash_textbox) {
this.header.animate({ backgroundColor: "lightgreen"}, 500);
}
};
RunningHeaderAutoComplete.prototype.fill_rh = function(data) {
var success = false;
if (this.header && !data.query.pages[0].missing) {
var content = data.query.pages[0].revisions[0].slots.main.content;
var r = new RegExp("{" +
"{ *([Rr]h|[Rr]unning header|[[Rr]unningHeader) *\\|[^\n<]*}}");
var match = r.exec(content);
if (match) {
// FIXME: needs to be tweaked, actually works only if the first
// rh parameters consisting of only digits or roman numerals is the one to increment
var rh = match[0];
var pg_offset = this.offsets[this.offset];
//try to increment the number
success = this.increment_arabic(rh, -pg_offset);
if (!success) { //we failed to get a number, see if there is a roman numeral
success = this.increment_roman(rh, -pg_offset);
}
if (!success) {
//we didn't find a number to increment
//set equal to the previous page's header, the user needs to edit by hand
this.add_rh(rh);
}
if ($("prp_header").css('display') == 'none') {
pr_toggle_visibility();
}
}
}
return success;
};
RunningHeaderAutoComplete.prototype.next_offset = function() {
if (this.offset < this.offsets.length -1) {
this.offset++;
return true;
}
return false;
}
RunningHeaderAutoComplete.prototype.try_offset = function() {
var rhac = this;
var r = new RegExp("(\\d+)$");
var page = Number(r.exec(mw.config.get("wgPageName"))[1]) + this.offsets[
this.offset];
var pagename = mw.config.get("wgPageName").replace(/\d+$/g, page);
var offset = this.offsets[this.offset];
// console.log("Trying offset: ", offset);
mw.loader.using(['mediawiki.api'], function() {
var api = new mw.Api();
api.get({
'action': 'query',
'prop': 'revisions',
'rvprop': 'content',
'rvslots': 'main',
'titles': pagename,
'format': 'json',
'formatversion': 2,
})
.done(function(jsondata) {
var success = rhac.fill_rh(jsondata);
if (!success && rhac.next_offset()) {
rhac.try_offset();
}
})
.fail(function() {
if (rhac.next_offset()) {
rhac.try_offset();
}
});
});
};
RunningHeaderAutoComplete.prototype.set_running_header = function() {
if (!this.header) {
return;
}
this.try_offset();
};
function install_css(css) {
$('head').append('<style type="text/css">' + css + '</style>');
}
function add_portlet(callback) {
var portlet = mw.util.addPortletLink(
'p-tb',
'#',
"Running header",
't-running-header',
'Add a running header based on the running headers on surrounding pages',
);
$(portlet)
.click(function(e) {
e.preventDefault();
callback();
});
}
function handle_alt_click(elem, callback) {
$(elem).click(function(event) {
if (event.altKey) {
callback();
}
});
}
if (["Page"].indexOf(mw.config.get("wgCanonicalNamespace")) !== -1) {
var RunningHeaderAutoCompleteInstance = new RunningHeaderAutoComplete();
var go_fn = function() {
RunningHeaderAutoCompleteInstance.set_running_header();
};
add_portlet(go_fn);
handle_alt_click(RunningHeaderAutoCompleteInstance.header, go_fn);
}
}(jQuery, mediaWiki));