User:Hippietrail/personalsidebar.js

Note – after saving, you may have to bypass your browser’s cache to see the changes.

  • Mozilla / Firefox / Safari: hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (Command-R on a Macintosh);
  • Konqueror and Chrome: click Reload or press F5;
  • Opera: clear the cache in Tools → Preferences;
  • Internet Explorer: hold Ctrl while clicking Refresh, or press Ctrl-F5.

//importScript('User:Hippietrail/wfMsgCentre.js');
document.write('<script type="text/javascript" src="/w/index.php?title=User:Hippietrail/wfMsgCentre.js&action=raw&ctype=text/javascript"><\/script>');

var wgPersonalSidebarMsgArray;

// uppercase first char, leave rest as is
function ucfirst(t) {
  return t.charAt(0).toUpperCase() + t.substring(1);
}

// set the href in a list node
// also handles the PAGENAME magic word
// also alters CSS based on the changes
// TODO should be a member function
function set_link(listnode, text) {
  // Magic word subsitution
  // TODO hide these entries when we're not in namespace 0
  if (text.match(/\{\{PAGENAME}}/)) {
    text = text.replace(/\{\{PAGENAME}}/, wgPageName.replace(/_/g, ' '));
  }

  // set absolute or relative link
  listnode.firstChild.href = text.match(/^http:/) ? text : wgArticlePath.replace('$1', text);
}

// set the text in a list node
// also alters CSS based on the changes
// TODO should be a member function
function set_text(listnode, text) {
  listnode.firstChild.innerHTML = text;
}

// emulate wfMsgForContent using ajax (must be a closure!)
// TODO checking for quoted string should happen outside this function
function ajax_wfMsgForContent(listnode, title) {
  if (title.match(/^'.*'$/) || title.match(/^".*"$/)) {
    set_link(listnode, title.substring(1, title.length-1));
  } else {
    wgPersonalSidebarMsgArray[ucfirst(title)] = { forcontent: false, obj: listnode.firstChild, attr: 'href', xform: makehref };
  }
}

// setting the accesskey also changes the tooltip
function psb_ak_cb(arg) {
  if (this.obj.title == '' || this.obj.title == undefined)
    this.obj.title = '';
  else
    this.obj.title += ' ';

  this.obj.title += '[' + tooltipAccessKeyPrefix + arg + ']';

  return arg;
}

// setting the tooltip must take into account the accesskey
function psb_tt_cb(arg) {
  if (this.obj.title == '' || this.obj.title == undefined)
    return arg;
  else
    return arg + ' ' + this.obj.title;
}

// emulate wfMsg using ajax (must be a closure!)
// TODO checking for quoted string should happen outside this function
function ajax_wfMsg(listnode, title) {
  if (title.match(/^'.*'$/) || title.match(/^".*"$/)) {
    set_text(listnode, title.substring(1, title.length-1));
  } else {
    // register label for localisation
    wgPersonalSidebarMsgArray[ucfirst(title)] = { forcontent: true, obj: listnode.firstChild.firstChild, attr: 'nodeValue' };
    wgPersonalSidebarMsgArray['Accesskey-n-' + title] = { forcontent: true, obj: listnode.firstChild, attr: 'accessKey', xform: psb_ak_cb };
    wgPersonalSidebarMsgArray['Tooltip-n-' + title] = { forcontent: true, obj: listnode.firstChild, attr: 'title', xform: psb_tt_cb };
  }
}

// find the navigation portlet or one by another name in its place
function findStdSidebar() {
  var pnav = document.getElementById('p-navigation');

  // if its name has been changed let's look for the 4th portlet
  if (pnav == null) {
    var portlets = document.getElementById('column-one').getElementsByTagName('div');
    var k = 0;
    for (var l = 0; l < portlets.length; l++) {
      if (portlets[i].className.match(/\bportlet\b/)) {
        if (k == 3) {
          pnav = portlets[i];
          break;
        }
        k++;
      }
    }
  }
  return pnav;
}

// use sidebar in User:xxx/MediaWiki/Sidebar
function personalizeSidebar() {
  // page exists. parse it.
  function parse(req) {
    var msgctr = wfMsgCentreFactory.create();
    wgPersonalSidebarMsgArray = new Object();

    // process req.responseText
    var line = new Array();
    line = req.responseText.split('\n');

    var portlet = null;
    var heading = '';
    var ul = null;

    for (var i = 0; i < line.length; i++) {
      if (line[i].indexOf('*') != 0) {
        continue;
      }
      if (line[i].indexOf('**') != 0) {
        heading = line[i].substring(2);

        portlet = document.createElement('div');
        //portlet.style.display = 'none';
        portlet.className = 'portlet';
        portlet.id = 'p-' + heading;

        var h5 = document.createElement('h5');
        var h5a = document.createElement('a');
        h5a.href = 'http://en.wiktionary.org/w/index.php?title=User:Hippietrail/MediaWiki:Sidebar&action=edit';
        h5a.appendChild(document.createTextNode('*'));
        h5.appendChild(document.createTextNode(heading));
        // register title for localisation
        wgPersonalSidebarMsgArray[ucfirst(heading)] = { forcontent: true, obj: h5.firstChild, attr: 'nodeValue' };
        h5.appendChild(h5a);
        portlet.appendChild(h5);

        var pbody = document.createElement('div');
        pbody.className = 'pBody';
        portlet.appendChild(pbody);
        ul = document.createElement('ul');
        pbody.appendChild(ul);

        var pnav = findStdSidebar();

        // replace standard sidebars with our constructed portlet
        // TODO only replaces a single sidebar called p-navigation so far
        pnav.parentNode.replaceChild(portlet, pnav);

      } else {
        if (line[i].indexOf('|') != -1) {
          var link_text = line[i].substring(3).match(/([^|]*)\|(.*)/);

          var newli = document.createElement('li');
          newli.className = 'autowidth';
          newli.appendChild(document.createElement('a'));
          newli.firstChild.appendChild(document.createTextNode(link_text[2]));
          ul.appendChild(newli);

          var list = portlet.getElementsByTagName('ul')[0];

          ajax_wfMsgForContent(list.childNodes[i-1], link_text[1]);
          ajax_wfMsg(list.childNodes[i-1], link_text[2]);
        } else continue;
      }
    }
    msgctr.batch(wgPersonalSidebarMsgArray);
  }

  // page doesn't exist. just use the global sidebar
  function on404() {
    //debugPrint('personal sidebar doesn\'t exist\n');
  };

  // TODO we now load a fresh User:/xyz/MediaWiki:Sidebar every hour
  // TODO but we can't force it to happen when User:/xyz/MediaWiki:Sidebar has been edited
  var date = new Date();
  var beatcache = '&beatcache=' + date.getFullYear() + '/' + (date.getMonth() + 1) + '/' + date.getDate() + '/' + date.getHours();

  ajax(wgScriptPath + '/index.php?title=' + 'User:' + wgUserName + '/MediaWiki:Sidebar' + '&action=raw' + beatcache, parse, on404);
}