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.
//{{PAGENAME}}


//<pre><nowiki>
document.write('<link rel="stylesheet" type="text/css" href="'  
             + 'http://en.wikipedia.org/w/index.php?title=User:Zocky/CategoryBrowser.css'
             + '&action=raw&ctype=text/css&dontcountme=s">');

var categoryListViewTop=1;

function categoryListClick(e)
{
  var tt=e.target.tagName;
  
  if (e.button==0 && tt=='A')
  { 
    var aaa=$e('categoryArticleView');
    aaa.src=e.target.href+'?action=render';
    e.preventDefault();
  }
}


function categoryTreeClick(e)
{
  var tt=e.target.tagName;
   if (e.button==0 && tt=='IMG')
  {
    var lll=e.target; while (lll.tagName!='A') {lll=lll.nextSibling};
    var t=lll.innerHTML;
    var u=lll.href;

    var ccc=$e('Category:'+t);
    var sss=$e('Subcategories:'+t);

    if (ccc.getAttribute('state')=='+')
    {
       ccc.setAttribute('state','-');
       sss || loadCategoryContent(lll.href,lll.innerHTML);
    }
    else if (ccc.getAttribute('state')=='-')
    {
       ccc.setAttribute('state','+');
    } 
  }
  else if (e.button==1 && tt=='A')
  { 
    var aaa=$e('Category articles:'+e.target.innerHTML)
    aaa || loadCategoryContent(e.target.href,e.target.innerHTML);
    $e('Category articles:'+e.target.innerHTML).style.zIndex=categoryListViewTop++;
    e.preventDefault();
  }
}


//Handle clicks on categories
document.addEventListener('click',categoryClick,true);
function categoryClick(e)
{
  var t=e.target;
  if (!e.shiftKey && !e.ctrlKey && t.tagName=='A')
  {
    if (t.href.match(/\/wiki\/Category:/))
    {
      var realurl = t.href;
      var title = t.innerHTML;
      $e('categoryTreeView') || showCategoryBrowser();
      $e('Category:'+title) || insertRootCategory(realurl,title);
      $e('Subcategories:'+title) || loadCategoryContent(realurl,title);
//      selectCategory(title);
      e.preventDefault();
    }
  }
}

function insertRootCategory(u,t)
{
  $a($e('categoryTreeView'),categoryTreeItem(u,t));
}

function categoryTreeItem(u,t)
{
  var l=$c('DD');
  l.id='Category:' + t;
  l.setAttribute('state','+');
  l.innerHTML = '<img src="http://en.wikipedia.org/skins-1.5/common/images/Arr_r.png" state="+">'
              + '<img src="http://en.wikipedia.org/skins-1.5/common/images/Arr_d.png" state="-">'
              + '<img src="http://en.wikipedia.org/skins-1.5/common/images/Arr_.png" state="0">'
              + ' <A class="categoryTreeItemLink" href="' + u + '">' + t + '</a>';
  return l;
}

function categoryListItem(u,t)
{
  var l=$c('LI');
  l.id='Category:' + t;
  l.setAttribute('state','+');
  l.innerHTML = ' <A class="categoryListItemLink" href="' + u + '">' + t + '</a>';
  return l;
}

function loadCategoryContent(u,t)
{
  var d=$c('DL'); 
  d.id='Subcategories:'+t;
  d.innerHTML='<blink><small><i>loading...</i></small></blink>';
  $a($e('Category:'+t),d);

  var d=$c('DIV'); 
  d.id='Category articles:'+t; d.setAttribute('class','categoryArticleLinks');
  d.innerHTML='<blink><small><i>loading...</i></small></blink>';
  d.style.zIndex=0;
  $a($e('categoryListView'),d);

  var cbSuccess=function(x,c)
  {
    insertSubcategories(t,c);
    insertArticles(t,c);
    return true;
  }
  var cbFailure=function(x,c)
  {
    alert(x.statusText);
    return true;
  }

  loadText(u,cbSuccess,cbFailure);
}

function insertSubcategories(t,c)
{
  var ccc=$e('Category:'+t);
  var ddd=$e('Subcategories:'+t);
  $r(ccc,ddd);
  var d=$c('DL'); d.id='Subcategories:'+t;

  var h=$ee(c,'H2');

  if (h.length>1 && h[h.length-2].innerHTML=='Subcategories') 
  {
    var lll=$c('div');
    var pp;

    var hh=h[h.length-2].nextSibling;
    while (hh.tagName!='H2')
    {
      pp=hh.nextSibling;
      $a(lll,hh);
      hh=pp;
    };
    var hhh=$ee(lll,'A');
    for (var i=0; i<hhh.length; i++) 
    {
      $a(d,categoryTreeItem(hhh[i].href,hhh[i].innerHTML));
    }
  }
  else
  {
    ccc.setAttribute('state','0');
  }
  $a(ccc,d);
}


function insertArticles(t,c)
{
  var ddd=$e('Category articles:'+t);
  ddd.innerHTML='';
  var d=$c('UL'); 
  var h=$ee(c,'H2');

  var lll=$c('div');
  var pp;

  var hh=h[h.length-1].nextSibling;
  while (hh.tagName!='DIV')
  {
    pp=hh.nextSibling;
    $a(lll,hh);
    hh=pp;
  };

//  var hhh=$ee(lll,'A');
//  for (var i=0; i<hhh.length; i++) 
//  {
//     $a(d,categoryListItem(hhh[i].href,hhh[i].innerHTML));
//  }
  $a(ddd,lll);
}

function showCategoryBrowser ()
{
  var cb=constructCategoryBrowser();
  $a($e('globalWrapper'),cb);
  $e('categoryTreeView').addEventListener('click',categoryTreeClick,true);
  $e('categoryListView').addEventListener('click',categoryListClick,true);
  $e('categoryArticleView').addEventListener('click',categoryListClick,true);
  document.addEventListener('doubleclick',categoryIconCloseClick,true);
}

function categoryIconCloseClick (e)
{
  document.removeEventListener('doubleclick',categoryIconCloseClick,true);
  $r($e('globalWrapper'),$e('categoryBrowser'));
}

function constructCategoryBrowser ()
{
  return $d('categoryBrowser','<table id="categoryBrowserTable"><tr><td rowspan="2" id="categoryTreeView"></td>'
        +'<td id="categoryListView"></td></tr>'
        +'<tr><div id="content"><iframe id="categoryArticleView"></iframe></div></tr></table>');
}



//DOM shortcuts
//$e=function(id) {var d=document.getElementById(id); if (d) {return d} else {alert ("Couldn't find id: "+id)};}
$e=function(id) {return document.getElementById(id);}
$ee=function(parent,tag) {return parent.getElementsByTagName(tag)}
$c=function(tag) {return document.createElement(tag)}
$d=function(id,i) {var d=$c('DIV'); d.id=id; d.innerHTML=i; return d}
$cc=function(tag,id,i) {var d=$c(tag); d.id=id; d.innerHTML=i; return d}
$r=function(parent,child) {return parent.removeChild(child)}
$a=function(parent,child) {return parent.appendChild(child)}

//DOWNLOADER
function loadText(url,cb1,cb2) {
  var x = window.XMLHttpRequest ? new XMLHttpRequest()
        : window.ActiveXObject ? new ActiveXObject("Microsoft.XMLHTTP")
        : false;
  var c=document.createElement("div");

  if (x) {
    x.onreadystatechange=function() {
      x.readyState==4 && textLoaded(x,c,cb1,cb2)};
    x.open("GET",url,true);
    x.setRequestHeader('Accept','text/*');
    x.send(null); }
}

function textLoaded(x,c,cb1,cb2) {
  x.status==200
  && ((c.innerHTML=x.responseText) && cb1 && cb1(x,c))
  || ( cb2 && cb2(x,c) || alert(x.statusText));
}

//XML helper functions
function findDescendantById(node, id) {
  if (node.id == id) { return node; }
  var i, c;
  for (i = node.firstChild; i != null; i=i.nextSibling) {
    c = findDescendantById(i,id);
    if (c != null)
      return c; }
  return null;
}

//</nowiki></pre>