/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set et sw=2 ts=2: */ 'use strict'; function createId(boardid, nodeid) { return "b" + boardid + "_t" + nodeid; } function idFromStr(str) { return str.substring(str.search('t') + 1, str.length); } function subscriptionIdFromStr(str) { return str.substring(1, str.search('_')); } var nodes = new Array(); function findNode(id, subscribeid) { for(var i = 0; i < nodes.length; i++) { var node = nodes[i]; var child = node.findNode(id, subscribeid); if(child != null) { return child; } } return null; } function findNodeFromString(idstr) { return findNode(idFromStr(idstr), subscriptionIdFromStr(idstr)); } function Node(id, subscribeid) { this.id = id; this.subscribeid = subscribeid; this.childNodes = new Array(); this.attributes = {}; this.parent = null; } Node.prototype.dump = function() { alert(this.id); }; Node.prototype.dumpChildren = function(msg) { console.log("Node " + this.id + " children (" + this.childNodes.length + "):"); if(msg) { console.log(msg); } for(var i = 0; i < this.childNodes.length; i++) { console.log("[" + i + "]: " + this.childNodes[i].id); } } Node.prototype.findNode = function(id, subscribeid) { if(this.subscribeid != subscribeid) { return null; } if(this.id == id) { return this; } for(var i = 0; i < this.childNodes.length; i++) { var node = this.childNodes[i]; var child = node.findNode(id, subscribeid); if(child != null) { return child; } } return null; }; Node.prototype.addChild = function(node, insertBeforeId) { if(node.parent != null) { node.parent.removeChild(node); } node.parent = this; var inserted = false; for(var i = 0; i < this.childNodes.length; ++i) { if(this.childNodes[i].id == insertBeforeId) { this.childNodes.splice(i, 0, node); this.children_element.insertBefore(node.element, this.children_element.childNodes[i]); inserted = true; break; } } if(inserted == false) { this.childNodes.push(node); this.children_element.appendChild(node.element); } // if(this.childNodes.length == 0) // { // this.element.style.backgroundColor = "#aaa"; // } // else // { // this.element.style.backgroundColor = "#aaaa81"; // } }; Node.prototype.removeChild = function(node) { this.childNodes = this.childNodes.filter(function(e) { return e.id != node.id; }); node.parent = null; this.children_element.removeChild(node.element); // if(this.childNodes.length == 0) // { // this.element.style.backgroundColor = "#aaa"; // } // else // { // this.element.style.backgroundColor = "#aaaa81"; // } }; Node.prototype.create = function() { // Node root element this.element = document.createElement("div"); // Element for title, description, state, etc... this.data_element = document.createElement("div"); this.data_element.className = "data"; this.data_element.style.pointerEvents = "none"; this.element.appendChild(this.data_element); // Root element for child nodes. this.children_element = document.createElement("div"); this.children_element.className = "children"; this.element.appendChild(this.children_element); this.div_id = document.createElement("span"); this.div_id.setAttribute("class", "id"); this.data_element.appendChild(this.div_id); this.div_title = document.createElement("span"); this.div_title.setAttribute("class", "title"); var id_txt = document.createTextNode(this.id); this.div_id.appendChild(id_txt); this.data_element.appendChild(this.div_title); this.setAttribute("title", ""); var node = this.element; node.name = "node"; node.setAttribute("class", "node"); node.setAttribute("ondblclick", "editTitle(event)"); node.setAttribute("ondrop", "drop(event)"); node.setAttribute("ondragenter", "dragenter(event)"); node.setAttribute("ondragover", "dragover(event)"); node.setAttribute("ondragleave", "dragleave(event)"); node.setAttribute("draggable", true); node.setAttribute("ondragstart", "drag(event)"); node.setAttribute("ondragend", "dragEnd(event)"); node.setAttribute("nodeid", this.id); // This is a hack to make it possible to identify the nodeid and // oberveid from the node id alone. node.id = createId(this.subscribeid, this.id); var add_child_button = document.createElement("div"); add_child_button.name = "add_button"; add_child_button.setAttribute("onclick", "addChild(event)"); add_child_button.setAttribute("nodeid", this.id); add_child_button.setAttribute("class", "button"); var txt_plus = document.createTextNode("+"); add_child_button.appendChild(txt_plus); this.data_element.appendChild(add_child_button); var collapse_button = document.createElement("div"); collapse_button.name = "add_button"; collapse_button.setAttribute("onclick", "collapse(event)"); collapse_button.setAttribute("nodeid", this.id); collapse_button.setAttribute("class", "button"); var txt_v = document.createTextNode("v"); collapse_button.appendChild(txt_v); this.data_element.appendChild(collapse_button); this.state_element = document.createElement("div"); this.state_element.name = "state"; this.state_element.setAttribute("onclick", "changeState(event)"); this.state_element.setAttribute("nodeid", this.id); this.state_element.setAttribute("class", "state"); var txt_state = document.createTextNode(""); this.state_element.appendChild(txt_state); this.data_element.appendChild(this.state_element); /* var subscribe_button = document.createElement("div"); subscribe_button.name = "subscribe_button"; subscribe_button.setAttribute("onclick", "subscribeMe(this, event)"); subscribe_button.setAttribute("nodeid", this.id); subscribe_button.setAttribute("style", "float: left; display: inline-box; width:14px; height: 14px; border: solid green 2px; cursor: pointer;"); var txt_plus = document.createTextNode("+"); subscribe_button.appendChild(txt_plus); this.data_element.appendChild(subscribe_button); var unsubscribe_button = document.createElement("div"); unsubscribe_button.name = "unsubscribe_button"; unsubscribe_button.setAttribute("onclick", "unsubscribeMe(this, event)"); unsubscribe_button.setAttribute("nodeid", this.id); unsubscribe_button.setAttribute("style", "float: left; display: inline-box; width:14px; height: 14px; border: solid red 2px; cursor: pointer;"); var txt_minus = document.createTextNode("-"); unsubscribe_button.appendChild(txt_minus); this.data_element.appendChild(unsubscribe_button); */ { var collapsed = getCookie(node.id+"_collapsed") == "true"; if(collapsed) { //this.children_element.style.maxHeight = "16px"; this.children_element.classList.add('collapsed'); } else { //this.children_element.style.maxHeight = "inherit"; this.children_element.classList.remove('collapsed'); } } }; Node.prototype.setAttribute = function(name, value) { this.attributes[name] = value; if(name == "title") { if(this.div_title.firstChild != null) { this.div_title.removeChild(this.div_title.firstChild); } var title_txt = document.createTextNode(value); this.div_title.appendChild(title_txt); } if(name == "dragged") { if(value == "true") { // Make transparent and non-draggable this.element.style.opacity = "0.3"; // TODO: Apply recursively? this.element.setAttribute("draggable", false); } else { // Make opaque and draggable again this.element.style.opacity = "1.0"; // TODO: Apply recursively? this.element.setAttribute("draggable", true); } } if(name == "state") { var txt = this.state_element.firstChild; if(txt != null) { this.state_element.removeChild(txt); } txt = document.createTextNode(value); this.state_element.appendChild(txt); if(value == "done") { this.state_element.style.color = "green"; } else if(value == "in-progress") { this.state_element.style.color = "yellow"; } else if(value == "blocked") { this.state_element.style.color = "red"; } else { this.state_element.style.color = "black"; } } }; Node.prototype.getTitle = function() { return this.attributes["title"]; };