diff options
-rw-r--r-- | handler.js | 102 | ||||
-rw-r--r-- | munia.css | 58 | ||||
-rw-r--r-- | munia.html | 79 | ||||
-rw-r--r-- | proto.js | 3 | ||||
-rw-r--r-- | task.js | 123 | ||||
-rw-r--r-- | view.js | 148 |
6 files changed, 447 insertions, 66 deletions
diff --git a/handler.js b/handler.js new file mode 100644 index 0000000..60a6aee --- /dev/null +++ b/handler.js @@ -0,0 +1,102 @@ +/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ + + +document.addEventListener("connectEvent", connectEventHandler, false); +function connectEventHandler(e) +{ + document.getElementById("wstask_status").style.backgroundColor = "#40ff40"; + document.getElementById("wstask_status").textContent = "TaskProto websocket connection opened "; + socket_task.send("observe 0;"); +} + +document.addEventListener("disconnectEvent", disconnectEventHandler, false); +function disconnectEventHandler(e) +{ + document.getElementById("wstask_status").style.backgroundColor = "#ff4040"; + document.getElementById("wstask_status").textContent = "TaskProto websocket connection CLOSED "; +} + +document.addEventListener("removeEvent", removeEventHandler, false); +function removeEventHandler(e) +{ + var observeid = e.detail.observeid; + var id = e.detail.id; + + var task = findTask(id, observeid); + if(task.parent) task.parent.removeChild(task); +} + +document.addEventListener("moveEvent", moveEventHandler, false); +function moveEventHandler(e) +{ + var observeid = e.detail.observeid; + var id = e.detail.id; + var parentid = e.detail.parentid; + + var task = findTask(id, observeid); + var new_parent = findTask(parentid, observeid); + if(task != null && new_parent != null) new_parent.addChild(task); +} + +document.addEventListener("createEvent", createEventHandler, false); +function createEventHandler(e) +{ + var observeid = e.detail.observeid; + var id = e.detail.id; + var parentid = e.detail.parentid; + + var task = new Task(id, observeid); + task.create(); + + if(parentid == -1) { + tasks.push(task); + var board = getBoard(observeid); + board.appendChild(task.element); + return; + } + + var parent = findTask(parentid, observeid); + if(parent != null) { + parent.addChild(task); + } + +} + +document.addEventListener("updateEvent", updateEventHandler, false); +function updateEventHandler(e) +{ + var observeid = e.detail.observeid; + var id = e.detail.id; + var name = e.detail.name; + var value = e.detail.value; + + var task = findTask(id, observeid); + if(task == null) return; + + task.setAttribute(name, value); + + //LogEvent("update handled"); +} + +/////// +////// +///// +//// +/// +// + +document.addEventListener("messageEvent", messageEventHandler, false); +function messageEventHandler(e) { + LogEvent( + "Event: " + e.detail.time.toLocaleString()+": "+e.detail.message + ); +} + +// log event in console +function LogEvent(msg) { + var log = document.getElementById("log"); + log.textContent += msg + "\n"; + var ot = log.scrollHeight - log.clientHeight; + if (ot > 0) log.scrollTop = ot; +} diff --git a/munia.css b/munia.css new file mode 100644 index 0000000..9fab874 --- /dev/null +++ b/munia.css @@ -0,0 +1,58 @@ +/* Prevent the text contents of draggable elements from being selectable. */ +[draggable] { + -moz-user-select: none; + -khtml-user-select: none; + -webkit-user-select: none; + user-select: none; +} + +body { + cursor: default; +} + +.task { + -webkit-touch-callout: none; + -webkit-user-select: none; + -khtml-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + -o-user-select: none; + user-select: none; + cursor: move; + background-color: #888; + border-style: solid; + border-width: medium; +/* border-radius: 15px;*/ + padding: 4px; + margin: 6px; + max-width: 300px; +} + +.board { + width: *; + min-height: 100px; + padding: 2px; + margin: 2px; + + background: -moz-linear-gradient(left center, rgb(0,0,0), rgb(79,79,79), rgb(21,21,21)); + background: -webkit-gradient(linear, left top, right top, + color-stop(0, rgb(0,0,0)), + color-stop(0.50, rgb(79,79,79)), + color-stop(1, rgb(21,21,21))); + background: -webkit-linear-gradient(left center, rgb(0,0,0), rgb(79,79,79), rgb(21,21,21)); + background: -ms-linear-gradient(left center, rgb(0,0,0), rgb(79,79,79), rgb(21,21,21)); +} + + +.log +{ + height: 20em; + font-family: monospace; + font-size: 1em; + padding: 2px 5px; + color: #0f0; + background-color: #111; + border: 1px solid #030; + border-radius: 4px; + overflow: auto; +} @@ -2,83 +2,34 @@ "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang="en"> <head> + <meta http-equiv="Pragma" content="no-cache"/> + <meta http-equiv="Expires" content="-1"/> <title>Munia</title> -<style> -/* Prevent the text contents of draggable elements from being selectable. */ -[draggable] { - -moz-user-select: none; - -khtml-user-select: none; - -webkit-user-select: none; - user-select: none; -} - -body { - cursor: default; -} - -.task { - -webkit-touch-callout: none; - -webkit-user-select: none; - -khtml-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - -o-user-select: none; - user-select: none; - cursor: move; - background-color: #888; - border-style: solid; - border-width: medium; -/* border-radius: 15px;*/ - padding: 4px; - margin: 6px; - max-width: 300px; -} - -.board { - width: *; - min-height: 100px; - padding: 2px; - margin: 2px; - - background: -moz-linear-gradient(left center, rgb(0,0,0), rgb(79,79,79), rgb(21,21,21)); - background: -webkit-gradient(linear, left top, right top, - color-stop(0, rgb(0,0,0)), - color-stop(0.50, rgb(79,79,79)), - color-stop(1, rgb(21,21,21))); - background: -webkit-linear-gradient(left center, rgb(0,0,0), rgb(79,79,79), rgb(21,21,21)); - background: -ms-linear-gradient(left center, rgb(0,0,0), rgb(79,79,79), rgb(21,21,21)); -} - - -.log -{ - height: 20em; - font-family: monospace; - font-size: 1em; - padding: 2px 5px; - color: #0f0; - background-color: #111; - border: 1px solid #030; - border-radius: 4px; - overflow: auto; -} - -</style> + <link rel="stylesheet" type="text/css" href="/munia.css" media="screen"/> </head> <body id="body"> -<div id="boards" class="boards"></div> <div id="wstask_status">TaskProto not initialized</div> TaskProto: <input type="text" id="input_task_data" value="observe 0" onfocus="clear()"/> <input type="button" value="submit" onclick="task_submit()"/><br/> -TaskMessages: <span id="wstask_lastmsg"></span><br/> </div> +<script type="text/javascript"> +function task_submit() { + var data = document.getElementById("input_task_data").value; + socket_task.send(data); +} +</script> + +<div id="boards" class="boards"></div> + <pre class="log" id="log">Event information log ===================== </pre> -<script type="text/javascript" charset="utf-8" src="/handler.js"></script> <script type="text/javascript" charset="utf-8" src="/proto.js"></script> +<script type="text/javascript" charset="utf-8" src="/task.js"></script> +<script type="text/javascript" charset="utf-8" src="/view.js"></script> +<script type="text/javascript" charset="utf-8" src="/handler.js"></script> </body> </html> @@ -40,8 +40,6 @@ try { } socket_task.onmessage = function got_packet(msg) { - document.getElementById("wstask_lastmsg").textContent = msg.data; - var messageEvent = new CustomEvent("messageEvent", { detail: { message: msg.data, @@ -163,3 +161,4 @@ try { } catch(exception) { alert('<p>Error' + exception + '</p>'); } + @@ -0,0 +1,123 @@ +/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ + +var tasks = new Array(); + +function findTask(id, observeid) +{ + for(var i = 0; i < tasks.length; i++) { + var task = tasks[i]; + var child = task.findTask(id, observeid); + if(child != null) return child; + } + + return null; +} + +function Task(id, observeid) +{ + this.id = id; + this.observeid = observeid; + this.children = new Array(); + this.attributes = {}; + this.parent = null; + + // Elements: + this.element = document.createElement("div"); + this.div_id = document.createElement("span"); + this.div_title = document.createElement("span"); +} + +Task.prototype.dump = function() +{ + alert(this.id); +} + +Task.prototype.findTask = function(id, observeid) +{ + if(this.observeid != observeid) return null; + + if(this.id == id) return this; + + for(var i = 0; i < this.children.length; i++) { + var task = this.children[i]; + var child = task.findTask(id, observeid); + if(child != null) return child; + } + + return null; +} + +Task.prototype.addChild = function(task) +{ + if(task.parent != null) task.parent.removeChild(task); + this.children.push(task); + task.parent = this; + this.element.appendChild(task.element); +} + +Task.prototype.removeChild = function(task) +{ + this.children = this.children.filter( + function(e) { + return e.id != task.id; + }); + task.parent = null; + this.element.removeChild(task.element); +} + +Task.prototype.create = function() +{ + var task = this.element; + + task.name = "task"; + task.setAttribute("class", "task"); + task.setAttribute("ondblclick", "editTitle(this, event)"); + //task.setAttribute("onclick", "showHideChildren(this, event)"); + task.setAttribute("ondrop", "drop(this, event)"); + task.setAttribute("ondragover", "return false"); + task.setAttribute("draggable", true); + task.setAttribute("ondragstart", "drag(this, event)"); + task.setAttribute("title", this.id); + + task.id = createId(this.observeid, this.id); +/* + var observe_button = document.createElement("div"); + observe_button.name = "observe_button"; + observe_button.setAttribute("onclick", "observeMe(this, event)"); + observe_button.setAttribute("title", this.id); + observe_button.setAttribute("style", "float: left; display: inline-box; width:14px; height: 14px; border: solid green 2px; cursor: pointer;"); + var txt_plus = document.createTextNode("+"); + observe_button.appendChild(txt_plus); + task.appendChild(observe_button); + + var unobserve_button = document.createElement("div"); + unobserve_button.name = "unobserve_button"; + unobserve_button.setAttribute("onclick", "unobserveMe(this, event)"); + unobserve_button.setAttribute("title", this.id); + unobserve_button.setAttribute("style", "float: left; display: inline-box; width:14px; height: 14px; border: solid red 2px; cursor: pointer;"); + var txt_minus = document.createTextNode("-"); + unobserve_button.appendChild(txt_minus); + task.appendChild(unobserve_button); +*/ + this.element.appendChild(this.div_id); + var id_txt = document.createTextNode(this.id); + this.div_id.appendChild(id_txt); + + this.element.appendChild(this.div_title); + + this.setAttribute("title", "(missing title)"); +} + +Task.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); + } +}
\ No newline at end of file @@ -0,0 +1,148 @@ +/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set et sw=2 ts=2: */ + +/* +function createTask() +{ + var task = new Task(); + task.id = 42; + task.dump = function() { + alert(this.id); + } +} +*/ + +function createId(boardid, taskid) +{ + return "b" + boardid + "_t" + taskid; +} + +function idFromStr(str) +{ + return str.substring(str.search('t') + 1, str.length); +} + +function getTask(observeid, id) +{ + +} + +function updateTask(observeid, id, name, value) +{ +} + +function getBoard(observeid) +{ + var board = document.getElementById("board_" + observeid); + if(!board) { + board = document.createElement("div"); + board.name = "board"; + board.setAttribute("class", "board"); + board.id = "board_" + observeid; + boards.appendChild(board); + } + + return board; +} + +////////////////////////////////////////////////////// +////////////////////////////////////////////////////// + +function clear() { + document.getElementById("input_data").value = ""; +} + +function deleteTask(id) { + socket_task.send("remove " + id + ";"); +} + +function drag(target, e) { + e.dataTransfer.setData('Text', target.id); + e.stopPropagation(); // <--- this fixes the drag target problem +} + +function drop(target, e) { + e.preventDefault(); + e.stopPropagation(); + + var id = e.dataTransfer.getData('Text'); + var task = document.getElementById(id); + socket_task.send("move " + idFromStr(id) + " " + idFromStr(target.id) + ";"); +} + +function observeMe(target, e) +{ + e.stopPropagation(); + socket_task.send("observe "+target.title+";"); +} + +function unobserveMe(target, e) +{ + e.stopPropagation(); + socket_task.send("unobserve "+target.title+";"); +} + +function showHideChildren(target, e) +{ + e.stopPropagation(); + updateid = idFromStr(target.id); + if(target.style.backgroundColor != "red") { + target.style.backgroundColor = "red"; + for(var i = 1; i < target.childNodes.length; i++) { + target.childNodes[i].style.display = "none"; + } + } else { + target.style.backgroundColor = "grey"; + for(var i = 1; i < target.childNodes.length; i++) { + target.childNodes[i].style.display = "block"; + } + } +} + +// +// Butt ugly.. but hey! it works... +// +var updateid; +var divtxt; +var oldtxt; +var oldtitle; +function onKeyUpHandler(target, e) +{ + if(e.which == 13) { // enter + divtxt.removeChild(target); + oldtxt.nodeValue = 'updating...'; + socket_task.send("update " + updateid + " \""+target.value+"\";"); + } + if(e.which == 27) { // escape + divtxt.removeChild(target); + oldtxt.nodeValue = oldtitle; + } +} + +function onLostFocusHandler(target, e) +{ + if(target.value == oldtitle) { + divtxt.removeChild(target); + oldtxt.nodeValue = oldtitle; + } +} + +function editTitle(target, e) +{ + e.stopPropagation(); + updateid = idFromStr(target.id); + if(updateid < 10) return; + var inp = document.createElement("input"); + var txtdiv = document.getElementById(target.id + "_txt"); + divtxt = txtdiv; + oldtxt = txtdiv.firstChild; + oldtitle = oldtxt.nodeValue; + oldtxt.nodeValue = ""; + inp.setAttribute("onkeyup", "onKeyUpHandler(this, event)"); + inp.setAttribute("onblur", "onLostFocusHandler(this, event)"); + inp.setAttribute("style", "border: inherit; padding: inherit; margin: inherit; background: inherit;"); + inp.value = oldtitle; + lineedit = inp; + txtdiv.appendChild(inp); + inp.focus(); +} |