User:Quarl/wikipage.js
Note: After saving, you have to bypass your browser's cache to see the changes. Google Chrome, Firefox, Microsoft Edge and Safari: Hold down the ⇧ Shift key and click the Reload toolbar button. For details and instructions about other browsers, see Wikipedia:Bypass your cache.
// [[User:Quarl/wikipage.js]] - "WikiPage" class for page name, etc. functionality
// depends: util.js
// Suppose we are editing [[Template talk:Foo bar 'blah']].
// WikiPage.editingP: true;
// ...
// wikiPage is a pre-initialized global variable using the current page's canonical URL.
// It uses the "Retrieved from" page hyperlink which is robust against redirections, editing, special characters, special pages.
//
// wikiPage.url: "http://en.wikipedia.org/wiki/Template_talk:Foo_bar_%27blah%27"
// wikiPage.qurl: "http://en.wikipedia.org/w/index.php?title=Template_talk:Foo_bar_%27blah%27"
// wikiPage.page: "Template talk:Foo bar 'blah'"
// wikiPage.article: "Foo bar 'blah'"
// wikiPage.namespace: "Template talk"
// wikiPage.namespaceNT: "Template"
// wikiPage.talkP: true
// wikiPage.nsTemplateP: true
// wikiPage.nsMainP: false
// wikiPage.nsUserP: false
// wikiPage.nsCategoryP: false
// wikiPage.nsSpecialP: false
// wikiPage.nsProjectP: false // (namespace "Wikipedia")
// To create new WikiPage object from a URL:
// var wp = new WikiPage("http://en.wikipedia.org/wiki/Article_Name");
// To create a new WikiPage object from a page name:
// var wp = new WikiPage(null, 'Article Name');
// <pre><nowiki>
/*
<div class="printfooter">
Retrieved from "<a href="http://en.wikipedia.org/wiki/Albert_Einstein">http://en.wikipedia.org/wiki/Albert_Einstein</a>"</div>
*/
// the "retrieved from" text contains the canonical article URL (even if we're looking at an edit or history page)
function getCanonPageURL0() {
var pfooter = document.querySelectorAll("div.printfooter a")[0];
return pfooter && pfooter.href;
}
function getUsername0(doc) {
// read username from pt-userpage link.
// <li id="pt-userpage"><a href="/wiki/User:Quarl">Quarl</a></li>
return doc.getElementById('pt-userpage').getElementsByTagName('a')[0].text;
}
var wpNamespaces = {'Media':1, 'Special':1,
'Talk':1,
'User':1, 'User talk':1,
'Wikipedia':1, 'Wikipedia talk':1,
'Image':1, 'Image talk':1,
'MediaWiki':1, 'MediaWiki talk':1,
'Template':1, 'Template talk':1,
'Help':1, 'Help talk':1,
'Category':1, 'Category talk':1,
'Portal':1, 'Portal talk':1,
};
function WikiPage(url, page, doc) {
if (!(this instanceof WikiPage)) return new WikiPage(url, page, doc);
this.doc = doc;
if (url) {
url = "" + url;
if (url.match( '^(?:(?:https?:|)//'+WikiPage.server+')?/wiki/')) {
this.pageQuoted = RegExp.rightContext;
} else if (url.match( '^(?:(?:https?:|)//'+WikiPage.server+')?/w/index\\.php\\?title=([^&]+)')) {
this.pageQuoted = RegExp.$1;
} else {
alert("WikiPage: Couldn't parse page name from url '"+url+"'");
return;
}
if(typeof wpadecode === 'undefined') {
mw.log.error('Uncaught ReferenceError: wpadecode is not defined');
return;
}
this.page = wpadecode(this.pageQuoted);
} else if (page) {
this.page = page.replace(/_/g, ' ');
this.pageQuoted = wpaescape(page);
} else {
alert("WikiPage: must specify url or page"); return;
}
this.url = 'http://'+WikiPage.server+'/wiki/' + this.pageQuoted;
this.qurl = 'http://'+WikiPage.server+'/w/index.php?title=' + this.pageQuoted;
// Get term on the left of ":". Not any string is a namespace though, only certain hardcoded ones!
if (this.page.match(/:/) && wpNamespaces[RegExp.leftContext]) {
this.namespace = RegExp.leftContext;
this.article = RegExp.rightContext;
} else {
this.namespace = ''; // (main)
this.article = this.page;
}
if (this.namespace == 'Talk') {
this.talkP = true;
this.namespaceNT = '';
} else if (this.namespace.match(/ talk$/)) {
this.talkP = true;
this.namespaceNT = RegExp.leftContext;
} else {
this.talkP = false;
this.namespaceNT = this.namespace;
}
if (this.article.match(/\//)) {
this.superarticle = RegExp.leftContext;
this.subarticle = RegExp.rightContext;
} else {
this.superarticle = this.article;
this.subarticle = '';
}
this.nsMainP = (this.namespaceNT == '');
this.nsMediaP = (this.namespaceNT == 'Media');
this.nsSpecialP = (this.namespaceNT == 'Special');
this.nsUserP = (this.namespaceNT == 'User');
this.nsPortalP = (this.namespaceNT == 'Portal');
this.nsImageP = (this.namespaceNT == 'Image');
this.nsMediaWikiP = (this.namespaceNT == 'MediaWiki');
this.nsTemplateP = (this.namespaceNT == 'Template');
this.nsHelpP = (this.namespaceNT == 'Help');
this.nsCategoryP = (this.namespaceNT == 'Category');
this.nsProjectP = (this.namespaceNT == 'Wikipedia');
this.talkPage = function() {
if (this.talkP) { return this; }
else if (this.namespaceNT == '') { return new WikiPage(null, 'Talk:'+this.article); }
else { return new WikiPage(null, this.namespaceNT+' talk:'+this.article); }
}
this.notalkPage = function() {
if (!this.talkP) { return this; }
else if (this.namespaceNT == '') { return new WikiPage(null, this.article); }
else { return new WikiPage(null, this.namespaceNT+':'+this.article); }
}
this.sandboxP = Boolean(this.page.match(/sandbox$/i));
this.setDoc = function(doc) {
var wd = new WikiDocument(doc, this);
if (wd.editingP) {
this.editDoc = wd;
} else {
this.viewDoc = wd;
}
this.wd = wd;
}
if (doc) {
// Note that a WikiPage may have more than one associated WikiDocument,
// e.g. one from viewing and one from editing
this.setDoc(doc);
this.relevantUser = this.wd.relevantUser;
} else {
// this is less powerful than WikiDocument.relevantUser if we don't
// have access to doc.
this.relevantUser = getRelevantUser0(this, doc);
}
}
function WikiDocument(doc, wp) {
this.doc = doc;
this.wp = wp;
this.username = getUsername0(doc);
// Note: can't use "doc.editform" or "doc.forms.editform", because 'doc'
// might actually be an XMLDocument (not HTMLDocument), if this is the
// result of an XMLHTTPRequest.
this.editForm = doc.getElementById('editform');
this.editingP = Boolean(this.editForm);
// obsolete method: document.title.match(/^Editing /)
this.protectedP = Boolean(doc.getElementById("ca-viewsource"));
this.newSectionP = this.editForm && (this.editForm.wpSection.value == "new");
this.movePageP = Boolean(doc.getElementById("movepage"));
this.previewP = Boolean(doc.getElementById("wikiPreview"));
this.historyP = Boolean(doc.getElementById("pagehistory"));
this.permalinkP = Boolean(doc.getElementById("t-ispermalink"));
this.oldid = getOldid0(doc, this.permalinkP);
this.relevantUser = getRelevantUser0(wp, doc);
}
function getUsernameFromLink(link) {
return link && (new WikiPage(link)).relevantUser;
}
function getRelevantUser0(wp, doc) {
if (wp.nsUserP) return wp.superarticle;
if (doc && wp.page == 'Special:Contributions') {
var cdiv = doc.getElementById('contentSub');
if (cdiv.textContent == "For newbies") return null;
return getUsernameFromLink(cdiv.getElementsByTagName('a')[0]);
}
return null;
}
// Get the oldid ("permalink") for the current page.
// Note that we can't get oldid for editing pages, special pages, etc.
function getOldid0(doc, perm) {
var tagid = perm ? 'ca-edit' : 't-permalink';
var tag = doc.getElementById(tagid);
if (!tag) return null;
var href = tag.getElementsByTagName("a")[0].href;
if (!href) return null;
href.match(/&oldid=([0-9]+)/);
return RegExp.$1;
}
function getQueryVars0(){
var res = new Array();
var pairs = location.search.substring(1).split("&");
for(var i=0; i < pairs.length; i++){
var pair = pairs[i].split("=");
res[decodeURIComponent(pair[0])] = decodeURIComponent(pair[1]);
}
return res;
}
function initWikiPage() {
WikiPage.server = window.location.host || 'en.wikipedia.org';
window.wikiPage = new WikiPage(getCanonPageURL0(), null, document);
window.wikiDoc = wikiPage.wd;
WikiPage.queryVars = window.queryVars = getQueryVars0();
// these are all deprecated
if (typeof wikiDoc !== 'undefined') {
WikiPage.username = window.username = wikiDoc.username;
WikiPage.relevantUser = window.relevantUser = wikiDoc.relevantUser;
WikiPage.editingP = window.editingP = wikiDoc.editingP;
WikiPage.newSectionP = window.newSectionP = wikiDoc.newSectionP;
WikiPage.movePageP = window.movepageP = wikiDoc.movePageP;
WikiPage.previewP = window.previewP = wikiDoc.previewP;
WikiPage.historyP = window.historyP = wikiDoc.historyP;
WikiPage.sandboxP = window.sandboxP = wikiDoc.sandboxP;
WikiPage.permalinkP = window.permalinkP = wikiDoc.permalinkP;
WikiPage.oldid = window.pageOldid = wikiDoc.oldid;
}
}
// DEPRECATED:
function getPname() { return wikiPage.page; }
function getPnameNS() { return wikiPage.namespace; }
function getPnameNoNS() { return wikiPage.article; }
function pageIsSpecial() { return wikiPage.nsSpecialP; }
function get_query_vars() { return queryVars; }
addOnloadHook(initWikiPage);
// obsolete method 1:
// function getPname0() {
// var z=document.getElementById("content").childNodes;
// for (var n=0;n<z.length;n++) {
// if (z[n].className=="firstHeading") return z[n].textContent;
// }
// }
// function getPname1() {
// var t = getPname0();
// t = t.replace(/^Editing /,'');
// t = t.replace(/ \(section\)$/,'');
// return t;
// }
// obsolete method 2:
// document.title.substr(0, document.title.lastIndexOf(' - Wikipedia, the free'));
//</nowiki></pre>