User:Gyrobo/sortISODate.js

From Wikipedia, the free encyclopedia
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.
/**
 *    Sort references by date if they are in YMD/ISO 8601 format
 *    To use, insert the following into your vector.js page:
 *    importScript("User:Gyrobo/sortISODate.js");
 **/

var ref_sorted_type = false;

// Convert nodelist to array
// http://stackoverflow.com/questions/2735067/how-to-convert-a-dom-node-list-to-an-array-in-javascript
function toArray(obj) {
  var array = [];
  // iterate backwards ensuring that length is an UInt32
  for (var i = obj.length >>> 0; i--;) { 
    array[i] = obj[i];
  }
  return array;
}

function sortReferencesByDate() {
  var references = [];
  var i = 0;

  // FF 3.5+, Opera 10+, Safari 3.1+, Chrome, IE8+
  if (document.querySelectorAll) {
    references = document.querySelectorAll("ol.references");
  }

  // You should really upgrade
  else {
    return false;
  }

  // Iterate through each reference block
  for (var l = 0; l < references.length; l++) {

    refs = references[l].getElementsByTagName("li");
    refs = toArray(refs);
    var dates = [];
  
    // Build date array
    for (i = 0; i < refs.length; i++) {
      dates[dates.length] = refs[i].innerHTML.match(/\d{4}-\d{2}-\d{2}/);
    }

    // Now, sort them with a simple bubble sort (N^2 runtime)
    for (i = 0; i < dates.length; i++) {
      for (var k = 0; k < dates.length - 1; k++) {
        if (dates[k + 1] < dates[k]) {
          var td = dates[k];
          var tr = refs[k];
          
          dates[k] = dates[k + 1];
          refs[k] = refs[k + 1];
          
          dates[k + 1] = td;
          refs[k + 1] = tr;
        }
      }
    }
    
    // Should dates be reversed?
    if (ref_sorted_type) {
      dates = dates.reverse();
      refs = refs.reverse();
      ref_sorted_type = false;
    }
    else {
      ref_sorted_type = true;
    }

    // Now add all the references back to their section in order
    references[l].innerHTML = "";
    for (i = 0; i < refs.length; i++) {
      references[l].appendChild(refs[i]);
    }

  }
  
  return false;
}

function addSortingButton() {
  var references = [];

  // FF 3.5+, Opera 10+, Safari 3.1+, Chrome, IE8+
  if (document.querySelectorAll) {
    references = document.querySelectorAll("ol.references");
  }

  // You should really upgrade
  else {
    return false;
  }

  for (var i = 0; i < references.length; i++) {
    var node = references[i].parentNode;
    var a = document.createElement("a");
    a.href="#";
    a.onclick = sortReferencesByDate;
    a.innerHTML = "[Sort by date]";
    node.insertBefore(a, references[i]);
  }

}

if (window.addEventListener) {
  window.addEventListener("load", addSortingButton, false);
}
else {
  window.attachEvent("onload", addSortingButton);
}