// ==UserScript==
// @name Actitime Taskinator
// @version 3.0
// @namespace http://www.sra.com.au
// @description Filters the Actitime Time Track
// @include */user/submit_tt.do*
// ==/UserScript==
var taskinator_filterTarget = "//form[1]/table[2]/tbody[1]";
var taskinator_extractNumber = /^\D+(\d+).*$/;
initialiseTaskinator();
function initialiseTaskinator(){
taskinator_createHideColumn();
taskinator_restoreSelections();
}
function taskinator_hideRow(event){
if (event.target.checked && document.getElementById("masterHide").checked) {
var targetRow = event.target.parentNode.parentNode;
targetRow.style.display = "none";
}
}
function taskinator_checkAll(event){
document.getElementById("allLink").style.display = "none";
document.getElementById("noneLink").style.display = "inline";
taskinator_checkboxes(true);
}
function taskinator_uncheckAll(event){
document.getElementById("allLink").style.display = "inline";
document.getElementById("noneLink").style.display = "none";
taskinator_checkboxes(false);
}
function taskinator_checkboxes(state){
var rowCollection = taskinator_evaluateXPath(document, taskinator_filterTarget + "/tr");
for (var i = 2; i < (rowCollection.length - 1); i++) {
var curRow = rowCollection[i];
curRow.getElementsByTagName("INPUT").item(0).checked = state;
curRow.style.display = "table-row";
}
document.getElementById("masterHide").checked = !state;
}
function taskinator_hideAll(event){
var rowCollection = taskinator_evaluateXPath(document, taskinator_filterTarget + "/tr");
if (event.target.checked){
//hide any rows that have checks
for (var i = 2; i < (rowCollection.length - 1); i++) {
var curRow = rowCollection[i];
if (curRow.getElementsByTagName("INPUT").item(0).checked){
curRow.style.display = "none";
}
}
}else {
//display all rows
for (var i = 2; i < (rowCollection.length - 1); i++) {
var curRow = rowCollection[i];
curRow.style.display = "table-row";
}
}
}
function taskinator_restoreSelections(){
var encodedString = GM_getValue("taskinatorSelectionData","");
var selectionArray = encodedString.split("||");
var selectionData;
document.getElementById("masterHide").checked = true;
for (var i = 1; i < selectionArray.length;i++){
selectionData = selectionArray[i].split("|");
if (document.getElementById(selectionData[0]) && selectionData[0] != "masterHide"){
if (selectionData[1] == "true"){
document.getElementById(selectionData[0]).checked = true;
} else {
document.getElementById(selectionData[0]).checked = false;
}
if (selectionData[1] == "true" && document.getElementById("masterHide").checked){
document.getElementById(selectionData[0]).parentNode.parentNode.style.display = "none";
} else {
document.getElementById(selectionData[0]).parentNode.parentNode.style.display = "table-row";
}
} else if ( selectionData[0] == "masterHide" && selectionData[1] != "true") {
document.getElementById(selectionData[0]).checked = false;
}
}
}
function taskinator_saveSelections(){
var encodedString = "||masterHide|" + document.getElementById("masterHide").checked;
var rowCollection = taskinator_evaluateXPath(document, taskinator_filterTarget + "/tr");
for (var i = 2; i < (rowCollection.length - 1); i++) {
var curCheckbox = rowCollection[i].getElementsByTagName("INPUT").item(0);
if (curCheckbox.id) {
encodedString = encodedString + "||" + curCheckbox.id + "|" + curCheckbox.checked;
}
}
GM_setValue("taskinatorSelectionData",encodedString);
}
function taskinator_createHideColumn(){
var filterList, checkBox, rowCollection;
filterList = taskinator_evaluateXPath(document, taskinator_filterTarget)[0];
filterList.parentNode.style.width = "95%";
filterList.id = "filterTarget";
checkBox = document.createElement("INPUT");
checkBox.type = "checkbox";
checkBox.id = "masterHide";
checkBox.checked = true;
checkBox.addEventListener("click", taskinator_hideAll, true);
var anchor = document.createElement("A");
anchor.href = "javascript:;";
anchor.id = "allLink";
anchor.appendChild(document.createTextNode("All"));
anchor.addEventListener("click", taskinator_checkAll, true);
var tableData = document.createElement("TD");
tableData.className = "listtblcolheader";
tableData.rowSpan = "2";
tableData.align = "center";
tableData.appendChild(document.createTextNode("Hide"));
tableData.appendChild(document.createElement("BR"));
tableData.appendChild(checkBox);
tableData.appendChild(document.createElement("BR"));
tableData.appendChild(anchor);
anchor = document.createElement("A");
anchor.id = "noneLink";
anchor.href = "javascript:;";
anchor.appendChild(document.createTextNode("None"));
anchor.addEventListener("click", taskinator_uncheckAll, true);
anchor.style.display = "none";
tableData.appendChild(anchor);
filterList.getElementsByTagName("TR").item(0).insertBefore(tableData,filterList.getElementsByTagName("TD").item(0));
rowCollection = taskinator_evaluateXPath(document, taskinator_filterTarget + "/tr");
for (var i = 2; i < (rowCollection.length - 1); i++) {
var curRow = rowCollection[i];
var curTaskId = curRow.getElementsByTagName("A").item(0).href.replace(taskinator_extractNumber,"$1"); //extract task number from the url
if (curTaskId == 0) curTaskId = curRow.getElementsByTagName("A").item(1).href.replace(taskinator_extractNumber,"$1");
curRow.id = "taskRow" + curTaskId;
checkBox = document.createElement("INPUT");
checkBox.type = "checkbox";
checkBox.id = "hideRow" + curTaskId;
checkBox.addEventListener("click",taskinator_hideRow, true);
var tableData = document.createElement("TD");
tableData.className = "listtblcell";
tableData.align = "center";
tableData.appendChild(checkBox);
curRow.insertBefore(tableData,curRow.getElementsByTagName("TD").item(0));
}
/* Add some stuff to the bottom row... */
var totalsRow = taskinator_evaluateXPath(document, taskinator_filterTarget + '/tr[last()]')[0];
//Undo link...
tableData = document.createElement("TD");
tableData.className = "weektotalheader";
tableData.align = "center";
tableData.id = "debugging"; //I sometimes use this element to output debugging messages as comments to like innerHTML += "<!-- " + messages + "-->"
anchor = document.createElement("A");
anchor.href = "javascript:;";
anchor.appendChild(document.createTextNode("Undo"));
anchor.addEventListener("click", taskinator_restoreSelections, true);
tableData.appendChild(anchor);
totalsRow.insertBefore(tableData,totalsRow.getElementsByTagName("TD").item(0));
//~ //Push the cells across for the reports link
//~ var weekTotalCell = taskinator_evaluateXPath(document, taskinator_filterTarget + '/tr[last()]/td/table')[0].parentNode;
//~ weekTotalCell.colSpan = weekTotalCell.colSpan - 1;
//~ weekTotalCell.id = "weekTotalCell";
//~ //Reports link...
//~ tableData = document.createElement("TD");
//~ tableData.className = "weektotalheader";
//~ tableData.align = "center";
//~ tableData.id = "runreports";
//~ anchor = document.createElement("A");
//~ anchor.href = "javascript:alert('Not implemented!');";
//~ anchor.appendChild(document.createTextNode("Reports"));
//~ //anchor.addEventListener("click", backgroundReporting, true);
//~ tableData.appendChild(anchor);
//~ totalsRow.insertBefore(tableData,weekTotalCell);
unsafeWindow.onunload = taskinator_saveSelections;
}
// Evaluate an XPath expression aExpression against a given DOM node
// or Document object (aNode), returning the results as an array
// thanks wanderingstan at morethanwarm dot mail dot com for the
// initial work.
function taskinator_evaluateXPath(aNode, aExpr) {
var xpe = new XPathEvaluator();
var nsResolver = xpe.createNSResolver(aNode.ownerDocument == null ?
aNode.documentElement : aNode.ownerDocument.documentElement);
var result = xpe.evaluate(aExpr, aNode, nsResolver, 0, null);
var found = [];
var res;
while (res = result.iterateNext())
found.push(res);
return found;
}