Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Massive overhaul of the message tracking interface, bugs remain...

  • Loading branch information...
commit dc0be4b784891f082acdd7886ab6f707440c0488 1 parent 97c2417
@jamesgao authored
View
31 IPython/frontend/html/js/communicate.js
@@ -25,21 +25,7 @@ CometGetter.prototype.process = function (json) {
} else if (this.pause) {
setTimeout(function () { thisObj.process(json) }, 1)
} else {
-//$("#messages").append("<div class='headers'>"+json.msg_type+": "+json.parent_header.msg_id+"</div>")
- var id = json.parent_header.msg_id
- var msg = manager.get( id, json.parent_header.session)
- if (json.msg_type == "stream") {
- msg.setOutput(id, fixConsole(json.content.data))
- } else if (json.msg_type == "pyin") {
- if (json.parent_header.session != session)
- msg.setInput(id, fixConsole(json.content.code))
- } else if (json.msg_type == "pyout") {
- exec_count = json.content.execution_count
- msg.num = json.content.execution_count
- msg.setOutput(id, fixConsole(json.content.data), true)
- } else if (json.msg_type == "pyerr") {
- msg.setOutput(id, fixConsole(json.content.traceback.join("\n")))
- }
+ manager.process(json)
}
}
CometGetter.prototype.start = function () {
@@ -59,7 +45,7 @@ function heartbeat() {
})
}
-function execute(code, postfunc) {
+function execute(code, msg) {
comet.stop()
$.ajax({
type: "POST",
@@ -67,18 +53,7 @@ function execute(code, postfunc) {
success: function(json, status, request) {
comet.start()
if (json != null) {
- var id = json.parent_header.msg_id
- exec_count = json.content.execution_count
- if (typeof(postfunc) != "undefined")
- postfunc(json)
- if (json.content.payload.length > 0 &&
- json.content.payload[0]['format'] == "svg") {
- var svg = $(document.createElement('div'))
- svg.html(json.content.payload[0]['data'])
- manager.get(id).setOutput(id, svg)
- }
- //Open a new input object
- manager.get().activate()
+ manager.process(json, msg)
}
}
})
View
22 IPython/frontend/html/js/notebook.js
@@ -20,24 +20,34 @@ $(document).ready(function() {
statusbar = new StatusBar("statusbar")
})
+function xmlencode(string) {
+ return string.replace(/\&/g,'&'+'amp;').replace(/</g,'&'+'lt;')
+ .replace(/>/g,'&'+'gt;').replace(/\'/g,'&'+'apos;')
+ .replace(/\"/g,'&'+'quot;');
+}
+
+attrib = {"30":"cblack", "31":"cred","32":"cgreen", "34":"cblue", "36":"ccyan", "01":"cbold"}
function fixConsole(txt) {
//Fixes escaped console commands, IE colors. Turns them into HTML
//Unfortunately, the "semantics" of html and console are very
//different, so fancy things *will* break
- var attrib = {"30":"cblack", "31":"cred","32":"cgreen", "34":"cblue", "36":"ccyan", "01":"cbold"}
- txt = txt.replace("<","&lt;").replace(">", "&gt;")
+ txt = xmlencode(txt)
var re = /\033\[([\d;]+?)m/
var opened = false
+ var cmds = []
+ var opener = ""
+ var closer = ""
+
while (re.test(txt)) {
var cmds = txt.match(re)[1].split(";")
- opened = cmds[0] != "0"
- var close = opened?"":"</span>"
+ closer = opened?"</span>":""
+ opened = cmds.length > 1 || cmds[0] != 0
var rep = []
for (var i in cmds)
if (typeof(attrib[cmds[i]]) != "undefined")
rep.push(attrib[cmds[i]])
- var open = rep.length > 0?"<span class=\""+rep.join(" ")+"\">":""
- txt = txt.replace(re, close + open)
+ opener = rep.length > 0?"<span class=\""+rep.join(" ")+"\">":""
+ txt = txt.replace(re, closer + opener)
}
if (opened) txt += "</span>"
return txt.trim()
View
96 IPython/frontend/html/js/ui.js
@@ -28,7 +28,7 @@ function Manager(obj) {
thisObj.deactivate(thisObj.ondeck)
})
}
-Manager.prototype.get = function (msg_id, sess) {
+Manager.prototype.get = function (msg_id) {
if (typeof(msg_id) == "undefined") {
//Handle manager.get(), to return a new message on deck
if (this.ondeck == null) {
@@ -48,27 +48,11 @@ Manager.prototype.get = function (msg_id, sess) {
}
return this.ordering[this.cursor]
} else if (typeof(this.messages[msg_id]) == "undefined") {
- if (sess != session) {
- if (this.ondeck != null)
- this.ondeck.remove()
- this.messages[msg_id] = new Message(msg_id, this.obj)
- this.ordering.push(this.messages[msg_id])
- this.get().activate()
- }
+ this.messages[msg_id] = new Message(msg_id, this.obj)
+ this.ordering.push(this.messages[msg_id])
}
return this.messages[msg_id]
}
-Manager.prototype.set = function (msg_id, new_id) {
- if (typeof(new_id) == "undefined") {
- this.ondeck.msg_id = msg_id
- this.messages[msg_id] = this.ondeck
- this.ordering.push(this.ondeck)
- this.ondeck = null
- } else {
- this.messages[msg_id].msg_id = new_id
- this.messages[new_id] = this.messages[msg_id]
- }
-}
Manager.prototype.deactivate = function (current) {
for (var i in this.messages)
this.messages[i].deactivate()
@@ -80,6 +64,51 @@ Manager.prototype.deactivate = function (current) {
}
}
}
+Manager.prototype.process = function (json, origin) {
+ var id = json.parent_header.msg_id
+ var type = json.msg_type
+
+ if (typeof(origin) != "undefined") {
+ if (type != "execute_reply")
+ throw Exception("Recieved other message with an origin message??")
+ this.messages[id] = origin
+ if (origin == this.ondeck) {
+ this.ordering.push(origin)
+ this.ondeck = null
+ }
+ }
+
+ var msg = this.get(id)
+
+ if (type == "stream") {
+ msg.setOutput(fixConsole(json.content.data))
+ } else if (type == "pyin") {
+ msg.setInput(json.content.code, true)
+ } else if (type == "pyout") {
+ exec_count = json.content.execution_count
+ msg.num = json.content.execution_count
+ msg.setOutput(msg.output.html() + fixConsole(json.content.data), true)
+ } else if (type == "pyerr") {
+ msg.setOutput(fixConsole(json.content.traceback.join("\n")))
+ } else if (type == "execute_reply") {
+ exec_count = json.content.execution_count
+ //If this reply has an SVG, let's add it
+ if (json.content.payload.length > 0 &&
+ json.content.payload[0]['format'] == "svg") {
+ var data = json.content.payload[0]['data']
+ //Remove the doctype from the top, otherwise no way to embed
+ data = data.split("\n").slice(4).join("\n")
+ var svg = document.createElement("div")
+ svg.innerHTML = data
+ msg.setOutput(svg)
+ }
+ //Open a new input object
+ manager.get().activate()
+ }
+
+ if (typeof(origin) != "undefined")
+ origin.msg_id = id
+}
/***********************************************************************
* Each message is a paired input/output object
@@ -135,21 +164,19 @@ Message.prototype.deactivate = function () {
}
Message.prototype.remove = function () {
this.outer.remove()
- manager.ondeck = null
+ if (manager.ondeck == this)
+ manager.ondeck = null
}
-Message.prototype.setInput = function(msg_id, value) {
+Message.prototype.setInput = function(value, header) {
this.code = value
this.input.html(value)
+ var head = header?"In [<span class='cbold'>"+this.num+"</span>]:":""
+ this.in_head.html(head)
}
-Message.prototype.setOutput = function(msg_id, value, header) {
- if (this.msg_id != msg_id) {
- this.in_head.html("In [<span class='cbold'>"+this.num+"</span>]:")
- this.output.html(value)
- } else {
- this.output.append(value)
- }
- if (header)
- this.out_head.html("Out [<span class='cbold'>"+this.num+"</span>]:")
+Message.prototype.setOutput = function(value, header) {
+ this.output.html(value)
+ var head = header?"Out [<span class='cbold'>"+this.num+"</span>]:":""
+ this.out_head.html(head)
}
/***********************************************************************
@@ -186,14 +213,7 @@ InputArea.prototype.activate = function () {
}
InputArea.prototype.submit = function (code) {
this.msg.code = code
- var thisObj = this
- execute(code, function(json) {
- thisObj.msg.num = exec_count
- if (manager.ondeck == thisObj.msg)
- manager.set(json.parent_header.msg_id)
- else
- manager.set(thisObj.msg.msg_id, json.parent_header.msg_id)
- })
+ execute(code, this.msg)
}
InputArea.prototype.complete = function (matches) {
if (matches.length == 1)
View
2  IPython/frontend/html/kernelmanager.py
@@ -79,7 +79,7 @@ def do_GET(self):
json.dump(manager[path].get(), self.wfile)
elif path == "notebook":
self.send_response(200)
- self.send_header("Content-type", "text/html")
+ self.send_header("Content-type", "application/xhtml+xml")
self.end_headers()
#This is a good spot to add login mechanics
Please sign in to comment.
Something went wrong with that request. Please try again.