From 202a416dc5de2d1e00387c3b75eb568e84665922 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 12:44:55 +0100 Subject: [PATCH 01/30] preparation for dynamic objects --- debugger.js | 69 ++++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 63 insertions(+), 6 deletions(-) diff --git a/debugger.js b/debugger.js index 2c440f3..dd343f6 100644 --- a/debugger.js +++ b/debugger.js @@ -4,13 +4,70 @@ var file_get_contents = function(f,mode){return (!file_exists(f))? '' : require( var get_constr = function(v){ return(v===null)?"[object Null]":Object.prototype.toString.call(v); }; // var fnprefix = (["FUNCTION"].concat(process.hrtime()).concat(process.hrtime())).join('.'); // ONLY WORKS IN LATER Vs var fnprefix = 'TYPE_FUNC_'+(new Date().getTime()); + +var util = require("util"); var stringify = require('./stringify.js'); -var jsencr = function(o){ var e = []; return stringify(o, function(k,v){ - if(typeof(v)==='function') return fnprefix+v.toString(); - if(typeof(v)!=='object' || v===null) return v; - for(var i in e){ if(e[i]===v){ return "Circular"; }}; - e.push(v); return v; -}); }; + +var jsencr = function(o){ + var value = {}; + switch(typeof o) { + case 'object': + var id = objCache.register(o); + value.type = "object"; + value.typename = "Object"; + if(o.constructor && o.constructor.name) { + value.typename = o.constructor.name; + value.objid = id; + value.keys = []; + for(var key in o) { + // Add all keys which are strings or int. Otherwise, don't for now for simplification. + if(util.isString(key) || util.isNumber(key)) + value.keys.push(key); + } + break; + default: + value.type = "other"; + value.value = o; + } + var e = []; + return stringify(value, function(k,v){ + if(typeof(v)==='function') return fnprefix+v.toString(); + if(typeof(v)!=='object' || v===null) return v; + for(var i in e){ if(e[i]===v){ return "Circular"; }}; + e.push(v); + return v; + }); +}; + +var assert = require("assert"); + +var _objCache_counter = 0; + +function createObjCache() { + var objToId = {}; + var idToObj = {}; + + return { + register: register, + get: get + }; + + function register(obj) { + if(obj in objToId) return objToId[obj]; + _objCache_counter++; + var newId = _objCache_counter; + assert(!(newId in idToObj)); + objToId[obj] = newId; + idToObj[newId] = obj; + return newId; + } + + function get(id) { + return idToObj[id]; + } +} + +var objCache = createObjCache(); var dbg = { From fcf81b38c10128f08525ff061849b5d4158496bf Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 12:45:42 +0100 Subject: [PATCH 02/30] cleanup. not used --- scripts/console.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/scripts/console.js b/scripts/console.js index 35539a1..f99de7a 100644 --- a/scripts/console.js +++ b/scripts/console.js @@ -15,22 +15,6 @@ $(document).ready(function(){ var decd = function(v){ return $('
').html(v).text();}; window.clearConsole = function(){ c.val(''); return vw.html('');}; - - var treefiy_obj = function(o, n, c){ - var r = { data:""+n+"", state:!!c ? 'open' : 'closed', children:[] }; - for(var i in o){ - if(typeof(o[i])==='object' && o[i]!==null) - o[i] = treefiy_obj(o[i], i); - else{ - var val = encd(o[i]); - // if(val.length>100) val = ''+val.substr(0,100)+'... (length: '+val.length+')'; - o[i] = ""+i+""+val+''; - }; - r.children.push(o[i]); - }; - return r; - }; - window.focusLastMessage = function(){ vwscr.scrollTo(0,vw.height()); }; window.showAnError = function(err, type){ From 737210bcd0c58ab428a0ac512d35eca22fcc6278 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 13:12:47 +0100 Subject: [PATCH 03/30] safe fallback --- scripts/localtree.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/localtree.js b/scripts/localtree.js index 21c38f5..6e9da7e 100644 --- a/scripts/localtree.js +++ b/scripts/localtree.js @@ -26,6 +26,8 @@ window.formatStaticValue = function(data, nobrk){ var r = '' + (d)+''; return (type=='string' ? '"'+r+'"' : r); + default: + return 'unknown '+type+''; }; }; From 3db1b74c1d53430d3094df5263fd7c85ac7c85c6 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 13:13:19 +0100 Subject: [PATCH 04/30] use dynamic tree-from-obj --- scripts/console.js | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/scripts/console.js b/scripts/console.js index f99de7a..9fff1fb 100644 --- a/scripts/console.js +++ b/scripts/console.js @@ -14,7 +14,14 @@ $(document).ready(function(){ var encd = function(v){ return $('
').text(v).html();}; var decd = function(v){ return $('
').html(v).text();}; - window.clearConsole = function(){ c.val(''); return vw.html('');}; + window.clearConsole = function() { + $.ajax({url:'./', type:'POST', dataType:'text', data:'clear', complete:function(r) { + if(r.status!==200) return showAnError('Bad response from server ('+r.status+')'); + + c.val(''); + return vw.html(''); + }); + }; window.focusLastMessage = function(){ vwscr.scrollTo(0,vw.height()); }; window.showAnError = function(err, type){ @@ -27,16 +34,15 @@ $(document).ready(function(){ window.showAResponse = function(r){ var resp = $('
').appendTo(vw); - var tpo = typeof(r.cnt); if(typeof(r.fnprefix)==='string') window.fnprefix = r.fnprefix; if(r.cnt===null) tpo = 'null'; - switch(tpo){ + switch(r.cnt.type){ case 'object': - createTreeFromObj({'[object Object]':r.cnt}, $('.autoexpand').is('.sel')).appendTo(resp); + createTreeFromObj(r.cnt:, $('.autoexpand').is('.sel')).appendTo(resp); break; default: - $(formatStaticValue(r.cnt,false)).appendTo(resp); + $(formatStaticValue(r.cnt.value,false)).appendTo(resp); break; }; focusLastMessage(); From aeff641ea37c8b5635b9fcc2839a6181ac2de4fc Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 13:13:38 +0100 Subject: [PATCH 05/30] handle clear --- debugger.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/debugger.js b/debugger.js index dd343f6..dc1a809 100644 --- a/debugger.js +++ b/debugger.js @@ -17,6 +17,7 @@ var jsencr = function(o){ value.typename = "Object"; if(o.constructor && o.constructor.name) { value.typename = o.constructor.name; + value.str = "[" + value.typename + "]"; value.objid = id; value.keys = []; for(var key in o) { @@ -218,6 +219,8 @@ var dbg = { s.writeHead(200, {'Content-type': dbg.mimes['txt'], 'Content-length': r.length}); s.end(r); + } else if(post == "clear") { + s.end(); }else{ return dbg.serve500(s,'Command was not found'); } From 60d7ca9c2905e318ccf7ee06b7df92398f1665f6 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 13:15:00 +0100 Subject: [PATCH 06/30] handle clear in server --- debugger.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/debugger.js b/debugger.js index dc1a809..17f251e 100644 --- a/debugger.js +++ b/debugger.js @@ -70,6 +70,10 @@ function createObjCache() { var objCache = createObjCache(); +function clear() { + // reset obj cache + objCache = createObjCache(); +} var dbg = { @@ -220,6 +224,7 @@ var dbg = { s.writeHead(200, {'Content-type': dbg.mimes['txt'], 'Content-length': r.length}); s.end(r); } else if(post == "clear") { + clear(); s.end(); }else{ return dbg.serve500(s,'Command was not found'); From 4622a55921d69a0f971370c6a49fe6db26ff2ab2 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 14:48:32 +0100 Subject: [PATCH 07/30] handle dynget --- debugger.js | 45 +++++++++++++++++++++++++++++++++------------ 1 file changed, 33 insertions(+), 12 deletions(-) diff --git a/debugger.js b/debugger.js index 17f251e..d99c757 100644 --- a/debugger.js +++ b/debugger.js @@ -8,35 +8,47 @@ var fnprefix = 'TYPE_FUNC_'+(new Date().getTime()); var util = require("util"); var stringify = require('./stringify.js'); +function objGetPropertyDescriptor(obj, key) { + while(true) { + var desc = Object.getOwnPropertyDescriptor(obj, key); + if(desc) return desc; + obj = Object.getPrototypeOf(obj); + if(obj === Object) return null; + } +} + var jsencr = function(o){ - var value = {}; - switch(typeof o) { - case 'object': + function objDescription(o) { + var value = {}; var id = objCache.register(o); value.type = "object"; value.typename = "Object"; - if(o.constructor && o.constructor.name) { + if(o.constructor && o.constructor.name) value.typename = o.constructor.name; value.str = "[" + value.typename + "]"; value.objid = id; value.keys = []; + value.attribs = []; // each item is a 2-tuple. _[0] says whether this is static. if static, _[1] is the value. for(var key in o) { // Add all keys which are strings or int. Otherwise, don't for now for simplification. - if(util.isString(key) || util.isNumber(key)) - value.keys.push(key); + if(!util.isString(key) && !util.isNumber(key)) continue; + value.keys.push(key); + var prop = objGetPropertyDescriptor(o, key); + if(!prop || !prop.get) + value.attribs.push([true, o[key]]); + else + value.attribs([false, undefined]); } - break; - default: - value.type = "other"; - value.value = o; + return value; } var e = []; - return stringify(value, function(k,v){ + return stringify(o, function(k,v){ if(typeof(v)==='function') return fnprefix+v.toString(); if(typeof(v)!=='object' || v===null) return v; for(var i in e){ if(e[i]===v){ return "Circular"; }}; + if(util.isArray(v)) return v; e.push(v); - return v; + return objDescription(v); }); }; @@ -226,6 +238,15 @@ var dbg = { } else if(post == "clear") { clear(); s.end(); + } else if(post.dynget) { + var r = {error:false}; + + try{ + var obj = objCache.get(post.dynget.objid); + r.cnt = obj[post.dynget.key]; + }catch(e){ r.error=e.toString(); } + + s.end(jsencr(r)); }else{ return dbg.serve500(s,'Command was not found'); } From 91a62bc3fbf6c879aa595feb7717368c295a35f2 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 14:48:46 +0100 Subject: [PATCH 08/30] fix typos --- scripts/console.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/console.js b/scripts/console.js index 9fff1fb..fab20ec 100644 --- a/scripts/console.js +++ b/scripts/console.js @@ -20,7 +20,7 @@ $(document).ready(function(){ c.val(''); return vw.html(''); - }); + }}); }; window.focusLastMessage = function(){ vwscr.scrollTo(0,vw.height()); }; @@ -37,9 +37,9 @@ $(document).ready(function(){ if(typeof(r.fnprefix)==='string') window.fnprefix = r.fnprefix; if(r.cnt===null) tpo = 'null'; - switch(r.cnt.type){ + switch(typeof r.cnt){ case 'object': - createTreeFromObj(r.cnt:, $('.autoexpand').is('.sel')).appendTo(resp); + createTreeFromObj(r.cnt, $('.autoexpand').is('.sel')).appendTo(resp); break; default: $(formatStaticValue(r.cnt.value,false)).appendTo(resp); From 8f7b14c1af26f4c422cd402bf04abf89d6c3223a Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 14:48:59 +0100 Subject: [PATCH 09/30] display dynamic attribs --- scripts/localtree.js | 63 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/scripts/localtree.js b/scripts/localtree.js index 6e9da7e..0cc1a53 100644 --- a/scripts/localtree.js +++ b/scripts/localtree.js @@ -31,19 +31,20 @@ window.formatStaticValue = function(data, nobrk){ }; }; +var encd = function(v){ return $('
').text(v).html();}; + + window.createTreeFromObj = function(obj,autoexpand){ if(typeof(obj)!=='object' || null==obj) return false; var ul = $('
    '); - var keys = []; for(var i in obj) keys.push(i); if(typeof(obj.length)=='undefined') keys.sort(); - for(var i=0; i'+k+' '+formatStaticValue(d,1) +' ').appendTo(ul); + $('
    '+k+' '+formatStaticValue(d,1) +'
    ').appendTo(container); }else{ - var li = $('').appendTo(ul); + var li = $('').appendTo(container); var hdr = $('
    ').appendTo(li); var arrow = $('').appendTo(hdr); var key = $('' + k +'').appendTo(hdr) @@ -64,9 +65,57 @@ window.createTreeFromObj = function(obj,autoexpand){ arrow.click(function(){ if(!$('.dotstruct').is('.sel')) expand(); }); hdr.click(function(){ if($('.dotstruct').is('.sel')) expand(); }); if(!!autoexpand) expand(); - }; + }; + } + + function appendAttribGeneric(k, attr) { + var li = $('
  • ').appendTo(ul); - }(obj[keys[i]], keys[i])); + if(!attr[0]) { + var hdr = $('
    ').appendTo(li); + var key = $('' + k +'').appendTo(hdr) + var getCmd = $('<get>').appendTo(hdr); + + function showError(msg) { + var resp = $('
    ').appendTo(hdr); + resp.html(' W ' + encd(msg)); + } + + function getAttrib() { + if(!getCmd.is(':visible')) return; // already requested + getCmd.hide(); + + $.ajax({url:'./', type:'POST', dataType:'text', data:{'dynget':{objid:obj.objid, key:k}}, complete:function(r){ + if(r.status!==200) { + showError("Bad server response " + r.status + " " + r); + return; + } + + try{ var pa = JSON.parse(r.responseText); }catch(e){ + showError('Failed to parse response ('+e+')'); + return; + }; + + if(pa.error) { + showError(pa.error); + return; + } + + hdr.hide(); + appendAttrib(k, pa.cnt, li); + }}); + }; + getCmd.click(getAttrib); + hdr.click(getAttrib); + return; + } + + var d = attr[1]; + appendAttrib(k, d, li); + } + + for(var i=0; i Date: Thu, 27 Mar 2014 14:51:15 +0100 Subject: [PATCH 10/30] small fix --- debugger.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/debugger.js b/debugger.js index d99c757..64b35af 100644 --- a/debugger.js +++ b/debugger.js @@ -37,7 +37,7 @@ var jsencr = function(o){ if(!prop || !prop.get) value.attribs.push([true, o[key]]); else - value.attribs([false, undefined]); + value.attribs.push([false, undefined]); } return value; } From 82d7cd33a0fada7b4469e405d98bfa8e078a24c0 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 14:57:54 +0100 Subject: [PATCH 11/30] small fix --- scripts/console.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/console.js b/scripts/console.js index fab20ec..a4d9e54 100644 --- a/scripts/console.js +++ b/scripts/console.js @@ -42,7 +42,7 @@ $(document).ready(function(){ createTreeFromObj(r.cnt, $('.autoexpand').is('.sel')).appendTo(resp); break; default: - $(formatStaticValue(r.cnt.value,false)).appendTo(resp); + $(formatStaticValue(r.cnt,false)).appendTo(resp); break; }; focusLastMessage(); From ecdc638c20442ab5622f1ee384391b4d7a0130b7 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 15:19:57 +0100 Subject: [PATCH 12/30] fixes --- debugger.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/debugger.js b/debugger.js index 64b35af..8d533a6 100644 --- a/debugger.js +++ b/debugger.js @@ -46,8 +46,8 @@ var jsencr = function(o){ if(typeof(v)==='function') return fnprefix+v.toString(); if(typeof(v)!=='object' || v===null) return v; for(var i in e){ if(e[i]===v){ return "Circular"; }}; - if(util.isArray(v)) return v; e.push(v); + if(util.isArray(v)) return v; return objDescription(v); }); }; @@ -115,7 +115,8 @@ var dbg = { broadcastSSE: function(t, a){ clearTimeout(dbg.pendingBroadcast); - var data = { t:t, a:a }; + a = Array.prototype.slice.call(a, 0);; // make it an array + var data = [t,a]; dbg.queued.push(data); var sendFn = function(){ From eb4f1584eff1c4da39b4a65055aae4603ce7a82f Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 15:20:22 +0100 Subject: [PATCH 13/30] obj tree --- scripts/localtree.js | 81 +++++++++++++++++++++++++++----------------- 1 file changed, 49 insertions(+), 32 deletions(-) diff --git a/scripts/localtree.js b/scripts/localtree.js index 0cc1a53..ac3f344 100644 --- a/scripts/localtree.js +++ b/scripts/localtree.js @@ -33,41 +33,41 @@ window.formatStaticValue = function(data, nobrk){ var encd = function(v){ return $('
    ').text(v).html();}; +function appendAttrib(k, d, container, autoexpand) { + if(typeof(d)!=='object' || d===null){ + $('
    '+k+' '+formatStaticValue(d,1) +'
    ').appendTo(container); + }else{ + var li = $('').appendTo(container); + var hdr = $('
    ').appendTo(li); + var arrow = $('').appendTo(hdr); + var key = $('' + k +'').appendTo(hdr) + + var expand = function(){ + var tgt = li.find('>.object'); + if(tgt.length && tgt.is(':visible')){ + tgt.hide(); + arrow.removeClass('arrow-expanded').addClass('arrow-collapsed').html('►'); + }else{ + if(!tgt.length) tgt = createTreeFromObj(d).appendTo(li); + tgt.show(); + arrow.removeClass('arrow-collapsed').addClass('arrow-expanded').html('▼'); + }; + if(typeof(doResizeWin)=='function') doResizeWin(); + }; + + arrow.click(function(){ if(!$('.dotstruct').is('.sel')) expand(); }); + hdr.click(function(){ if($('.dotstruct').is('.sel')) expand(); }); + if(!!autoexpand) expand(); + }; +} + -window.createTreeFromObj = function(obj,autoexpand){ +window.createTreeFromDynObj = function(obj,autoexpand){ if(typeof(obj)!=='object' || null==obj) return false; var ul = $('
      '); - - function appendAttrib(k, d, container) { - if(typeof(d)!=='object' || d===null){ - $('
      '+k+' '+formatStaticValue(d,1) +'
      ').appendTo(container); - }else{ - var li = $('').appendTo(container); - var hdr = $('
      ').appendTo(li); - var arrow = $('').appendTo(hdr); - var key = $('' + k +'').appendTo(hdr) - - var expand = function(){ - var tgt = li.find('>.object'); - if(tgt.length && tgt.is(':visible')){ - tgt.hide(); - arrow.removeClass('arrow-expanded').addClass('arrow-collapsed').html('►'); - }else{ - if(!tgt.length) tgt = createTreeFromObj(d).appendTo(li); - tgt.show(); - arrow.removeClass('arrow-collapsed').addClass('arrow-expanded').html('▼'); - }; - if(typeof(doResizeWin)=='function') doResizeWin(); - }; - - arrow.click(function(){ if(!$('.dotstruct').is('.sel')) expand(); }); - hdr.click(function(){ if($('.dotstruct').is('.sel')) expand(); }); - if(!!autoexpand) expand(); - }; - } - + function appendAttribGeneric(k, attr) { var li = $('
    • ').appendTo(ul); @@ -102,7 +102,7 @@ window.createTreeFromObj = function(obj,autoexpand){ } hdr.hide(); - appendAttrib(k, pa.cnt, li); + appendAttrib(k, pa.cnt, li, autoexpand); }}); }; getCmd.click(getAttrib); @@ -111,7 +111,7 @@ window.createTreeFromObj = function(obj,autoexpand){ } var d = attr[1]; - appendAttrib(k, d, li); + appendAttrib(k, d, li, autoexpand); } for(var i=0; i'); + for(var key in obj) { + var li = $('
    • ').appendTo(ul); + appendAttrib(key, obj[key], li, autoexpand); + } + return ul; +} + +window.createTreeFromArray = window.createTreeFromRawObj; + +window.createTreeFromObj = function(obj, autoexpand) { + if(Array.isArray(obj)) return window.createTreeFromArray(obj, autoexpand); + return createTreeFromDynObj(obj, autoexpand); +} From cd67603af18e5913256178de531ca954a83ddbca Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 15:20:36 +0100 Subject: [PATCH 14/30] small fixes --- scripts/sse.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/sse.js b/scripts/sse.js index 765f0b8..749c5d2 100644 --- a/scripts/sse.js +++ b/scripts/sse.js @@ -32,17 +32,17 @@ $(document).ready(function(){ setTimeout(function(){ catch(e){ var q = []}; for(var j=0; j Date: Thu, 27 Mar 2014 15:42:59 +0100 Subject: [PATCH 15/30] fix --- scripts/localtree.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/localtree.js b/scripts/localtree.js index ac3f344..a316e7b 100644 --- a/scripts/localtree.js +++ b/scripts/localtree.js @@ -85,9 +85,9 @@ window.createTreeFromDynObj = function(obj,autoexpand){ if(!getCmd.is(':visible')) return; // already requested getCmd.hide(); - $.ajax({url:'./', type:'POST', dataType:'text', data:{'dynget':{objid:obj.objid, key:k}}, complete:function(r){ + $.ajax({url:'./', type:'POST', dataType:'text', data:{dynget:obj.objid, key:k}, complete:function(r){ if(r.status!==200) { - showError("Bad server response " + r.status + " " + r); + showError("Bad server response " + r.status); return; } From cc08e05e90dd54ddef57cedf1a5eccf0c083aaf3 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 15:43:05 +0100 Subject: [PATCH 16/30] fix --- debugger.js | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/debugger.js b/debugger.js index 8d533a6..efa2768 100644 --- a/debugger.js +++ b/debugger.js @@ -17,7 +17,7 @@ function objGetPropertyDescriptor(obj, key) { } } -var jsencr = function(o){ +var jsencr = function(o, rawRoot) { function objDescription(o) { var value = {}; var id = objCache.register(o); @@ -43,11 +43,12 @@ var jsencr = function(o){ } var e = []; return stringify(o, function(k,v){ - if(typeof(v)==='function') return fnprefix+v.toString(); + if(typeof(v)==='function') return "[Function]"; if(typeof(v)!=='object' || v===null) return v; for(var i in e){ if(e[i]===v){ return "Circular"; }}; e.push(v); if(util.isArray(v)) return v; + if(v === o && rawRoot) return v; return objDescription(v); }); }; @@ -66,7 +67,7 @@ function createObjCache() { }; function register(obj) { - if(obj in objToId) return objToId[obj]; + //if(obj in objToId) return objToId[obj]; // doesnt work _objCache_counter++; var newId = _objCache_counter; assert(!(newId in idToObj)); @@ -228,7 +229,7 @@ var dbg = { typeof(r.cnt); }catch(e){ r.error=e.toString(); } - s.end(jsencr(r)); + s.end(jsencr(r, true)); } else if(typeof(post.getsug)==='string'){ try{ var r = jsencr(dbg.getsug(JSON.parse(post.getsug))); } @@ -240,14 +241,16 @@ var dbg = { clear(); s.end(); } else if(post.dynget) { + var objid = post.dynget; + var key = post.key; var r = {error:false}; try{ - var obj = objCache.get(post.dynget.objid); - r.cnt = obj[post.dynget.key]; + var obj = objCache.get(objid); + r.cnt = obj[key]; }catch(e){ r.error=e.toString(); } - s.end(jsencr(r)); + s.end(jsencr(r, true)); }else{ return dbg.serve500(s,'Command was not found'); } From baadf725ce0bc15144749d625e10e61fdf62a89f Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 15:56:53 +0100 Subject: [PATCH 17/30] fix clearConsole --- debugger.js | 2 +- scripts/console.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/debugger.js b/debugger.js index efa2768..8ca824c 100644 --- a/debugger.js +++ b/debugger.js @@ -237,7 +237,7 @@ var dbg = { s.writeHead(200, {'Content-type': dbg.mimes['txt'], 'Content-length': r.length}); s.end(r); - } else if(post == "clear") { + } else if(post.clear) { clear(); s.end(); } else if(post.dynget) { diff --git a/scripts/console.js b/scripts/console.js index a4d9e54..6202bc2 100644 --- a/scripts/console.js +++ b/scripts/console.js @@ -15,7 +15,7 @@ $(document).ready(function(){ var decd = function(v){ return $('
      ').html(v).text();}; window.clearConsole = function() { - $.ajax({url:'./', type:'POST', dataType:'text', data:'clear', complete:function(r) { + $.ajax({url:'./', type:'POST', dataType:'text', data:{'clear':true}, complete:function(r) { if(r.status!==200) return showAnError('Bad response from server ('+r.status+')'); c.val(''); From 8ab3d657c83896480f54b9efccef85f38f4987c8 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 16:13:43 +0100 Subject: [PATCH 18/30] print full error call stack --- debugger.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/debugger.js b/debugger.js index 8ca824c..51e26f0 100644 --- a/debugger.js +++ b/debugger.js @@ -227,7 +227,7 @@ var dbg = { r.type = (typeof(r.cnt)==='object' && r.cnt!==null) ? get_constr(r.cnt) : typeof(r.cnt); - }catch(e){ r.error=e.toString(); } + }catch(e){ r.error= "" + (e.stack || e); } s.end(jsencr(r, true)); } else if(typeof(post.getsug)==='string'){ @@ -248,7 +248,7 @@ var dbg = { try{ var obj = objCache.get(objid); r.cnt = obj[key]; - }catch(e){ r.error=e.toString(); } + }catch(e){ r.error= "" + (e.stack || e); } s.end(jsencr(r, true)); }else{ From 167fde647a6e87a8ff29d1f4c453ff47c6c69751 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 16:13:54 +0100 Subject: [PATCH 19/30] better encodeHTML --- scripts/localtree.js | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/localtree.js b/scripts/localtree.js index a316e7b..4acd657 100644 --- a/scripts/localtree.js +++ b/scripts/localtree.js @@ -31,7 +31,13 @@ window.formatStaticValue = function(data, nobrk){ }; }; -var encd = function(v){ return $('
      ').text(v).html();}; +function encodeHTML(s) { + s = s.replace(/&/g, '&'); + s = s.replace(/'); + return s; +} function appendAttrib(k, d, container, autoexpand) { if(typeof(d)!=='object' || d===null){ @@ -78,7 +84,7 @@ window.createTreeFromDynObj = function(obj,autoexpand){ function showError(msg) { var resp = $('
      ').appendTo(hdr); - resp.html(' W ' + encd(msg)); + resp.html(' W ' + encodeHTML(msg)); } function getAttrib() { From e5ba2623bfbb4dcc553f27157fbceb4c3f1cd2f6 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 16:28:49 +0100 Subject: [PATCH 20/30] nicer display for function --- debugger.js | 11 ++++++++++- scripts/localtree.js | 7 ++++++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/debugger.js b/debugger.js index 51e26f0..d3371cc 100644 --- a/debugger.js +++ b/debugger.js @@ -41,9 +41,18 @@ var jsencr = function(o, rawRoot) { } return value; } + function funcDesc(f) { + var value = {}; + value.type = "function"; + value.typename = "Function"; + value.name = f.name; + if(value.name) value.str = "[Function: " + f.name + "]"; + else value.str = "[Function]"; + return value; + } var e = []; return stringify(o, function(k,v){ - if(typeof(v)==='function') return "[Function]"; + if(typeof(v)==='function') return funcDesc(o); if(typeof(v)!=='object' || v===null) return v; for(var i in e){ if(e[i]===v){ return "Circular"; }}; e.push(v); diff --git a/scripts/localtree.js b/scripts/localtree.js index 4acd657..088463f 100644 --- a/scripts/localtree.js +++ b/scripts/localtree.js @@ -42,6 +42,8 @@ function encodeHTML(s) { function appendAttrib(k, d, container, autoexpand) { if(typeof(d)!=='object' || d===null){ $('
      '+k+' '+formatStaticValue(d,1) +'
      ').appendTo(container); + }else if(d.type == "function"){ + $('
      '+k+' '+encodeHTML(d.str)+'
      ').appendTo(container); }else{ var li = $('').appendTo(container); var hdr = $('
      ').appendTo(li); @@ -71,7 +73,10 @@ function appendAttrib(k, d, container, autoexpand) { window.createTreeFromDynObj = function(obj,autoexpand){ if(typeof(obj)!=='object' || null==obj) return false; - + + if(obj.type == "function") + return ''+encodeHTML(obj.str)+''; + var ul = $('
        '); function appendAttribGeneric(k, attr) { From 396d0143d9b38db7369b523a0d39ea87408996fc Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 16:40:14 +0100 Subject: [PATCH 21/30] html optimizations --- scripts/localtree.js | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/scripts/localtree.js b/scripts/localtree.js index 088463f..b7a3539 100644 --- a/scripts/localtree.js +++ b/scripts/localtree.js @@ -41,14 +41,15 @@ function encodeHTML(s) { function appendAttrib(k, d, container, autoexpand) { if(typeof(d)!=='object' || d===null){ - $('
        '+k+' '+formatStaticValue(d,1) +'
        ').appendTo(container); + $('
        '+k+''+formatStaticValue(d,1) +'
        ').appendTo(container); }else if(d.type == "function"){ - $('
        '+k+' '+encodeHTML(d.str)+'
        ').appendTo(container); + $('
        '+k+''+encodeHTML(d.str)+'
        ').appendTo(container); }else{ var li = $('').appendTo(container); var hdr = $('
        ').appendTo(li); var arrow = $('').appendTo(hdr); - var key = $('' + k +'').appendTo(hdr) + var key = $('' + k +'').appendTo(hdr); + var desc = $('' + encodeHTML(d.str) + '').appendTo(hdr); var expand = function(){ var tgt = li.find('>.object'); @@ -113,7 +114,7 @@ window.createTreeFromDynObj = function(obj,autoexpand){ } hdr.hide(); - appendAttrib(k, pa.cnt, li, autoexpand); + appendAttrib(k, pa.cnt, li, true); }}); }; getCmd.click(getAttrib); From be5fcacdc1f35b4a3665026cd6b541c1cec55a63 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 18:18:54 +0100 Subject: [PATCH 22/30] use Map/WeakMap and better random obj ids --- debugger.js | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/debugger.js b/debugger.js index d3371cc..ea2d14f 100644 --- a/debugger.js +++ b/debugger.js @@ -64,11 +64,13 @@ var jsencr = function(o, rawRoot) { var assert = require("assert"); -var _objCache_counter = 0; +function getRandomId() { + return Math.floor((new Date()).valueOf() + new Date(2000,0,0).valueOf()*Math.random()); +} function createObjCache() { - var objToId = {}; - var idToObj = {}; + var objToId = new WeakMap(); + var idToObj = new Map(); return { register: register, @@ -76,17 +78,19 @@ function createObjCache() { }; function register(obj) { - //if(obj in objToId) return objToId[obj]; // doesnt work - _objCache_counter++; - var newId = _objCache_counter; - assert(!(newId in idToObj)); - objToId[obj] = newId; - idToObj[newId] = obj; + if(objToId.has(obj)) return objToId.get(obj); + var newId; + while(true) { + newId = getRandomId(); + if(!idToObj.has(newId)) break; + } + objToId.set(obj, newId); + idToObj.set(newId, obj); return newId; } function get(id) { - return idToObj[id]; + return idToObj.get(Number(id)); } } From 7ec8e7133b6c923cb642be7257265c4431b6c377 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 18:25:56 +0100 Subject: [PATCH 23/30] small fix --- scripts/console.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/console.js b/scripts/console.js index 6202bc2..c7c0255 100644 --- a/scripts/console.js +++ b/scripts/console.js @@ -35,9 +35,10 @@ $(document).ready(function(){ window.showAResponse = function(r){ var resp = $('
        ').appendTo(vw); if(typeof(r.fnprefix)==='string') window.fnprefix = r.fnprefix; + var tpo = typeof(r.cnt); if(r.cnt===null) tpo = 'null'; - switch(typeof r.cnt){ + switch(tpo){ case 'object': createTreeFromObj(r.cnt, $('.autoexpand').is('.sel')).appendTo(resp); break; From 53b7c01967ff33d1bfdd1b2610005a22dce95a3f Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 18:28:37 +0100 Subject: [PATCH 24/30] small fix --- scripts/localtree.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/localtree.js b/scripts/localtree.js index b7a3539..398fe44 100644 --- a/scripts/localtree.js +++ b/scripts/localtree.js @@ -5,7 +5,6 @@ window.formatStaticValue = function(data, nobrk){ var encd = function(v){ return $('
        ').text(v).html();}; var fnprefix = typeof(window.fnprefix)=='string' ? window.fnprefix : '{'+(new Date().getTime()) + '#!@'; - if(type==='object') return false; if(data===null) type='null'; if(type==='string' && typeof fnprefix !== 'undefined' && data.indexOf(fnprefix+'function')===0 && data.lastIndexOf(fnprefix+'function')===0){ type='function'; From 7d061be4c3ce978a3b05ce4d51907b93fdff335b Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Thu, 27 Mar 2014 18:39:49 +0100 Subject: [PATCH 25/30] better encodeHTML --- scripts/console.js | 12 +++++++++++- scripts/localtree.js | 8 -------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/scripts/console.js b/scripts/console.js index c7c0255..4111cf0 100644 --- a/scripts/console.js +++ b/scripts/console.js @@ -14,6 +14,16 @@ $(document).ready(function(){ var encd = function(v){ return $('
        ').text(v).html();}; var decd = function(v){ return $('
        ').html(v).text();}; + window.encodeHTML = function(s) { + s = s.replace(/&/g, '&'); + s = s.replace(/'); + s = s.replace(/ /g, ' '); + s = s.replace(/\t/g, ' '); // not exactly... + return s; + } + window.clearConsole = function() { $.ajax({url:'./', type:'POST', dataType:'text', data:{'clear':true}, complete:function(r) { if(r.status!==200) return showAnError('Bad response from server ('+r.status+')'); @@ -27,7 +37,7 @@ $(document).ready(function(){ window.showAnError = function(err, type){ if(typeof(type)!=='string') type='error'; var resp = $('
        ').appendTo(vw); - resp.html(' W '+encd(err)); + resp.html(' W '+encodeHTML(err)); focusLastMessage(); }; diff --git a/scripts/localtree.js b/scripts/localtree.js index 398fe44..c69c6c5 100644 --- a/scripts/localtree.js +++ b/scripts/localtree.js @@ -30,14 +30,6 @@ window.formatStaticValue = function(data, nobrk){ }; }; -function encodeHTML(s) { - s = s.replace(/&/g, '&'); - s = s.replace(/'); - return s; -} - function appendAttrib(k, d, container, autoexpand) { if(typeof(d)!=='object' || d===null){ $('
        '+k+''+formatStaticValue(d,1) +'
        ').appendTo(container); From 4bf8eecd63006e99331d1f676eda45c5807d4869 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Fri, 28 Mar 2014 07:50:13 +0100 Subject: [PATCH 26/30] nicer --- scripts/localtree.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/localtree.js b/scripts/localtree.js index c69c6c5..8a78b55 100644 --- a/scripts/localtree.js +++ b/scripts/localtree.js @@ -32,7 +32,7 @@ window.formatStaticValue = function(data, nobrk){ function appendAttrib(k, d, container, autoexpand) { if(typeof(d)!=='object' || d===null){ - $('
        '+k+''+formatStaticValue(d,1) +'
        ').appendTo(container); + $('
        '+k+''+formatStaticValue(d,false) +'
        ').appendTo(container); }else if(d.type == "function"){ $('
        '+k+''+encodeHTML(d.str)+'
        ').appendTo(container); }else{ From 445281a05e535dc7563d6f3e2601bae58e5173f6 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Fri, 28 Mar 2014 15:54:38 +0100 Subject: [PATCH 27/30] better. avoid the exception --- debugger.js | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/debugger.js b/debugger.js index ea2d14f..06c2a6d 100644 --- a/debugger.js +++ b/debugger.js @@ -260,8 +260,13 @@ var dbg = { try{ var obj = objCache.get(objid); - r.cnt = obj[key]; - }catch(e){ r.error= "" + (e.stack || e); } + if(!obj) + r.error = "Object not found. Probably we have restarted the session."; + else + r.cnt = obj[key]; + } catch(e) { + r.error= "" + (e.stack || e); + } s.end(jsencr(r, true)); }else{ From 7647423293f693e6005cff3ac9397ba410bc3dd2 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Tue, 1 Apr 2014 17:41:14 +0200 Subject: [PATCH 28/30] fix for array --- scripts/localtree.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scripts/localtree.js b/scripts/localtree.js index 8a78b55..a190ab1 100644 --- a/scripts/localtree.js +++ b/scripts/localtree.js @@ -40,7 +40,10 @@ function appendAttrib(k, d, container, autoexpand) { var hdr = $('
        ').appendTo(li); var arrow = $('').appendTo(hdr); var key = $('' + k +'').appendTo(hdr); - var desc = $('' + encodeHTML(d.str) + '').appendTo(hdr); + var descStr = d.str; + if(!descStr && d.constructor) descStr = "[" + d.constructor.name + "]"; + if(!descStr) descStr = ""; + var desc = $('' + encodeHTML(descStr) + '').appendTo(hdr); var expand = function(){ var tgt = li.find('>.object'); From 5a1f4d53b7994abc77f135df95b420b1fea941ed Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Tue, 1 Apr 2014 18:41:16 +0200 Subject: [PATCH 29/30] re-get support --- scripts/localtree.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/scripts/localtree.js b/scripts/localtree.js index a190ab1..371fe3c 100644 --- a/scripts/localtree.js +++ b/scripts/localtree.js @@ -34,7 +34,7 @@ function appendAttrib(k, d, container, autoexpand) { if(typeof(d)!=='object' || d===null){ $('
        '+k+''+formatStaticValue(d,false) +'
        ').appendTo(container); }else if(d.type == "function"){ - $('
        '+k+''+encodeHTML(d.str)+'
        ').appendTo(container); + $('
        '+k+''+encodeHTML(d.str)+'
        ').appendTo(container); }else{ var li = $('').appendTo(container); var hdr = $('
        ').appendTo(li); @@ -43,7 +43,7 @@ function appendAttrib(k, d, container, autoexpand) { var descStr = d.str; if(!descStr && d.constructor) descStr = "[" + d.constructor.name + "]"; if(!descStr) descStr = ""; - var desc = $('' + encodeHTML(descStr) + '').appendTo(hdr); + var desc = $('' + encodeHTML(descStr) + ' ').appendTo(hdr); var expand = function(){ var tgt = li.find('>.object'); @@ -88,10 +88,12 @@ window.createTreeFromDynObj = function(obj,autoexpand){ } function getAttrib() { - if(!getCmd.is(':visible')) return; // already requested - getCmd.hide(); + getCmd.remove(); + var waitSpan = $("...").appendTo(hdr); $.ajax({url:'./', type:'POST', dataType:'text', data:{dynget:obj.objid, key:k}, complete:function(r){ + waitSpan.remove(); // remove old + if(r.status!==200) { showError("Bad server response " + r.status); return; @@ -107,8 +109,15 @@ window.createTreeFromDynObj = function(obj,autoexpand){ return; } - hdr.hide(); + hdr.remove(); appendAttrib(k, pa.cnt, li, true); + + // re-add get-cmd to new header + hdr = li.find(">div")[0]; + tgt = li.find(".header")[0]; + getCmd.text(""); + getCmd.appendTo(tgt); + getCmd.click(getAttrib); }}); }; getCmd.click(getAttrib); From 495ded1296cf295fdcda3e60ad444b18067f3d17 Mon Sep 17 00:00:00 2001 From: Albert Zeyer Date: Sat, 5 Apr 2014 19:02:42 +0200 Subject: [PATCH 30/30] better str repr --- scripts/localtree.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/localtree.js b/scripts/localtree.js index 371fe3c..5ca0d01 100644 --- a/scripts/localtree.js +++ b/scripts/localtree.js @@ -20,8 +20,7 @@ window.formatStaticValue = function(data, nobrk){ return ''+(typeof(data)!=='boolean'?data:(!!data?'true':'false'))+''; case 'string': case 'function': - var d = encd(data.toString()); - if(!!!nobrk) d = d.replace(/\r\n/gmi,"
        ").replace(/\n/gmi,"
        ").replace(/\t/gmi,tabSpaces); + var d = encodeHTML(data.toString()); var r = '' + (d)+''; return (type=='string' ? '"'+r+'"' : r);