User:Quarl/wikipage.js

// 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');

//

/*

  • /

// 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.

//

  • Quarl
  • 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

    // 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'));

    //