Browse Source

- Better error handling taking advantage of message sends
- MethodContext & thisContext are now working (temps still missing)
- unhandled errors now log a stacktrace
- Rendering widgets do not add an extra surrounding div anymore

Nicolas Petton 13 years ago
parent
commit
2737561109
15 changed files with 984 additions and 192 deletions
  1. 70 10
      js/Canvas.js
  2. 12 12
      js/Compiler.js
  3. 1 1
      js/Examples.js
  4. 168 38
      js/IDE.js
  5. 47 18
      js/JQuery.js
  6. 286 4
      js/Kernel.js
  7. 16 16
      js/Parser.js
  8. 27 11
      js/SUnit.js
  9. 103 16
      js/boot.js
  10. 26 3
      st/Canvas.st
  11. 3 2
      st/Compiler.st
  12. 86 37
      st/IDE.st
  13. 24 15
      st/JQuery.st
  14. 103 2
      st/Kernel.st
  15. 12 7
      st/SUnit.st

+ 70 - 10
js/Canvas.js

@@ -265,11 +265,11 @@ category: 'initialization',
 fn: function (){
 var self=this;
 smalltalk.send(self, "_initialize", [], smalltalk.Object);
-self['@root']=smalltalk.send(smalltalk.TagBrush, "_fromString_canvas_", ["div", self]);
+smalltalk.send(self['@root'], "_ifNil_", [(function(){return self['@root']=smalltalk.send(smalltalk.TagBrush, "_fromString_canvas_", ["div", self]);})]);
 return self;},
-source: unescape('initialize%0A%20%20%20%20super%20initialize.%0A%20%20%20%20root%20%3A%3D%20TagBrush%20fromString%3A%20%27div%27%20canvas%3A%20self'),
-messageSends: ["initialize", "fromString:canvas:"],
-referencedClasses: [smalltalk.TagBrush]
+source: unescape('initialize%0A%20%20%20%20super%20initialize.%0A%20%20%20%20root%20ifNil%3A%20%5Broot%20%3A%3D%20TagBrush%20fromString%3A%20%27div%27%20canvas%3A%20self%5D'),
+messageSends: ["initialize", "ifNil:", "fromString:canvas:"],
+referencedClasses: [smalltalk.nil]
 }),
 smalltalk.HTMLCanvas);
 
@@ -299,7 +299,7 @@ return smalltalk.send(smalltalk.TagBrush, "_fromString_canvas_", [aString, self]
 return self;},
 source: unescape('newTag%3A%20aString%0A%20%20%20%20%5ETagBrush%20fromString%3A%20aString%20canvas%3A%20self'),
 messageSends: ["fromString:canvas:"],
-referencedClasses: [smalltalk.TagBrush]
+referencedClasses: [smalltalk.nil]
 }),
 smalltalk.HTMLCanvas);
 
@@ -693,6 +693,36 @@ referencedClasses: []
 }),
 smalltalk.HTMLCanvas);
 
+smalltalk.addMethod(
+'_initializeFromJQuery_',
+smalltalk.method({
+selector: 'initializeFromJQuery:',
+category: 'initialization',
+fn: function (aJQuery){
+var self=this;
+self['@root']=smalltalk.send(smalltalk.TagBrush, "_fromJQuery_canvas_", [aJQuery, self]);
+return self;},
+source: unescape('initializeFromJQuery%3A%20aJQuery%0A%20%20%20%20root%20%3A%3D%20TagBrush%20fromJQuery%3A%20aJQuery%20canvas%3A%20self'),
+messageSends: ["fromJQuery:canvas:"],
+referencedClasses: [smalltalk.nil]
+}),
+smalltalk.HTMLCanvas);
+
+
+smalltalk.addMethod(
+'_onJQuery_',
+smalltalk.method({
+selector: 'onJQuery:',
+category: 'instance creation',
+fn: function (aJQuery){
+var self=this;
+return (function($rec){smalltalk.send($rec, "_initializeFromJQuery_", [aJQuery]);smalltalk.send($rec, "_initialize", []);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_basicNew", []));
+return self;},
+source: unescape('onJQuery%3A%20aJQuery%0A%09%5Eself%20basicNew%0A%09%09initializeFromJQuery%3A%20aJQuery%3B%0A%09%09initialize%3B%0A%09%09yourself'),
+messageSends: ["initializeFromJQuery:", "initialize", "yourself", "basicNew"],
+referencedClasses: []
+}),
+smalltalk.HTMLCanvas.klass);
 
 
 smalltalk.addClass('TagBrush', smalltalk.Object, ['canvas', 'element'], 'Canvas');
@@ -1138,6 +1168,22 @@ referencedClasses: []
 }),
 smalltalk.TagBrush);
 
+smalltalk.addMethod(
+'_initializeFromJQuery_canvas_',
+smalltalk.method({
+selector: 'initializeFromJQuery:canvas:',
+category: 'initialization',
+fn: function (aJQuery, aCanvas){
+var self=this;
+self['@element']=smalltalk.send(smalltalk.send(aJQuery, "_jquery", []), "_get_", [(0)]);
+self['@canvas']=aCanvas;
+return self;},
+source: unescape('initializeFromJQuery%3A%20aJQuery%20canvas%3A%20aCanvas%0A%20%20%20%20element%20%3A%3D%20aJQuery%20jquery%20get%3A%200.%0A%20%20%20%20canvas%20%3A%3D%20aCanvas'),
+messageSends: ["get:", "jquery"],
+referencedClasses: []
+}),
+smalltalk.TagBrush);
+
 
 smalltalk.addMethod(
 '_fromString_canvas_',
@@ -1154,6 +1200,21 @@ referencedClasses: []
 }),
 smalltalk.TagBrush.klass);
 
+smalltalk.addMethod(
+'_fromJQuery_canvas_',
+smalltalk.method({
+selector: 'fromJQuery:canvas:',
+category: 'instance creation',
+fn: function (aJQuery, aCanvas){
+var self=this;
+return (function($rec){smalltalk.send($rec, "_initializeFromJQuery_canvas_", [aJQuery, aCanvas]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
+return self;},
+source: unescape('fromJQuery%3A%20aJQuery%20canvas%3A%20aCanvas%0A%20%20%20%20%5Eself%20new%0A%09initializeFromJQuery%3A%20aJQuery%20canvas%3A%20aCanvas%3B%0A%09yourself'),
+messageSends: ["initializeFromJQuery:canvas:", "yourself", "new"],
+referencedClasses: []
+}),
+smalltalk.TagBrush.klass);
+
 
 smalltalk.addClass('Widget', smalltalk.Object, ['root'], 'Canvas');
 smalltalk.addMethod(
@@ -1193,12 +1254,11 @@ selector: 'appendToJQuery:',
 category: 'adding',
 fn: function (aJQuery){
 var self=this;
-smalltalk.send(self, "_render", []);
-smalltalk.send(aJQuery, "_append_", [smalltalk.send(smalltalk.send(self, "_root", []), "_asJQuery", [])]);
+smalltalk.send(self, "_renderOn_", [smalltalk.send(smalltalk.HTMLCanvas, "_onJQuery_", [aJQuery])]);
 return self;},
-source: unescape('appendToJQuery%3A%20aJQuery%0A%20%20%20%20self%20render.%0A%20%20%20%20aJQuery%20append%3A%20self%20root%20asJQuery'),
-messageSends: ["render", "append:", "asJQuery", "root"],
-referencedClasses: []
+source: unescape('appendToJQuery%3A%20aJQuery%0A%20%20%20self%20renderOn%3A%20%28HTMLCanvas%20onJQuery%3A%20aJQuery%29'),
+messageSends: ["renderOn:", "onJQuery:"],
+referencedClasses: [smalltalk.HTMLCanvas]
 }),
 smalltalk.Widget);
 

+ 12 - 12
js/Compiler.js

@@ -288,7 +288,7 @@ return (function($rec){smalltalk.send($rec, "_receiver_", [smalltalk.send(self,
 return self;},
 source: unescape('cascadeNodeWithMessages%3A%20aCollection%0A%09%7C%20first%20%7C%0A%09first%20%3A%3D%20SendNode%20new%0A%09%20%20%20%20selector%3A%20self%20selector%3B%0A%09%20%20%20%20arguments%3A%20self%20arguments%3B%0A%09%20%20%20%20yourself.%0A%09%5ECascadeNode%20new%0A%09%20%20%20%20receiver%3A%20self%20receiver%3B%0A%09%20%20%20%20nodes%3A%20%28Array%20with%3A%20first%29%2C%20aCollection%3B%0A%09%20%20%20%20yourself'),
 messageSends: ["selector:", "selector", "arguments:", "arguments", "yourself", "new", "receiver:", "receiver", "nodes:", unescape("%2C"), "with:"],
-referencedClasses: [smalltalk.SendNode,smalltalk.Array,smalltalk.nil]
+referencedClasses: [smalltalk.SendNode,smalltalk.Array,smalltalk.CascadeNode]
 }),
 smalltalk.SendNode);
 
@@ -525,7 +525,7 @@ return (function($rec){smalltalk.send($rec, "_nodes_", [smalltalk.send(self, "_n
 return self;},
 source: unescape('asBlockSequenceNode%0A%09%5EBlockSequenceNode%20new%0A%09%20%20%20%20nodes%3A%20self%20nodes%3B%0A%09%20%20%20%20temps%3A%20self%20temps%3B%0A%09%20%20%20%20yourself'),
 messageSends: ["nodes:", "nodes", "temps:", "temps", "yourself", "new"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.BlockSequenceNode]
 }),
 smalltalk.SequenceNode);
 
@@ -1005,7 +1005,7 @@ return smalltalk.send(smalltalk.send(smalltalk.DoIt, "_new", []), "_doIt", []);
 return self;},
 source: unescape('loadExpression%3A%20aString%0A%09DoIt%20addCompiledMethod%3A%20%28self%20eval%3A%20%28self%20compileExpression%3A%20aString%29%29.%0A%09%5EDoIt%20new%20doIt'),
 messageSends: ["addCompiledMethod:", "eval:", "compileExpression:", "doIt", "new"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.DoIt]
 }),
 smalltalk.Compiler);
 
@@ -1055,7 +1055,7 @@ return smalltalk.send(self, "_compileNode_", [smalltalk.send(self, "_parseExpres
 return self;},
 source: unescape('compileExpression%3A%20aString%0A%09self%20currentClass%3A%20DoIt.%0A%09%5Eself%20compileNode%3A%20%28self%20parseExpression%3A%20aString%29'),
 messageSends: ["currentClass:", "compileNode:", "parseExpression:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.DoIt]
 }),
 smalltalk.Compiler);
 
@@ -1478,11 +1478,11 @@ selector: 'recompileAll',
 category: 'compiling',
 fn: function (){
 var self=this;
-smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.Smalltalk, "_current", []), "_classes", []), "_do_", [(function(each){return smalltalk.send(self, "_recompile_", [each]);})]);
+smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.Smalltalk, "_current", []), "_classes", []), "_do_", [(function(each){(function($rec){smalltalk.send($rec, "_show_", [each]);return smalltalk.send($rec, "_cr", []);})(smalltalk.Transcript);return smalltalk.send((function(){return smalltalk.send(self, "_recompile_", [each]);}), "_valueWithTimeout_", [(100)]);})]);
 return self;},
-source: unescape('recompileAll%0A%09Smalltalk%20current%20classes%20do%3A%20%5B%3Aeach%20%7C%0A%09%09self%20recompile%3A%20each%5D'),
-messageSends: ["do:", "classes", "current", "recompile:"],
-referencedClasses: [smalltalk.Smalltalk]
+source: unescape('recompileAll%0A%09Smalltalk%20current%20classes%20do%3A%20%5B%3Aeach%20%7C%0A%09%09Transcript%20show%3A%20each%3B%20cr.%0A%09%09%5Bself%20recompile%3A%20each%5D%20valueWithTimeout%3A%20100%5D'),
+messageSends: ["do:", "classes", "current", "show:", "cr", "valueWithTimeout:", "recompile:"],
+referencedClasses: [smalltalk.Smalltalk,smalltalk.Transcript]
 }),
 smalltalk.Compiler);
 
@@ -1573,11 +1573,11 @@ selector: 'doIt',
 category: '',
 fn: function (){
 var self=this;
-return smalltalk.send((function(){return self["@"+'foo'];}), "_value", []);
+return smalltalk.send((function(){return smalltalk.send(smalltalk.send(smalltalk.Compiler, "_new", []), "_recompileAll", []);}), "_value", []);
 return self;},
-source: unescape('doIt%20%5E%5B%3Cself%5B%22@%22+%27foo%27%5D%3E%5D%20value'),
-messageSends: ["value"],
-referencedClasses: []
+source: unescape('doIt%20%5E%5BCompiler%20new%20recompileAll%5D%20value'),
+messageSends: ["value", "recompileAll", "new"],
+referencedClasses: [smalltalk.Compiler]
 }),
 smalltalk.DoIt);
 

+ 1 - 1
js/Examples.js

@@ -271,7 +271,7 @@ self['@movingPiece']=smalltalk.send(smalltalk.TetrisPiece, "_atRandom", []);
 return self;},
 source: unescape('newPiece%0A%09movingPiece%20%3A%3D%20TetrisPiece%20atRandom'),
 messageSends: ["atRandom"],
-referencedClasses: []
+referencedClasses: [smalltalk.TetrisPiece]
 }),
 smalltalk.Tetris);
 

+ 168 - 38
js/IDE.js

@@ -1,4 +1,4 @@
-smalltalk.addClass('TabManager', smalltalk.Widget, ['selectedTab', 'tabs', 'opened'], 'IDE');
+smalltalk.addClass('TabManager', smalltalk.Widget, ['selectedTab', 'tabs', 'opened', 'ul'], 'IDE');
 smalltalk.addMethod(
 '_tabs',
 smalltalk.method({
@@ -115,10 +115,10 @@ selector: 'open',
 category: 'actions',
 fn: function (){
 var self=this;
-smalltalk.send(self['@opened'], "_ifFalse_", [(function(){smalltalk.send(smalltalk.send(smalltalk.send(self, "_root", []), "_asJQuery", []), "_show", []);smalltalk.send(smalltalk.send("body", "_asJQuery", []), "_addClass_", ["jtalkBody"]);smalltalk.send(smalltalk.send(unescape("%23jtalk"), "_asJQuery", []), "_show", []);smalltalk.send(self, "_updateBodyMargin", []);smalltalk.send(smalltalk.send(smalltalk.send(self['@selectedTab'], "_root", []), "_asJQuery", []), "_show", []);return self['@opened']=true;})]);
+smalltalk.send(self['@opened'], "_ifFalse_", [(function(){smalltalk.send(smalltalk.send("body", "_asJQuery", []), "_addClass_", ["jtalkBody"]);smalltalk.send(smalltalk.send(unescape("%23jtalk"), "_asJQuery", []), "_show", []);smalltalk.send(smalltalk.send(self['@ul'], "_asJQuery", []), "_show", []);smalltalk.send(self, "_updateBodyMargin", []);smalltalk.send(self['@selectedTab'], "_show", []);return self['@opened']=true;})]);
 return self;},
-source: unescape('open%0A%20%20%20%20opened%20ifFalse%3A%20%5B%0A%09self%20root%20asJQuery%20show.%0A%09%27body%27%20asJQuery%20addClass%3A%20%27jtalkBody%27.%0A%09%27%23jtalk%27%20asJQuery%20show.%0A%09self%20updateBodyMargin.%0A%09selectedTab%20root%20asJQuery%20show.%0A%09opened%20%3A%3D%20true%5D'),
-messageSends: ["ifFalse:", "show", "asJQuery", "root", "addClass:", "updateBodyMargin"],
+source: unescape('open%0A%20%20%20%20opened%20ifFalse%3A%20%5B%0A%09%27body%27%20asJQuery%20addClass%3A%20%27jtalkBody%27.%0A%09%27%23jtalk%27%20asJQuery%20show.%0A%09ul%20asJQuery%20show.%0A%09self%20updateBodyMargin.%0A%09selectedTab%20show.%0A%09opened%20%3A%3D%20true%5D'),
+messageSends: ["ifFalse:", "addClass:", "asJQuery", "show", "updateBodyMargin"],
 referencedClasses: []
 }),
 smalltalk.TabManager);
@@ -130,10 +130,10 @@ selector: 'close',
 category: 'actions',
 fn: function (){
 var self=this;
-smalltalk.send(self['@opened'], "_ifTrue_", [(function(){smalltalk.send(smalltalk.send(smalltalk.send(self, "_root", []), "_asJQuery", []), "_hide", []);smalltalk.send(smalltalk.send(unescape("%23jtalk"), "_asJQuery", []), "_hide", []);smalltalk.send(self, "_removeBodyMargin", []);smalltalk.send(smalltalk.send("body", "_asJQuery", []), "_removeClass_", ["jtalkBody"]);return self['@opened']=false;})]);
+smalltalk.send(self['@opened'], "_ifTrue_", [(function(){smalltalk.send(smalltalk.send(unescape("%23jtalk"), "_asJQuery", []), "_hide", []);smalltalk.send(smalltalk.send(self['@ul'], "_asJQuery", []), "_hide", []);smalltalk.send(self['@selectedTab'], "_hide", []);smalltalk.send(self, "_removeBodyMargin", []);smalltalk.send(smalltalk.send("body", "_asJQuery", []), "_removeClass_", ["jtalkBody"]);return self['@opened']=false;})]);
 return self;},
-source: unescape('close%0A%20%20%20%20opened%20ifTrue%3A%20%5B%0A%09self%20root%20asJQuery%20hide.%0A%09%27%23jtalk%27%20asJQuery%20hide.%0A%09self%20removeBodyMargin.%0A%09%27body%27%20asJQuery%20removeClass%3A%20%27jtalkBody%27.%0A%09opened%20%3A%3D%20false%5D'),
-messageSends: ["ifTrue:", "hide", "asJQuery", "root", "removeBodyMargin", "removeClass:"],
+source: unescape('close%0A%20%20%20%20opened%20ifTrue%3A%20%5B%0A%09%27%23jtalk%27%20asJQuery%20hide.%0A%09ul%20asJQuery%20hide.%0A%09selectedTab%20hide.%0A%09self%20removeBodyMargin.%0A%09%27body%27%20asJQuery%20removeClass%3A%20%27jtalkBody%27.%0A%09opened%20%3A%3D%20false%5D'),
+messageSends: ["ifTrue:", "hide", "asJQuery", "removeBodyMargin", "removeClass:"],
 referencedClasses: []
 }),
 smalltalk.TabManager);
@@ -149,7 +149,7 @@ smalltalk.send(smalltalk.Browser, "_open", []);
 return self;},
 source: unescape('newBrowserTab%0A%20%20%20%20Browser%20open'),
 messageSends: ["open"],
-referencedClasses: []
+referencedClasses: [smalltalk.nil]
 }),
 smalltalk.TabManager);
 
@@ -162,12 +162,12 @@ fn: function (aWidget){
 var self=this;
 smalltalk.send(self, "_open", []);
 self['@selectedTab']=aWidget;
-smalltalk.send(smalltalk.send(self, "_tabs", []), "_do_", [(function(each){return smalltalk.send(smalltalk.send(smalltalk.send(each, "_root", []), "_asJQuery", []), "_hide", []);})]);
-smalltalk.send(smalltalk.send(smalltalk.send(aWidget, "_root", []), "_asJQuery", []), "_show", []);
+smalltalk.send(smalltalk.send(self, "_tabs", []), "_do_", [(function(each){return smalltalk.send(each, "_hide", []);})]);
+smalltalk.send(aWidget, "_show", []);
 smalltalk.send(self, "_update", []);
 return self;},
-source: unescape('selectTab%3A%20aWidget%0A%20%20%20%20self%20open.%0A%20%20%20%20selectedTab%20%3A%3D%20aWidget.%0A%20%20%20%20self%20tabs%20do%3A%20%5B%3Aeach%20%7C%0A%09each%20root%20asJQuery%20hide%5D.%0A%20%20%20%20aWidget%20root%20asJQuery%20show.%0A%20%20%20%20self%20update'),
-messageSends: ["open", "do:", "tabs", "hide", "asJQuery", "root", "show", "update"],
+source: unescape('selectTab%3A%20aWidget%0A%20%20%20%20self%20open.%0A%20%20%20%20selectedTab%20%3A%3D%20aWidget.%0A%20%20%20%20self%20tabs%20do%3A%20%5B%3Aeach%20%7C%0A%09each%20hide%5D.%0A%20%20%20%20aWidget%20show.%0A%09%0A%20%20%20%20self%20update'),
+messageSends: ["open", "do:", "tabs", "hide", "show", "update"],
 referencedClasses: []
 }),
 smalltalk.TabManager);
@@ -181,11 +181,11 @@ fn: function (aWidget){
 var self=this;
 smalltalk.send(self, "_removeTab_", [aWidget]);
 smalltalk.send(self, "_selectTab_", [smalltalk.send(smalltalk.send(self, "_tabs", []), "_last", [])]);
-smalltalk.send(smalltalk.send(smalltalk.send(aWidget, "_root", []), "_asJQuery", []), "_remove", []);
+smalltalk.send(aWidget, "_remove", []);
 smalltalk.send(self, "_update", []);
 return self;},
-source: unescape('closeTab%3A%20aWidget%0A%20%20%20%20self%20removeTab%3A%20aWidget.%0A%20%20%20%20self%20selectTab%3A%20self%20tabs%20last.%0A%20%20%20%20aWidget%20root%20asJQuery%20remove.%0A%20%20%20%20self%20update'),
-messageSends: ["removeTab:", "selectTab:", "last", "tabs", "remove", "asJQuery", "root", "update"],
+source: unescape('closeTab%3A%20aWidget%0A%20%20%20%20self%20removeTab%3A%20aWidget.%0A%20%20%20%20self%20selectTab%3A%20self%20tabs%20last.%0A%20%20%20%20aWidget%20remove.%0A%20%20%20%20self%20update'),
+messageSends: ["removeTab:", "selectTab:", "last", "tabs", "remove", "update"],
 referencedClasses: []
 }),
 smalltalk.TabManager);
@@ -199,10 +199,10 @@ fn: function (aWidget){
 var self=this;
 smalltalk.send(smalltalk.send(self, "_tabs", []), "_add_", [aWidget]);
 smalltalk.send(smalltalk.send(unescape("%23jtalk"), "_asJQuery", []), "_append_", [aWidget]);
-smalltalk.send(smalltalk.send(smalltalk.send(aWidget, "_root", []), "_asJQuery", []), "_hide", []);
+smalltalk.send(aWidget, "_hide", []);
 return self;},
-source: unescape('addTab%3A%20aWidget%0A%20%20%20%20self%20tabs%20add%3A%20aWidget.%0A%20%20%20%20%27%23jtalk%27%20asJQuery%20append%3A%20aWidget.%0A%20%20%20%20aWidget%20root%20asJQuery%20hide'),
-messageSends: ["add:", "tabs", "append:", "asJQuery", "hide", "root"],
+source: unescape('addTab%3A%20aWidget%0A%20%20%20%20self%20tabs%20add%3A%20aWidget.%0A%20%20%20%20%27%23jtalk%27%20asJQuery%20append%3A%20aWidget.%0A%20%20%20%20aWidget%20hide'),
+messageSends: ["add:", "tabs", "append:", "asJQuery", "hide"],
 referencedClasses: []
 }),
 smalltalk.TabManager);
@@ -239,7 +239,7 @@ smalltalk.send(self, "_selectTab_", [smalltalk.send(smalltalk.send(self, "_tabs"
 return self;},
 source: unescape('initialize%0A%20%20%20%20super%20initialize.%0A%20%20%20%20opened%20%3A%3D%20true.%0A%20%20%20%20%27body%27%20asJQuery%20%0A%09append%3A%20self%3B%0A%09append%3A%20%5B%3Ahtml%20%7C%20html%20div%20id%3A%20%27jtalk%27%5D%3B%0A%09addClass%3A%20%27jtalkBody%27.%0A%20%20%20%20self%20%0A%09addTab%3A%20Transcript%20current%3B%0A%09addTab%3A%20Workspace%20new.%0A%20%20%20%20self%20selectTab%3A%20self%20tabs%20last.%0A%20%20%20%20self%20%0A%09onResize%3A%20%5Bself%20updateBodyMargin%3B%20updatePosition%5D%3B%0A%09onWindowResize%3A%20%5Bself%20updatePosition%5D'),
 messageSends: ["initialize", "append:", "id:", "div", "addClass:", "asJQuery", "addTab:", "current", "new", "selectTab:", "last", "tabs", "onResize:", "updateBodyMargin", "updatePosition", "onWindowResize:"],
-referencedClasses: []
+referencedClasses: [smalltalk.nil,smalltalk.nil]
 }),
 smalltalk.TabManager);
 
@@ -250,10 +250,11 @@ selector: 'renderOn:',
 category: 'rendering',
 fn: function (html){
 var self=this;
-(function($rec){smalltalk.send($rec, "_id_", ["jtalkTabs"]);return smalltalk.send($rec, "_with_", [(function(){(function($rec){smalltalk.send($rec, "_class_", ["closeAll"]);smalltalk.send($rec, "_with_", ["x"]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_close", []);})]);})(smalltalk.send(html, "_li", []));smalltalk.send(smalltalk.send(self, "_tabs", []), "_do_", [(function(each){return smalltalk.send(self, "_renderTabFor_on_", [each, html]);})]);return (function($rec){smalltalk.send($rec, "_class_", ["newtab"]);smalltalk.send($rec, "_with_", [unescape("%20+%20")]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_newBrowserTab", []);})]);})(smalltalk.send(html, "_li", []));})]);})(smalltalk.send(html, "_ul", []));
+self['@ul']=(function($rec){smalltalk.send($rec, "_id_", ["jtalkTabs"]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(html, "_ul", []));
+smalltalk.send(self, "_renderTabs", []);
 return self;},
-source: unescape('renderOn%3A%20html%0A%20%20%20%20html%20ul%0A%09id%3A%20%27jtalkTabs%27%3B%0A%09with%3A%20%5B%0A%09%20%20%20%20html%20li%20%0A%09%09class%3A%20%27closeAll%27%3B%0A%09%09with%3A%20%27x%27%3B%0A%09%09onClick%3A%20%5Bself%20close%5D.%0A%09%20%20%20%20self%20tabs%20do%3A%20%5B%3Aeach%20%7C%0A%09%09self%20renderTabFor%3A%20each%20on%3A%20html%5D.%0A%09%20%20%20%20html%20li%0A%09%09class%3A%20%27newtab%27%3B%0A%09%09with%3A%20%27%20+%20%27%3B%0A%09%09onClick%3A%20%5Bself%20newBrowserTab%5D%5D'),
-messageSends: ["id:", "with:", "class:", "onClick:", "close", "li", "do:", "tabs", "renderTabFor:on:", "newBrowserTab", "ul"],
+source: unescape('renderOn%3A%20html%0A%09ul%20%3A%3D%20html%20ul%0A%09%09id%3A%20%27jtalkTabs%27%3B%0A%09%09yourself.%0A%09self%20renderTabs'),
+messageSends: ["id:", "yourself", "ul", "renderTabs"],
 referencedClasses: []
 }),
 smalltalk.TabManager);
@@ -276,6 +277,36 @@ referencedClasses: []
 }),
 smalltalk.TabManager);
 
+smalltalk.addMethod(
+'_renderTabs',
+smalltalk.method({
+selector: 'renderTabs',
+category: 'rendering',
+fn: function (){
+var self=this;
+smalltalk.send(self['@ul'], "_contents_", [(function(html){(function($rec){smalltalk.send($rec, "_class_", ["closeAll"]);smalltalk.send($rec, "_with_", ["x"]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_close", []);})]);})(smalltalk.send(html, "_li", []));smalltalk.send(smalltalk.send(self, "_tabs", []), "_do_", [(function(each){return smalltalk.send(self, "_renderTabFor_on_", [each, html]);})]);return (function($rec){smalltalk.send($rec, "_class_", ["newtab"]);smalltalk.send($rec, "_with_", [unescape("%20+%20")]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_newBrowserTab", []);})]);})(smalltalk.send(html, "_li", []));})]);
+return self;},
+source: unescape('renderTabs%0A%09ul%20contents%3A%20%5B%3Ahtml%20%7C%0A%09%20%20%20%20html%20li%20%0A%09%09class%3A%20%27closeAll%27%3B%0A%09%09with%3A%20%27x%27%3B%0A%09%09onClick%3A%20%5Bself%20close%5D.%0A%09%20%20%20%20self%20tabs%20do%3A%20%5B%3Aeach%20%7C%0A%09%09self%20renderTabFor%3A%20each%20on%3A%20html%5D.%0A%09%20%20%20%20html%20li%0A%09%09class%3A%20%27newtab%27%3B%0A%09%09with%3A%20%27%20+%20%27%3B%0A%09%09onClick%3A%20%5Bself%20newBrowserTab%5D%5D'),
+messageSends: ["contents:", "class:", "with:", "onClick:", "close", "li", "do:", "tabs", "renderTabFor:on:", "newBrowserTab"],
+referencedClasses: []
+}),
+smalltalk.TabManager);
+
+smalltalk.addMethod(
+'_update',
+smalltalk.method({
+selector: 'update',
+category: 'updating',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_renderTabs", []);
+return self;},
+source: unescape('update%0A%09self%20renderTabs'),
+messageSends: ["renderTabs"],
+referencedClasses: []
+}),
+smalltalk.TabManager);
+
 
 smalltalk.TabManager.klass.iVarNames = ['current'];
 smalltalk.addMethod(
@@ -309,7 +340,7 @@ referencedClasses: []
 smalltalk.TabManager.klass);
 
 
-smalltalk.addClass('TabWidget', smalltalk.Widget, [], 'IDE');
+smalltalk.addClass('TabWidget', smalltalk.Widget, ['div'], 'IDE');
 smalltalk.addMethod(
 '_label',
 smalltalk.method({
@@ -332,10 +363,11 @@ selector: 'open',
 category: 'actions',
 fn: function (){
 var self=this;
-(function($rec){smalltalk.send($rec, "_addTab_", [self]);return smalltalk.send($rec, "_selectTab_", [self]);})(smalltalk.send(smalltalk.TabManager, "_current", []));
+smalltalk.send(smalltalk.send(smalltalk.TabManager, "_current", []), "_addTab_", [self]);
+smalltalk.send(smalltalk.send(smalltalk.TabManager, "_current", []), "_selectTab_", [self]);
 return self;},
-source: unescape('open%0A%20%20%20%20TabManager%20current%0A%09addTab%3A%20self%3B%0A%09selectTab%3A%20self'),
-messageSends: ["addTab:", "selectTab:", "current"],
+source: unescape('open%0A%20%20%20%20TabManager%20current%20addTab%3A%20self.%0A%20%20%20%20TabManager%20current%20selectTab%3A%20self'),
+messageSends: ["addTab:", "current", "selectTab:"],
 referencedClasses: [smalltalk.TabManager]
 }),
 smalltalk.TabWidget);
@@ -347,10 +379,11 @@ selector: 'renderOn:',
 category: 'rendering',
 fn: function (html){
 var self=this;
-(function($rec){smalltalk.send($rec, "_class_", ["jtalkTool"]);return smalltalk.send($rec, "_with_", [(function(){(function($rec){smalltalk.send($rec, "_class_", ["jt_box"]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(self, "_renderBoxOn_", [html]);})]);})(smalltalk.send(html, "_div", []));return (function($rec){smalltalk.send($rec, "_class_", ["jt_buttons"]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(self, "_renderButtonsOn_", [html]);})]);})(smalltalk.send(html, "_div", []));})]);})(smalltalk.send(html, "_root", []));
+self['@div']=(function($rec){smalltalk.send($rec, "_class_", ["jtalkTool"]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(html, "_div", []));
+smalltalk.send(self, "_renderTab", []);
 return self;},
-source: unescape('renderOn%3A%20html%0A%20%20%20%20html%20root%0A%09class%3A%20%27jtalkTool%27%3B%0A%09with%3A%20%5B%0A%09%20%20%20%20html%20div%0A%09%09class%3A%20%27jt_box%27%3B%0A%09%09with%3A%20%5Bself%20renderBoxOn%3A%20html%5D.%0A%09%20%20%20%20html%20div%0A%09%09class%3A%20%27jt_buttons%27%3B%0A%09%09with%3A%20%5Bself%20renderButtonsOn%3A%20html%5D%5D'),
-messageSends: ["class:", "with:", "renderBoxOn:", "div", "renderButtonsOn:", "root"],
+source: unescape('renderOn%3A%20html%0A%09div%20%3A%3D%20html%20div%0A%09%09class%3A%20%27jtalkTool%27%3B%0A%09%09yourself.%0A%09self%20renderTab'),
+messageSends: ["class:", "yourself", "div", "renderTab"],
 referencedClasses: []
 }),
 smalltalk.TabWidget);
@@ -400,6 +433,81 @@ referencedClasses: []
 }),
 smalltalk.TabWidget);
 
+smalltalk.addMethod(
+'_show',
+smalltalk.method({
+selector: 'show',
+category: 'actions',
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send(self['@div'], "_asJQuery", []), "_show", []);
+return self;},
+source: unescape('show%0A%09div%20asJQuery%20show'),
+messageSends: ["show", "asJQuery"],
+referencedClasses: []
+}),
+smalltalk.TabWidget);
+
+smalltalk.addMethod(
+'_hide',
+smalltalk.method({
+selector: 'hide',
+category: 'actions',
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send(self['@div'], "_asJQuery", []), "_hide", []);
+return self;},
+source: unescape('hide%0A%09div%20asJQuery%20hide'),
+messageSends: ["hide", "asJQuery"],
+referencedClasses: []
+}),
+smalltalk.TabWidget);
+
+smalltalk.addMethod(
+'_update',
+smalltalk.method({
+selector: 'update',
+category: 'rendering',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_renderTab", []);
+return self;},
+source: unescape('update%0A%09self%20renderTab'),
+messageSends: ["renderTab"],
+referencedClasses: []
+}),
+smalltalk.TabWidget);
+
+smalltalk.addMethod(
+'_remove',
+smalltalk.method({
+selector: 'remove',
+category: 'actions',
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.send(self['@div'], "_asJQuery", []), "_remove", []);
+return self;},
+source: unescape('remove%0A%09div%20asJQuery%20remove'),
+messageSends: ["remove", "asJQuery"],
+referencedClasses: []
+}),
+smalltalk.TabWidget);
+
+smalltalk.addMethod(
+'_renderTab',
+smalltalk.method({
+selector: 'renderTab',
+category: 'rendering',
+fn: function (){
+var self=this;
+smalltalk.send(self['@div'], "_contents_", [(function(html){(function($rec){smalltalk.send($rec, "_class_", ["jt_box"]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(self, "_renderBoxOn_", [html]);})]);})(smalltalk.send(html, "_div", []));return (function($rec){smalltalk.send($rec, "_class_", ["jt_buttons"]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(self, "_renderButtonsOn_", [html]);})]);})(smalltalk.send(html, "_div", []));})]);
+return self;},
+source: unescape('renderTab%0A%09div%20contents%3A%20%5B%3Ahtml%20%7C%0A%09%20%20%20%20html%20div%0A%09%09class%3A%20%27jt_box%27%3B%0A%09%09with%3A%20%5Bself%20renderBoxOn%3A%20html%5D.%0A%09%20%20%20%20html%20div%0A%09%09class%3A%20%27jt_buttons%27%3B%0A%09%09with%3A%20%5Bself%20renderButtonsOn%3A%20html%5D%5D'),
+messageSends: ["contents:", "class:", "with:", "renderBoxOn:", "div", "renderButtonsOn:"],
+referencedClasses: []
+}),
+smalltalk.TabWidget);
+
 
 smalltalk.addMethod(
 '_open',
@@ -1241,7 +1349,7 @@ smalltalk.send(self['@selectedProtocol'], "_ifNil_", [(function(){return self['@
 compiler=smalltalk.send(smalltalk.Compiler, "_new", []);
 node=smalltalk.send(compiler, "_parse_", [source]);
 smalltalk.send(smalltalk.send(node, "_isParseFailure", []), "_ifTrue_", [(function(){return (function(){throw({name: 'stReturn', selector: '_compileMethodDefinitionFor_', fn: function(){return smalltalk.send(self, "_alert_", [smalltalk.send(smalltalk.send(smalltalk.send("PARSE ERROR: ", "__comma", [smalltalk.send(node, "_reason", [])]), "__comma", [unescape("%2C%20position%3A%20")]), "__comma", [smalltalk.send(smalltalk.send(node, "_position", []), "_asString", [])])])}})})();})]);
-smalltalk.send(compiler, "_currentClass_", [self['@selectedClass']]);
+smalltalk.send(compiler, "_currentClass_", [aClass]);
 method=smalltalk.send(compiler, "_eval_", [smalltalk.send(compiler, "_compileNode_", [node])]);
 smalltalk.send(method, "_category_", [self['@selectedProtocol']]);
 smalltalk.send(smalltalk.send(compiler, "_unknownVariables", []), "_do_", [(function(each){return smalltalk.send(smalltalk.send(self, "_confirm_", [smalltalk.send(smalltalk.send(unescape("Declare%20%27"), "__comma", [each]), "__comma", [unescape("%27%20as%20instance%20variable%3F")])]), "_ifTrue_", [(function(){smalltalk.send(self, "_addInstanceVariableNamed_toClass_", [each, aClass]);return (function(){throw({name: 'stReturn', selector: '_compileMethodDefinitionFor_', fn: function(){return smalltalk.send(self, "_compileMethodDefinitionFor_", [aClass])}})})();})]);})]);
@@ -1251,7 +1359,7 @@ smalltalk.send(self, "_updateMethodsList", []);
 smalltalk.send(self, "_selectMethod_", [method]);
 return self;
 } catch(e) {if(e.name === 'stReturn' && e.selector === '_compileMethodDefinitionFor_'){return e.fn()} throw(e)}},
-source: unescape('compileMethodDefinitionFor%3A%20aClass%0A%20%20%20%20%7C%20compiler%20method%20source%20node%20%7C%0A%20%20%20%20source%20%3A%3D%20sourceTextarea%20asJQuery%20val.%0A%20%20%20%20selectedProtocol%20ifNil%3A%20%5BselectedProtocol%20%3A%3D%20selectedMethod%20category%5D.%0A%20%20%20%20compiler%20%3A%3D%20Compiler%20new.%0A%20%20%20%20node%20%3A%3D%20compiler%20parse%3A%20source.%0A%20%20%20%20node%20isParseFailure%20ifTrue%3A%20%5B%0A%09%5Eself%20alert%3A%20%27PARSE%20ERROR%3A%20%27%2C%20node%20reason%2C%20%27%2C%20position%3A%20%27%2C%20node%20position%20asString%5D.%0A%20%20%20%20compiler%20currentClass%3A%20selectedClass.%0A%20%20%20%20method%20%3A%3D%20compiler%20eval%3A%20%28compiler%20compileNode%3A%20node%29.%0A%20%20%20%20method%20category%3A%20selectedProtocol.%0A%20%20%20%20compiler%20unknownVariables%20do%3A%20%5B%3Aeach%20%7C%0A%09%28self%20confirm%3A%20%27Declare%20%27%27%27%2C%20each%2C%20%27%27%27%20as%20instance%20variable%3F%27%29%20ifTrue%3A%20%5B%0A%09%09self%20addInstanceVariableNamed%3A%20each%20toClass%3A%20aClass.%0A%09%09%5Eself%20compileMethodDefinitionFor%3A%20aClass%5D%5D.%0A%20%20%20%20aClass%20addCompiledMethod%3A%20method.%0A%20%20%20%20compiler%20setupClass%3A%20aClass.%0A%20%20%20%20self%20updateMethodsList.%0A%20%20%20%20self%20selectMethod%3A%20method'),
+source: unescape('compileMethodDefinitionFor%3A%20aClass%0A%20%20%20%20%7C%20compiler%20method%20source%20node%20%7C%0A%20%20%20%20source%20%3A%3D%20sourceTextarea%20asJQuery%20val.%0A%20%20%20%20selectedProtocol%20ifNil%3A%20%5BselectedProtocol%20%3A%3D%20selectedMethod%20category%5D.%0A%20%20%20%20compiler%20%3A%3D%20Compiler%20new.%0A%20%20%20%20node%20%3A%3D%20compiler%20parse%3A%20source.%0A%20%20%20%20node%20isParseFailure%20ifTrue%3A%20%5B%0A%09%5Eself%20alert%3A%20%27PARSE%20ERROR%3A%20%27%2C%20node%20reason%2C%20%27%2C%20position%3A%20%27%2C%20node%20position%20asString%5D.%0A%20%20%20%20compiler%20currentClass%3A%20aClass.%0A%20%20%20%20method%20%3A%3D%20compiler%20eval%3A%20%28compiler%20compileNode%3A%20node%29.%0A%20%20%20%20method%20category%3A%20selectedProtocol.%0A%20%20%20%20compiler%20unknownVariables%20do%3A%20%5B%3Aeach%20%7C%0A%09%28self%20confirm%3A%20%27Declare%20%27%27%27%2C%20each%2C%20%27%27%27%20as%20instance%20variable%3F%27%29%20ifTrue%3A%20%5B%0A%09%09self%20addInstanceVariableNamed%3A%20each%20toClass%3A%20aClass.%0A%09%09%5Eself%20compileMethodDefinitionFor%3A%20aClass%5D%5D.%0A%20%20%20%20aClass%20addCompiledMethod%3A%20method.%0A%20%20%20%20compiler%20setupClass%3A%20aClass.%0A%20%20%20%20self%20updateMethodsList.%0A%20%20%20%20self%20selectMethod%3A%20method'),
 messageSends: ["val", "asJQuery", "ifNil:", "category", "new", "parse:", "ifTrue:", "isParseFailure", "alert:", unescape("%2C"), "reason", "asString", "position", "currentClass:", "eval:", "compileNode:", "category:", "do:", "unknownVariables", "confirm:", "addInstanceVariableNamed:toClass:", "compileMethodDefinitionFor:", "addCompiledMethod:", "setupClass:", "updateMethodsList", "selectMethod:"],
 referencedClasses: [smalltalk.Compiler]
 }),
@@ -1285,7 +1393,7 @@ smalltalk.send(self['@selectedCategory'], "_ifNotNil_", [(function(){(function($
 return self;},
 source: unescape('commitCategory%0A%20%20%20%20selectedCategory%20ifNotNil%3A%20%5B%0A%09%28Ajax%20url%3A%20self%20class%20commitPathJs%2C%20%27/%27%2C%20selectedCategory%2C%20%27.js%27%29%0A%09%20%20%20%20at%3A%20%27type%27%20put%3A%20%27PUT%27%3B%0A%09%20%20%20%20at%3A%20%27data%27%20put%3A%20%28Exporter%20new%20exportCategory%3A%20selectedCategory%29%3B%0A%09%20%20%20%20at%3A%20%27error%27%20put%3A%20%5Bself%20alert%3A%20%27Commit%20failed%21%27%5D%3B%0A%09%20%20%20%20send.%0A%09%28Ajax%20url%3A%20self%20class%20commitPathSt%2C%20%27/%27%2C%20selectedCategory%2C%20%27.st%27%29%0A%09%20%20%20%20at%3A%20%27type%27%20put%3A%20%27PUT%27%3B%0A%09%20%20%20%20at%3A%20%27data%27%20put%3A%20%28ChunkExporter%20new%20exportCategory%3A%20selectedCategory%29%3B%0A%09%20%20%20%20at%3A%20%27error%27%20put%3A%20%5Bself%20alert%3A%20%27Commit%20failed%21%27%5D%3B%0A%09%20%20%20%20send%5D'),
 messageSends: ["ifNotNil:", "at:put:", "exportCategory:", "new", "alert:", "send", "url:", unescape("%2C"), "commitPathJs", "class", "commitPathSt"],
-referencedClasses: [smalltalk.Exporter,smalltalk.ChunkExporter]
+referencedClasses: [smalltalk.Exporter,smalltalk.Ajax,smalltalk.ChunkExporter]
 }),
 smalltalk.Browser);
 
@@ -1484,7 +1592,7 @@ smalltalk.send(smalltalk.ReferencesBrowser, "_search_", [aString]);
 return self;},
 source: unescape('searchReferencesOf%3A%20aString%0A%09ReferencesBrowser%20search%3A%20aString'),
 messageSends: ["search:"],
-referencedClasses: []
+referencedClasses: [smalltalk.nil]
 }),
 smalltalk.Browser);
 
@@ -1499,7 +1607,7 @@ smalltalk.send(smalltalk.ReferencesBrowser, "_search_", [smalltalk.send(self['@s
 return self;},
 source: unescape('searchClassReferences%0A%09ReferencesBrowser%20search%3A%20selectedClass%20name'),
 messageSends: ["search:", "name"],
-referencedClasses: []
+referencedClasses: [smalltalk.nil]
 }),
 smalltalk.Browser);
 
@@ -1726,7 +1834,7 @@ var self=this;
 self['@input']=(function($rec){smalltalk.send($rec, "_class_", ["implementors"]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(html, "_input", []));
 smalltalk.send(self['@input'], "_onKeyPress_", [(function(event){return smalltalk.send(smalltalk.send(smalltalk.send(event, "_keyCode", []), "__eq", [(13)]), "_ifTrue_", [(function(){return smalltalk.send(self, "_search_", [smalltalk.send(smalltalk.send(self['@input'], "_asJQuery", []), "_val", [])]);})]);})]);
 return self;},
-source: unescape('renderInputOn%3A%20html%0A%09input%20%3A%3D%20html%20input%20%0A%09%09class%3A%20%27implementors%27%3B%0A%09%09yourself.%0A%09input%20onKeyPress%3A%20%5B%3Aevent%20%7C%0A%09%09event%20keyCode%20%3D%2013%20ifTrue%3A%20%5B%0A%09%09%09self%20search%3A%20input%20asJQuery%20val%5D%5D'),
+source: unescape('renderInputOn%3A%20html%20%0A%09input%20%3A%3D%20html%20input%20%0A%09%09class%3A%20%27implementors%27%3B%0A%09%09yourself.%0A%09input%20onKeyPress%3A%20%5B%3Aevent%20%7C%0A%09%09event%20keyCode%20%3D%2013%20ifTrue%3A%20%5B%0A%09%09%09self%20search%3A%20input%20asJQuery%20val%5D%5D'),
 messageSends: ["class:", "yourself", "input", "onKeyPress:", "ifTrue:", unescape("%3D"), "keyCode", "search:", "val", "asJQuery"],
 referencedClasses: []
 }),
@@ -2491,11 +2599,11 @@ var self=this;
 var variables=nil;
 variables=smalltalk.send(smalltalk.Dictionary, "_new", []);
 smalltalk.send(variables, "_at_put_", [unescape("%23self"), self]);
-smalltalk.send(smalltalk.send(smalltalk.send(self, "_class", []), "_instanceVariableNames", []), "_do_", [(function(each){return smalltalk.send(variables, "_at_put_", [each, smalltalk.send(self, "_instVarAt_", [each])]);})]);
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_class", []), "_allInstanceVariableNames", []), "_do_", [(function(each){return smalltalk.send(variables, "_at_put_", [each, smalltalk.send(self, "_instVarAt_", [each])]);})]);
 (function($rec){smalltalk.send($rec, "_setLabel_", [smalltalk.send(self, "_printString", [])]);return smalltalk.send($rec, "_setVariables_", [variables]);})(anInspector);
 return self;},
-source: unescape('inspectOn%3A%20anInspector%0A%09%7C%20variables%20%7C%0A%09variables%20%3A%3D%20Dictionary%20new.%0A%09variables%20at%3A%20%27%23self%27%20put%3A%20self.%0A%09self%20class%20instanceVariableNames%20do%3A%20%5B%3Aeach%20%7C%0A%09%09variables%20at%3A%20each%20put%3A%20%28self%20instVarAt%3A%20each%29%5D.%0A%09anInspector%20%0A%09%09setLabel%3A%20self%20printString%3B%0A%09%09setVariables%3A%20variables'),
-messageSends: ["new", "at:put:", "do:", "instanceVariableNames", "class", "instVarAt:", "setLabel:", "printString", "setVariables:"],
+source: unescape('inspectOn%3A%20anInspector%0A%09%7C%20variables%20%7C%0A%09variables%20%3A%3D%20Dictionary%20new.%0A%09variables%20at%3A%20%27%23self%27%20put%3A%20self.%0A%09self%20class%20allInstanceVariableNames%20do%3A%20%5B%3Aeach%20%7C%0A%09%09variables%20at%3A%20each%20put%3A%20%28self%20instVarAt%3A%20each%29%5D.%0A%09anInspector%20%0A%09%09setLabel%3A%20self%20printString%3B%0A%09%09setVariables%3A%20variables'),
+messageSends: ["new", "at:put:", "do:", "allInstanceVariableNames", "class", "instVarAt:", "setLabel:", "printString", "setVariables:"],
 referencedClasses: [smalltalk.Dictionary]
 }),
 smalltalk.Object);
@@ -2562,6 +2670,28 @@ referencedClasses: []
 }),
 smalltalk.String);
 
+smalltalk.addMethod(
+'_inspectOn_',
+smalltalk.method({
+selector: 'inspectOn:',
+category: '*IDE',
+fn: function (anInspector){
+var self=this;
+var variables=nil;
+variables=smalltalk.send(smalltalk.Dictionary, "_new", []);
+smalltalk.send(variables, "_at_put_", [unescape("%23self"), self]);
+smalltalk.send(variables, "_at_put_", [unescape("%23home"), smalltalk.send(self, "_home", [])]);
+smalltalk.send(variables, "_at_put_", [unescape("%23receiver"), smalltalk.send(self, "_receiver", [])]);
+smalltalk.send(variables, "_at_put_", [unescape("%23selector"), smalltalk.send(self, "_selector", [])]);
+smalltalk.send(smalltalk.send(smalltalk.send(self, "_class", []), "_instanceVariableNames", []), "_do_", [(function(each){return smalltalk.send(variables, "_at_put_", [each, smalltalk.send(self, "_instVarAt_", [each])]);})]);
+(function($rec){smalltalk.send($rec, "_setLabel_", [smalltalk.send(self, "_printString", [])]);return smalltalk.send($rec, "_setVariables_", [variables]);})(anInspector);
+return self;},
+source: unescape('inspectOn%3A%20anInspector%0A%09%7C%20variables%20%7C%0A%09variables%20%3A%3D%20Dictionary%20new.%0A%09variables%20at%3A%20%27%23self%27%20put%3A%20self.%0A%09variables%20at%3A%20%27%23home%27%20put%3A%20self%20home.%0A%09variables%20at%3A%20%27%23receiver%27%20put%3A%20self%20receiver.%0A%09variables%20at%3A%20%27%23selector%27%20put%3A%20self%20selector.%0A%09self%20class%20instanceVariableNames%20do%3A%20%5B%3Aeach%20%7C%0A%09%09variables%20at%3A%20each%20put%3A%20%28self%20instVarAt%3A%20each%29%5D.%0A%09anInspector%20%0A%09%09setLabel%3A%20self%20printString%3B%0A%09%09setVariables%3A%20variables'),
+messageSends: ["new", "at:put:", "home", "receiver", "selector", "do:", "instanceVariableNames", "class", "instVarAt:", "setLabel:", "printString", "setVariables:"],
+referencedClasses: [smalltalk.Dictionary]
+}),
+smalltalk.MethodContext);
+
 smalltalk.addMethod(
 '_inspectOn_',
 smalltalk.method({

+ 47 - 18
js/JQuery.js

@@ -75,6 +75,21 @@ referencedClasses: []
 }),
 smalltalk.JQuery);
 
+smalltalk.addMethod(
+'_jquery',
+smalltalk.method({
+selector: 'jquery',
+category: 'accessing',
+fn: function (){
+var self=this;
+return self['@jquery'];
+return self;},
+source: unescape('jquery%0A%09%5Ejquery'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.JQuery);
+
 smalltalk.addMethod(
 '_removeAttribute_',
 smalltalk.method({
@@ -144,7 +159,7 @@ fn: function (aString){
 var self=this;
 return self['@jquery'].css(aString);
 return self;},
-source: unescape('cssAt%3A%20aString%0A%09%7B%27return%20self%5B%27%27@jquery%27%27%5D.css%28aString%29%27%7D'),
+source: unescape('cssAt%3A%20aString%0A%09%3Creturn%20self%5B%27@jquery%27%5D.css%28aString%29%3E'),
 messageSends: [],
 referencedClasses: []
 }),
@@ -159,7 +174,7 @@ fn: function (aString, anotherString){
 var self=this;
 self['@jquery'].css(aString, anotherString);
 return self;},
-source: unescape('cssAt%3A%20aString%20put%3A%20anotherString%0A%20%20%20%20%7B%27self%5B%27%27@jquery%27%27%5D.css%28aString%2C%20anotherString%29%27%7D'),
+source: unescape('cssAt%3A%20aString%20put%3A%20anotherString%0A%20%20%20%20%3Cself%5B%27@jquery%27%5D.css%28aString%2C%20anotherString%29%3E'),
 messageSends: [],
 referencedClasses: []
 }),
@@ -519,7 +534,7 @@ fn: function (anEventString, aBlock){
 var self=this;
 self['@jquery'].bind(anEventString, function(e){aBlock(e, self)});
 return self;},
-source: unescape('on%3A%20anEventString%20do%3A%20aBlock%0A%20%20%20%20%22Attach%20aBlock%20for%20anEventString%20on%20the%20element%22%0A%20%20%20%20%7B%27self%5B%27%27@jquery%27%27%5D.bind%28anEventString%2C%20function%28e%29%7BaBlock%28e%2C%20self%29%7D%29%27%7D'),
+source: unescape('on%3A%20anEventString%20do%3A%20aBlock%0A%20%20%20%20%22Attach%20aBlock%20for%20anEventString%20on%20the%20element%22%0A%20%20%20%20%3Cself%5B%27@jquery%27%5D.bind%28anEventString%2C%20function%28e%29%7BaBlock%28e%2C%20self%29%7D%29%3E'),
 messageSends: [],
 referencedClasses: []
 }),
@@ -564,7 +579,7 @@ fn: function (aString){
 var self=this;
 return self['@jquery'][aString]();
 return self;},
-source: unescape('call%3A%20aString%0A%09%7B%27return%20self%5B%27%27@jquery%27%27%5D%5BaString%5D%28%29%27%7D'),
+source: unescape('call%3A%20aString%0A%09%3Creturn%20self%5B%27@jquery%27%5D%5BaString%5D%28%29%3E'),
 messageSends: [],
 referencedClasses: []
 }),
@@ -579,7 +594,7 @@ fn: function (aString, anObject){
 var self=this;
 return self['@jquery'][aString](anObject);
 return self;},
-source: unescape('call%3A%20aString%20withArgument%3A%20anObject%0A%20%20%20%20%7B%27return%20self%5B%27%27@jquery%27%27%5D%5BaString%5D%28anObject%29%27%7D'),
+source: unescape('call%3A%20aString%20withArgument%3A%20anObject%0A%20%20%20%20%3Creturn%20self%5B%27@jquery%27%5D%5BaString%5D%28anObject%29%3E'),
 messageSends: [],
 referencedClasses: []
 }),
@@ -612,7 +627,7 @@ var newJQuery=nil;
 newJQuery = jQuery(String(aString));
 return smalltalk.send(self, "_from_", [newJQuery]);
 return self;},
-source: unescape('fromString%3A%20aString%0A%20%20%20%20%7C%20newJQuery%20%7C%0A%20%20%20%20%7B%27newJQuery%20%3D%20jQuery%28String%28aString%29%29%27%7D.%0A%20%20%20%20%5Eself%20from%3A%20newJQuery'),
+source: unescape('fromString%3A%20aString%0A%20%20%20%20%7C%20newJQuery%20%7C%0A%20%20%20%20%3CnewJQuery%20%3D%20jQuery%28String%28aString%29%29%3E.%0A%20%20%20%20%5Eself%20from%3A%20newJQuery'),
 messageSends: ["from:"],
 referencedClasses: []
 }),
@@ -642,7 +657,7 @@ fn: function (){
 var self=this;
 return self._from_(jQuery(window));
 return self;},
-source: unescape('window%0A%09%7B%27return%20self._from_%28jQuery%28window%29%29%27%7D'),
+source: unescape('window%0A%09%3Creturn%20self._from_%28jQuery%28window%29%29%3E'),
 messageSends: [],
 referencedClasses: []
 }),
@@ -655,9 +670,9 @@ selector: 'body',
 category: 'instance creation',
 fn: function (){
 var self=this;
-return self._from_(jQuery(body));
+return self._from_(jQuery('body'));
 return self;},
-source: unescape('body%0A%09%7B%27return%20self._from_%28jQuery%28body%29%29%27%7D'),
+source: unescape('body%0A%09%3Creturn%20self._from_%28jQuery%28%27body%27%29%29%3E'),
 messageSends: [],
 referencedClasses: []
 }),
@@ -672,12 +687,29 @@ fn: function (){
 var self=this;
 return self._from_(jQuery(document));
 return self;},
-source: unescape('document%0A%09%7B%27return%20self._from_%28jQuery%28document%29%29%27%7D'),
+source: unescape('document%0A%09%3Creturn%20self._from_%28jQuery%28document%29%29%3E'),
 messageSends: [],
 referencedClasses: []
 }),
 smalltalk.JQuery.klass);
 
+smalltalk.addMethod(
+'_fromElement_',
+smalltalk.method({
+selector: 'fromElement:',
+category: 'instance creation',
+fn: function (anElement){
+var self=this;
+var newJQuery=nil;
+newJQuery = jQuery(anElement);
+return smalltalk.send(self, "_from_", [newJQuery]);
+return self;},
+source: unescape('fromElement%3A%20anElement%0A%20%20%20%20%7C%20newJQuery%20%7C%0A%20%20%20%20%3CnewJQuery%20%3D%20jQuery%28anElement%29%3E.%0A%20%20%20%20%5Eself%20from%3A%20newJQuery'),
+messageSends: ["from:"],
+referencedClasses: []
+}),
+smalltalk.JQuery.klass);
+
 
 smalltalk.addClass('Ajax', smalltalk.Object, ['settings'], 'JQuery');
 smalltalk.Ajax.comment=unescape('instance%20variable%20names%3A%0A-%20settings%20%20A%20set%20of%20key/value%20pairs%20that%20configure%20the%20Ajax%20request.%20All%20settings%20are%20optional.%0A%0AFull%20list%20of%20settings%20options%20at%20http%3A//api.jquery.com/jQuery.ajax/')
@@ -750,7 +782,7 @@ fn: function (){
 var self=this;
 jQuery.ajax(self['@settings']);
 return self;},
-source: unescape('send%0A%20%20%20%20%7B%27jQuery.ajax%28self%5B%27%27@settings%27%27%5D%29%27%7D'),
+source: unescape('send%0A%20%20%20%20%3CjQuery.ajax%28self%5B%27@settings%27%5D%29%3E'),
 messageSends: [],
 referencedClasses: []
 }),
@@ -796,13 +828,10 @@ selector: 'appendToJQuery:',
 category: '*JQuery',
 fn: function (aJQuery){
 var self=this;
-var canvas=nil;
-canvas=smalltalk.send(smalltalk.HTMLCanvas, "_new", []);
-smalltalk.send(self, "_value_", [canvas]);
-smalltalk.send(aJQuery, "_append_", [canvas]);
+smalltalk.send(self, "_value_", [smalltalk.send(smalltalk.HTMLCanvas, "_onJQuery_", [aJQuery])]);
 return self;},
-source: unescape('appendToJQuery%3A%20aJQuery%0A%09%7C%20canvas%20%7C%0A%09canvas%20%3A%3D%20HTMLCanvas%20new.%0A%09self%20value%3A%20canvas.%0A%09aJQuery%20append%3A%20canvas'),
-messageSends: ["new", "value:", "append:"],
+source: unescape('appendToJQuery%3A%20aJQuery%0A%09self%20value%3A%20%28HTMLCanvas%20onJQuery%3A%20aJQuery%29'),
+messageSends: ["value:", "onJQuery:"],
 referencedClasses: [smalltalk.HTMLCanvas]
 }),
 smalltalk.BlockClosure);
@@ -831,7 +860,7 @@ fn: function (aJQuery){
 var self=this;
 aJQuery._appendElement_(String(self));
 return self;},
-source: unescape('appendToJQuery%3A%20aJQuery%0A%20%20%20%20%7B%27aJQuery._appendElement_%28String%28self%29%29%27%7D'),
+source: unescape('appendToJQuery%3A%20aJQuery%0A%20%20%20%20%3CaJQuery._appendElement_%28String%28self%29%29%3E'),
 messageSends: [],
 referencedClasses: []
 }),

+ 286 - 4
js/Kernel.js

@@ -678,6 +678,21 @@ referencedClasses: [smalltalk.Object]
 }),
 smalltalk.Object);
 
+smalltalk.addMethod(
+'_halt',
+smalltalk.method({
+selector: 'halt',
+category: 'error handling',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_error_", ["Halt encountered"]);
+return self;},
+source: unescape('halt%0A%09self%20error%3A%20%27Halt%20encountered%27'),
+messageSends: ["error:"],
+referencedClasses: []
+}),
+smalltalk.Object);
+
 
 smalltalk.addMethod(
 '_initialize',
@@ -1092,6 +1107,24 @@ referencedClasses: [smalltalk.nil,smalltalk.Array]
 }),
 smalltalk.Behavior);
 
+smalltalk.addMethod(
+'_allInstanceVariableNames',
+smalltalk.method({
+selector: 'allInstanceVariableNames',
+category: 'accessing',
+fn: function (){
+var self=this;
+var result=nil;
+result=smalltalk.send(self, "_instanceVariableNames", []);
+smalltalk.send(smalltalk.send(self, "_superclass", []), "_ifNotNil_", [(function(){return smalltalk.send(result, "_addAll_", [smalltalk.send(smalltalk.send(self, "_superclass", []), "_allInstanceVariableNames", [])]);})]);
+return result;
+return self;},
+source: unescape('allInstanceVariableNames%0A%09%7C%20result%20%7C%0A%09result%20%3A%3D%20self%20instanceVariableNames.%0A%09self%20superclass%20ifNotNil%3A%20%5B%0A%09%20%20%20%20result%20addAll%3A%20self%20superclass%20allInstanceVariableNames%5D.%0A%09%5Eresult'),
+messageSends: ["instanceVariableNames", "ifNotNil:", "superclass", "addAll:", "allInstanceVariableNames"],
+referencedClasses: []
+}),
+smalltalk.Behavior);
+
 
 
 smalltalk.addClass('Class', smalltalk.Behavior, [], 'Kernel');
@@ -4738,9 +4771,9 @@ selector: 'exec:',
 category: 'evaluating',
 fn: function (aString){
 var self=this;
-return self.exec(aString);
+return self.exec(aString) || nil;
 return self;},
-source: unescape('exec%3A%20aString%0A%09%3Creturn%20self.exec%28aString%29%3E'),
+source: unescape('exec%3A%20aString%0A%09%3Creturn%20self.exec%28aString%29%20%7C%7C%20nil%3E'),
 messageSends: [],
 referencedClasses: []
 }),
@@ -4831,9 +4864,24 @@ selector: 'signal',
 category: 'signaling',
 fn: function (){
 var self=this;
-console.log(self._messageText()); throw(self);
+self.context = thisContext; self.smalltalkError = true; throw(self);
 return self;},
-source: unescape('signal%0A%09%3Cconsole.log%28self._messageText%28%29%29%3B%20throw%28self%29%3E'),
+source: unescape('signal%0A%09%3Cself.context%20%3D%20thisContext%3B%20self.smalltalkError%20%3D%20true%3B%20throw%28self%29%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Error);
+
+smalltalk.addMethod(
+'_context',
+smalltalk.method({
+selector: 'context',
+category: 'accessing',
+fn: function (){
+var self=this;
+return self.context;
+return self;},
+source: unescape('context%0A%09%3Creturn%20self.context%3E'),
 messageSends: [],
 referencedClasses: []
 }),
@@ -4856,6 +4904,99 @@ referencedClasses: []
 smalltalk.Error.klass);
 
 
+smalltalk.addClass('MethodContext', smalltalk.Object, [], 'Kernel');
+smalltalk.addMethod(
+'_receiver',
+smalltalk.method({
+selector: 'receiver',
+category: 'accessing',
+fn: function (){
+var self=this;
+return self.receiver;
+return self;},
+source: unescape('receiver%0A%09%3Creturn%20self.receiver%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodContext);
+
+smalltalk.addMethod(
+'_selector',
+smalltalk.method({
+selector: 'selector',
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.convertSelector(self.selector);
+return self;},
+source: unescape('selector%0A%09%3Creturn%20smalltalk.convertSelector%28self.selector%29%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodContext);
+
+smalltalk.addMethod(
+'_home',
+smalltalk.method({
+selector: 'home',
+category: 'accessing',
+fn: function (){
+var self=this;
+return self.homeContext;
+return self;},
+source: unescape('home%0A%09%3Creturn%20self.homeContext%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodContext);
+
+smalltalk.addMethod(
+'_temps',
+smalltalk.method({
+selector: 'temps',
+category: 'accessing',
+fn: function (){
+var self=this;
+return self.temps;
+return self;},
+source: unescape('temps%0A%09%3Creturn%20self.temps%3E'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.MethodContext);
+
+smalltalk.addMethod(
+'_printString',
+smalltalk.method({
+selector: 'printString',
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_printString", [], smalltalk.Object), "__comma", [unescape("%28")]), "__comma", [smalltalk.send(self, "_asString", [])]), "__comma", [unescape("%29")]);
+return self;},
+source: unescape('printString%0A%09%5Esuper%20printString%2C%20%27%28%27%2C%20self%20asString%2C%20%27%29%27'),
+messageSends: [unescape("%2C"), "printString", "asString"],
+referencedClasses: []
+}),
+smalltalk.MethodContext);
+
+smalltalk.addMethod(
+'_asString',
+smalltalk.method({
+selector: 'asString',
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_receiver", []), "_class", []), "_printString", []), "__comma", [unescape("%20%3E%3E%20")]), "__comma", [smalltalk.send(self, "_selector", [])]);
+return self;},
+source: unescape('asString%0A%09%5Eself%20receiver%20class%20printString%2C%20%27%20%3E%3E%20%27%2C%20self%20selector'),
+messageSends: [unescape("%2C"), "printString", "class", "receiver", "selector"],
+referencedClasses: []
+}),
+smalltalk.MethodContext);
+
+
+
 smalltalk.addClass('Association', smalltalk.Object, ['key', 'value'], 'Kernel');
 smalltalk.addMethod(
 '__eq',
@@ -6423,3 +6564,144 @@ smalltalk.MessageNotUnderstood);
 
 
 
+smalltalk.addClass('ErrorHandler', smalltalk.Object, [], 'Kernel');
+smalltalk.addMethod(
+'_handleError_',
+smalltalk.method({
+selector: 'handleError:',
+category: 'error handling',
+fn: function (anError){
+var self=this;
+smalltalk.send(smalltalk.send(anError, "_context", []), "_ifNotNil_", [(function(){return smalltalk.send(self, "_logErrorContext_", [smalltalk.send(anError, "_context", [])]);})]);
+smalltalk.send(self, "_logError_", [anError]);
+return self;},
+source: unescape('handleError%3A%20anError%0A%09anError%20context%20ifNotNil%3A%20%5Bself%20logErrorContext%3A%20anError%20context%5D.%0A%09self%20logError%3A%20anError'),
+messageSends: ["ifNotNil:", "context", "logErrorContext:", "logError:"],
+referencedClasses: []
+}),
+smalltalk.ErrorHandler);
+
+smalltalk.addMethod(
+'_logContext_',
+smalltalk.method({
+selector: 'logContext:',
+category: 'private',
+fn: function (aContext){
+var self=this;
+smalltalk.send(smalltalk.send(aContext, "_home", []), "_ifNotNil_", [(function(){return smalltalk.send(self, "_logContext_", [smalltalk.send(aContext, "_home", [])]);})]);
+smalltalk.send(self, "_log_", [smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aContext, "_receiver", []), "_asString", []), "__comma", [unescape("%3E%3E")]), "__comma", [smalltalk.send(aContext, "_selector", [])])]);
+return self;},
+source: unescape('logContext%3A%20aContext%0A%09aContext%20home%20ifNotNil%3A%20%5B%0A%09%09self%20logContext%3A%20aContext%20home%5D.%0A%09self%20log%3A%20aContext%20receiver%20asString%2C%20%27%3E%3E%27%2C%20aContext%20selector'),
+messageSends: ["ifNotNil:", "home", "logContext:", "log:", unescape("%2C"), "asString", "receiver", "selector"],
+referencedClasses: []
+}),
+smalltalk.ErrorHandler);
+
+smalltalk.addMethod(
+'_logErrorContext_',
+smalltalk.method({
+selector: 'logErrorContext:',
+category: 'private',
+fn: function (aContext){
+var self=this;
+smalltalk.send(aContext, "_ifNotNil_", [(function(){return smalltalk.send(smalltalk.send(aContext, "_home", []), "_ifNotNil_", [(function(){return smalltalk.send(self, "_logContext_", [smalltalk.send(aContext, "_home", [])]);})]);})]);
+return self;},
+source: unescape('logErrorContext%3A%20aContext%0A%09aContext%20ifNotNil%3A%20%5B%0A%09%09aContext%20home%20ifNotNil%3A%20%5B%0A%09%09%09self%20logContext%3A%20aContext%20home%5D%5D'),
+messageSends: ["ifNotNil:", "home", "logContext:"],
+referencedClasses: []
+}),
+smalltalk.ErrorHandler);
+
+smalltalk.addMethod(
+'_logError_',
+smalltalk.method({
+selector: 'logError:',
+category: 'private',
+fn: function (anError){
+var self=this;
+smalltalk.send(self, "_log_", [smalltalk.send(anError, "_messageText", [])]);
+return self;},
+source: unescape('logError%3A%20anError%0A%09self%20log%3A%20anError%20messageText'),
+messageSends: ["log:", "messageText"],
+referencedClasses: []
+}),
+smalltalk.ErrorHandler);
+
+smalltalk.addMethod(
+'_log_',
+smalltalk.method({
+selector: 'log:',
+category: 'private',
+fn: function (aString){
+var self=this;
+smalltalk.send(console, "_log_", [aString]);
+return self;},
+source: unescape('log%3A%20aString%0A%09console%20log%3A%20aString'),
+messageSends: ["log:"],
+referencedClasses: []
+}),
+smalltalk.ErrorHandler);
+
+
+smalltalk.ErrorHandler.klass.iVarNames = ['current'];
+smalltalk.addMethod(
+'_current',
+smalltalk.method({
+selector: 'current',
+category: 'accessing',
+fn: function (){
+var self=this;
+return self['@current'];
+return self;},
+source: unescape('current%0A%09%5Ecurrent'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ErrorHandler.klass);
+
+smalltalk.addMethod(
+'_initialize',
+smalltalk.method({
+selector: 'initialize',
+category: 'initialization',
+fn: function (){
+var self=this;
+smalltalk.send(self, "_register", []);
+return self;},
+source: unescape('initialize%0A%09self%20register'),
+messageSends: ["register"],
+referencedClasses: []
+}),
+smalltalk.ErrorHandler.klass);
+
+smalltalk.addMethod(
+'_register',
+smalltalk.method({
+selector: 'register',
+category: 'initialization',
+fn: function (){
+var self=this;
+smalltalk.send(smalltalk.ErrorHandler, "_setCurrent_", [smalltalk.send(self, "_new", [])]);
+return self;},
+source: unescape('register%0A%09ErrorHandler%20setCurrent%3A%20self%20new'),
+messageSends: ["setCurrent:", "new"],
+referencedClasses: [smalltalk.ErrorHandler]
+}),
+smalltalk.ErrorHandler.klass);
+
+smalltalk.addMethod(
+'_setCurrent_',
+smalltalk.method({
+selector: 'setCurrent:',
+category: 'accessing',
+fn: function (anHandler){
+var self=this;
+self['@current']=anHandler;
+return self;},
+source: unescape('setCurrent%3A%20anHandler%0A%09current%20%3A%3D%20anHandler'),
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.ErrorHandler.klass);
+
+

+ 16 - 16
js/Parser.js

@@ -40,7 +40,7 @@ return smalltalk.send(smalltalk.PPFlattenParser, "_on_", [self]);
 return self;},
 source: unescape('flatten%0A%09%5EPPFlattenParser%20on%3A%20self'),
 messageSends: ["on:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPFlattenParser]
 }),
 smalltalk.PPParser);
 
@@ -55,7 +55,7 @@ return smalltalk.send(smalltalk.PPSourceParser, "_on_", [self]);
 return self;},
 source: unescape('withSource%0A%09%5EPPSourceParser%20on%3A%20self'),
 messageSends: ["on:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPSourceParser]
 }),
 smalltalk.PPParser);
 
@@ -70,7 +70,7 @@ return smalltalk.send(smalltalk.PPActionParser, "_on_block_", [self, aBlock]);
 return self;},
 source: unescape('%3D%3D%3E%20aBlock%0A%09%5EPPActionParser%20on%3A%20self%20block%3A%20aBlock'),
 messageSends: ["on:block:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPActionParser]
 }),
 smalltalk.PPParser);
 
@@ -85,7 +85,7 @@ return smalltalk.send(smalltalk.PPSequenceParser, "_with_with_", [self, aParser]
 return self;},
 source: unescape('%2C%20aParser%0A%09%5EPPSequenceParser%20with%3A%20self%20with%3A%20aParser'),
 messageSends: ["with:with:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPSequenceParser]
 }),
 smalltalk.PPParser);
 
@@ -100,7 +100,7 @@ return smalltalk.send(smalltalk.PPChoiceParser, "_with_with_", [self, aParser]);
 return self;},
 source: unescape('/%20aParser%0A%09%5EPPChoiceParser%20with%3A%20self%20with%3A%20aParser'),
 messageSends: ["with:with:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPChoiceParser]
 }),
 smalltalk.PPParser);
 
@@ -115,7 +115,7 @@ return smalltalk.send(smalltalk.PPRepeatingParser, "_on_min_", [self, (1)]);
 return self;},
 source: unescape('plus%0A%09%5EPPRepeatingParser%20on%3A%20self%20min%3A%201'),
 messageSends: ["on:min:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPRepeatingParser]
 }),
 smalltalk.PPParser);
 
@@ -130,7 +130,7 @@ return smalltalk.send(smalltalk.PPRepeatingParser, "_on_min_", [self, (0)]);
 return self;},
 source: unescape('star%0A%09%5EPPRepeatingParser%20on%3A%20self%20min%3A%200'),
 messageSends: ["on:min:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPRepeatingParser]
 }),
 smalltalk.PPParser);
 
@@ -145,7 +145,7 @@ return smalltalk.send(smalltalk.PPNotParser, "_on_", [self]);
 return self;},
 source: unescape('not%0A%09%5EPPNotParser%20on%3A%20self'),
 messageSends: ["on:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPNotParser]
 }),
 smalltalk.PPParser);
 
@@ -160,7 +160,7 @@ return smalltalk.send(self, "__slash", [smalltalk.send(smalltalk.PPEpsilonParser
 return self;},
 source: unescape('optional%0A%09%5Eself%20/%20PPEpsilonParser%20new'),
 messageSends: [unescape("/"), "new"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPEpsilonParser]
 }),
 smalltalk.PPParser);
 
@@ -211,7 +211,7 @@ return smalltalk.send(smalltalk.send(result, "_isParseFailure", []), "_ifTrue_if
 return self;},
 source: unescape('parseAll%3A%20aStream%0A%09%7C%20result%20%7C%0A%09result%20%3A%3D%20%28PPSequenceParser%20with%3A%20self%20with%3A%20PPEOFParser%20new%29%20memoizedParse%3A%20aStream.%0A%09%5Eresult%20isParseFailure%20%0A%09%20%20%20%20ifTrue%3A%20%5Bself%20error%3A%20%28result%20messageFor%3A%20aStream%20contents%29%5D%0A%09%20%20%20%20ifFalse%3A%20%5Bresult%20first%5D'),
 messageSends: ["memoizedParse:", "with:with:", "new", "ifTrue:ifFalse:", "isParseFailure", "error:", "messageFor:", "contents", "first"],
-referencedClasses: [smalltalk.nil,smalltalk.nil]
+referencedClasses: [smalltalk.PPSequenceParser,smalltalk.PPEOFParser]
 }),
 smalltalk.PPParser);
 
@@ -229,7 +229,7 @@ return smalltalk.send(smalltalk.send(aStream, "_atEnd", []), "_ifFalse_ifTrue_",
 return self;},
 source: unescape('parse%3A%20aStream%0A%09%5EaStream%20atEnd%20%0A%09%20%20%20%20ifFalse%3A%20%5B%0A%09%09PPFailure%20new%20reason%3A%20aStream%20contents%2C%20String%20lf%2C%20%27---------------%27%2C%20String%20lf%2C%20%27EOF%20expected%27%20at%3A%20aStream%20position%5D%0A%09%20%20%20%20ifTrue%3A%20%5Bnil%5D'),
 messageSends: ["ifFalse:ifTrue:", "atEnd", "reason:at:", "new", unescape("%2C"), "contents", "lf", "position"],
-referencedClasses: [smalltalk.nil,smalltalk.String]
+referencedClasses: [smalltalk.PPFailure,smalltalk.String]
 }),
 smalltalk.PPEOFParser);
 
@@ -247,7 +247,7 @@ return smalltalk.send(smalltalk.send(aStream, "_atEnd", []), "_ifTrue_ifFalse_",
 return self;},
 source: unescape('parse%3A%20aStream%0A%09%5EaStream%20atEnd%0A%09%20%20%20%20ifTrue%3A%20%5BPPFailure%20new%0A%09%09%09%20reason%3A%20%27did%20not%20expect%20EOF%27%20at%3A%20aStream%20position%5D%0A%09%20%20%20%20ifFalse%3A%20%5BaStream%20next%5D'),
 messageSends: ["ifTrue:ifFalse:", "atEnd", "reason:at:", "new", "position", "next"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPFailure]
 }),
 smalltalk.PPAnyParser);
 
@@ -317,7 +317,7 @@ return smalltalk.send(smalltalk.send(result, "__eq", [smalltalk.send(self, "_str
 return self;},
 source: unescape('parse%3A%20aStream%0A%09%7C%20position%20result%20%7C%0A%09position%20%3A%3D%20aStream%20position.%0A%09result%20%3A%3D%20aStream%20next%3A%20self%20string%20size.%0A%09%5Eresult%20%3D%20self%20string%0A%09%20%20%20%20ifTrue%3A%20%5Bresult%5D%0A%09%20%20%20%20ifFalse%3A%20%5B%0A%09%09aStream%20position%3A%20position.%0A%09%09PPFailure%20new%20reason%3A%20%27Expected%20%27%2C%20self%20string%2C%20%27%20but%20got%20%27%2C%20%28result%20at%3A%20position%29%20printString%3B%20yourself%5D'),
 messageSends: ["position", "next:", "size", "string", "ifTrue:ifFalse:", unescape("%3D"), "position:", "reason:", unescape("%2C"), "printString", "at:", "yourself", "new"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPFailure]
 }),
 smalltalk.PPStringParser);
 
@@ -350,7 +350,7 @@ return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aStream, "_pe
 return self;},
 source: unescape('parse%3A%20aStream%0A%09%5E%28aStream%20peek%20notNil%20and%3A%20%5Bself%20match%3A%20aStream%20peek%5D%29%0A%09%20%20%20%20ifTrue%3A%20%5BaStream%20next%5D%0A%09%20%20%20%20ifFalse%3A%20%5BPPFailure%20new%20reason%3A%20%27Could%20not%20match%27%20at%3A%20aStream%20position%5D'),
 messageSends: ["ifTrue:ifFalse:", "and:", "notNil", "peek", "match:", "next", "reason:at:", "new", "position"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPFailure]
 }),
 smalltalk.PPCharacterParser);
 
@@ -638,7 +638,7 @@ return smalltalk.send(smalltalk.send(element, "_isParseFailure", []), "_ifTrue_i
 return self;},
 source: unescape('parse%3A%20aStream%0A%09%7C%20element%20%7C%0A%09element%20%3A%3D%20self%20basicParse%3A%20aStream.%0A%09%5Eelement%20isParseFailure%20%0A%09%20%20%20%20ifTrue%3A%20%5Bnil%5D%0A%09%20%20%20%20ifFalse%3A%20%5BPPFailure%20reason%3A%20element%20at%3A%20aStream%20position%5D'),
 messageSends: ["basicParse:", "ifTrue:ifFalse:", "isParseFailure", "reason:at:", "position"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPFailure]
 }),
 smalltalk.PPNotParser);
 
@@ -1342,7 +1342,7 @@ nextChunk=smalltalk.send(smalltalk.send(self, "_chunkParser", []), "_parse_", [a
 return self;},
 source: unescape('import%3A%20aStream%0A%09aStream%20atEnd%20ifFalse%3A%20%5B%0A%09%20%20%20%20%7C%20nextChunk%20%7C%0A%09%20%20%20%20nextChunk%20%3A%3D%20self%20chunkParser%20parse%3A%20aStream.%0A%09%20%20%20%20nextChunk%20ifNotNil%3A%20%5B%0A%09%09nextChunk%20isInstructionChunk%20%0A%09%09%20%20%20%20ifTrue%3A%20%5B%28Compiler%20new%20loadExpression%3A%20nextChunk%20contents%29%0A%09%09%09%09%09%20scanFrom%3A%20aStream%5D%0A%09%09%20%20%20%20ifFalse%3A%20%5BCompiler%20new%20loadExpression%3A%20nextChunk%20contents%5D.%0A%09%09self%20import%3A%20aStream%5D%5D'),
 messageSends: ["ifFalse:", "atEnd", "parse:", "chunkParser", "ifNotNil:", "ifTrue:ifFalse:", "isInstructionChunk", "scanFrom:", "loadExpression:", "new", "contents", "import:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.Compiler]
 }),
 smalltalk.Importer);
 

+ 27 - 11
js/SUnit.js

@@ -55,7 +55,7 @@ var self=this;
 return self;},
 source: unescape('signalFailure%3A%20aString%0A%09TestFailure%20new%0A%09%09messageText%3A%20aString%3B%0A%09%09signal'),
 messageSends: ["messageText:", "signal", "new"],
-referencedClasses: []
+referencedClasses: [smalltalk.nil]
 }),
 smalltalk.TestCase);
 
@@ -132,7 +132,7 @@ smalltalk.send(smalltalk.send(self, "_methods", []), "_do_", [(function(each){sm
 return self;},
 source: unescape('performTestFor%3A%20aResult%0A%09self%20methods%20do%3A%20%5B%3Aeach%20%7C%20%0A%09%09%5B%5Bself%20perform%3A%20each%5D%0A%09%09%09on%3A%20TestFailure%20do%3A%20%5B%3Aex%20%7C%20aResult%20addFailure%3A%20self%20class%20name%2C%20%27%3E%3E%27%2C%20each%5D%5D%0A%09%09%09on%3A%20Error%20do%3A%20%5B%3Aex%20%7C%20aResult%20addError%3A%20self%20class%20name%2C%20%27%3E%3E%27%2C%20each%5D.%0A%09%09aResult%20increaseRuns%5D'),
 messageSends: ["do:", "methods", "on:do:", "perform:", "addFailure:", unescape("%2C"), "name", "class", "addError:", "increaseRuns"],
-referencedClasses: [smalltalk.Error]
+referencedClasses: [smalltalk.nil,smalltalk.Error]
 }),
 smalltalk.TestCase);
 
@@ -216,7 +216,7 @@ smalltalk.ExampleTest);
 
 
 
-smalltalk.addClass('ProgressBar', smalltalk.TabWidget, ['percent', 'progressDiv'], 'SUnit');
+smalltalk.addClass('ProgressBar', smalltalk.TabWidget, ['percent', 'progressDiv', 'div'], 'SUnit');
 smalltalk.addMethod(
 '_percent',
 smalltalk.method({
@@ -254,10 +254,11 @@ selector: 'renderOn:',
 category: 'rendering',
 fn: function (html){
 var self=this;
-(function($rec){smalltalk.send($rec, "_class_", ["progress_bar"]);return smalltalk.send($rec, "_with_", [(function(){return (function($rec){smalltalk.send($rec, "_class_", ["progress"]);return smalltalk.send($rec, "_style_", [smalltalk.send(smalltalk.send("width:", "__comma", [smalltalk.send(smalltalk.send(self, "_percent", []), "_asString", [])]), "__comma", [unescape("%25")])]);})(smalltalk.send(html, "_div", []));})]);})(smalltalk.send(html, "_div", []));
+self['@div']=(function($rec){smalltalk.send($rec, "_class_", ["progress_bar"]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(html, "_div", []));
+smalltalk.send(self, "_renderProgressBar", []);
 return self;},
-source: unescape('renderOn%3A%20html%20%0A%09html%20div%20%0A%09%09class%3A%20%27progress_bar%27%3B%0A%09%09with%3A%20%5B%0A%09%09%09html%20div%20%0A%09%09%09%09class%3A%20%27progress%27%3B%0A%09%09%09%09style%3A%20%27width%3A%27%2C%20self%20percent%20asString%2C%20%27%25%27%5D'),
-messageSends: ["class:", "with:", "style:", unescape("%2C"), "asString", "percent", "div"],
+source: unescape('renderOn%3A%20html%20%0A%09div%20%3A%3D%20html%20div%20%0A%09%09class%3A%20%27progress_bar%27%3B%0A%09%09yourself.%0A%09self%20renderProgressBar'),
+messageSends: ["class:", "yourself", "div", "renderProgressBar"],
 referencedClasses: []
 }),
 smalltalk.ProgressBar);
@@ -270,10 +271,25 @@ category: 'updating',
 fn: function (aNumber){
 var self=this;
 smalltalk.send(self, "_percent_", [aNumber]);
-smalltalk.send(self, "_update", []);
+smalltalk.send(self, "_renderProgressBar", []);
+return self;},
+source: unescape('updatePercent%3A%20aNumber%0A%09self%20percent%3A%20aNumber.%0A%09self%20renderProgressBar'),
+messageSends: ["percent:", "renderProgressBar"],
+referencedClasses: []
+}),
+smalltalk.ProgressBar);
+
+smalltalk.addMethod(
+'_renderProgressBar',
+smalltalk.method({
+selector: 'renderProgressBar',
+category: 'rendering',
+fn: function (){
+var self=this;
+smalltalk.send(self['@div'], "_contents_", [(function(html){return (function($rec){smalltalk.send($rec, "_class_", ["progress"]);return smalltalk.send($rec, "_style_", [smalltalk.send(smalltalk.send("width:", "__comma", [smalltalk.send(smalltalk.send(self, "_percent", []), "_asString", [])]), "__comma", [unescape("%25")])]);})(smalltalk.send(html, "_div", []));})]);
 return self;},
-source: unescape('updatePercent%3A%20aNumber%0A%09self%20percent%3A%20aNumber.%0A%09self%20update'),
-messageSends: ["percent:", "update"],
+source: unescape('renderProgressBar%0A%09div%20contents%3A%20%5B%3Ahtml%20%7C%0A%09%09html%20div%20%0A%09%09%09class%3A%20%27progress%27%3B%0A%09%09%09style%3A%20%27width%3A%27%2C%20self%20percent%20asString%2C%20%27%25%27%5D'),
+messageSends: ["contents:", "class:", "style:", unescape("%2C"), "asString", "percent", "div"],
 referencedClasses: []
 }),
 smalltalk.ProgressBar);
@@ -531,7 +547,7 @@ smalltalk.send(aCollection, "_do_", [(function(each){return smalltalk.send((func
 return self;},
 source: unescape('run%3A%20aCollection%0A%09result%20%3A%3D%20TestResult%20new.%0A%09self%20%0A%09%09updateStatusDiv%3B%0A%09%09updateMethodsList.%0A%09self%20progressBar%20updatePercent%3A%200.%0A%09result%20total%3A%20%28aCollection%20inject%3A%200%20into%3A%20%5B%3Aacc%20%3Aeach%20%7C%20acc%20+%20each%20methods%20size%5D%29.%0A%09aCollection%20do%3A%20%5B%3Aeach%20%7C%20%0A%09%09%5Beach%20runCaseFor%3A%20result.%0A%09%09self%20progressBar%20updatePercent%3A%20result%20runs%20/%20result%20total%20*%20100.%0A%09%09self%20updateStatusDiv.%0A%09%09self%20updateMethodsList%5D%20valueWithTimeout%3A%20100%5D.'),
 messageSends: ["new", "updateStatusDiv", "updateMethodsList", "updatePercent:", "progressBar", "total:", "inject:into:", unescape("+"), "size", "methods", "do:", "valueWithTimeout:", "runCaseFor:", unescape("*"), unescape("/"), "runs", "total"],
-referencedClasses: []
+referencedClasses: [smalltalk.nil]
 }),
 smalltalk.TestRunner);
 
@@ -547,7 +563,7 @@ self['@result']=smalltalk.send(smalltalk.TestResult, "_new", []);
 return self;},
 source: unescape('initialize%0A%09super%20initialize.%0A%09result%20%3A%3D%20TestResult%20new'),
 messageSends: ["initialize", "new"],
-referencedClasses: []
+referencedClasses: [smalltalk.nil]
 }),
 smalltalk.TestRunner);
 

+ 103 - 16
js/boot.js

@@ -221,7 +221,7 @@ function Smalltalk(){
     /* Handles Smalltalk message send. Automatically converts undefined to the nil object.
        If the receiver does not understand the selector, call its #doesNotUnderstand: method */
 
-    st.send = function(receiver, selector, args, klass) {
+    sendWithoutContext = function(receiver, selector, args, klass) {
 	if(typeof receiver === "undefined") {
 	    receiver = nil;
 	}
@@ -233,13 +233,67 @@ function Smalltalk(){
 	return messageNotUnderstood(receiver, selector, args);
     };
 
+
+    /* Handles unhandled errors during message sends */
+
+    sendWithContext = function(receiver, selector, args, klass) {
+	if(thisContext) {
+	     return withContextSend(receiver, selector, args, klass);
+	} else {
+	    try {return withContextSend(receiver, selector, args, klass)}
+	    catch(error) {
+		// Reset the context stack in any case
+		thisContext = undefined;
+		if(error.smalltalkError) {
+		    handleError(error);
+		} else {
+		    throw(error);
+		}
+	    }
+	}
+    };
+
+    /* Same as sendWithoutContext but creates a methodContext. */
+
+    withContextSend = function(receiver, selector, args, klass) {
+	var call, context;
+	if(typeof receiver === "undefined") {
+	    receiver = nil;
+	}
+	if(!klass && receiver.klass && receiver[selector]) {
+	    context = pushContext(receiver, selector, args);
+	    call = receiver[selector].apply(receiver, args);
+	    popContext(context);
+	    return call;
+	} else if(klass && klass.fn.prototype[selector]) {
+	    context = pushContext(receiver, selector, args);
+	    call = klass.fn.prototype[selector].apply(receiver, args);
+	    popContext(context);
+	    return call;
+	}
+	return messageNotUnderstood(receiver, selector, args);
+    };
+
+    /*  */
+
+    st.send = sendWithContext;
+
+
+    /* Handles Smalltalk errors. Triggers the registered ErrorHandler 
+       (See the Smalltalk class ErrorHandler and its subclasses */
+    
+    function handleError(error) {
+	thisContext = undefined;
+	smalltalk.ErrorHandler._current()._handleError_(error);
+    }
+
     /* Handles #dnu: *and* JavaScript method calls.
        if the receiver has no klass, we consider it a JS object (outside of the
        Jtalk system). Else assume that the receiver understands #doesNotUnderstand: */
 
     function messageNotUnderstood(receiver, selector, args) {
 	/* Handles JS method calls. */
-	if(receiver.klass === undefined) {
+	if(receiver.klass === undefined || receiver.allowJavaScriptCalls) {
 	    return callJavaScriptMethod(receiver, selector, args);
 	}
 
@@ -248,7 +302,7 @@ function Smalltalk(){
 	
 	return receiver._doesNotUnderstand_(
 	    st.Message._new()
-		._selector_(convertSelector(selector))
+		._selector_(st.convertSelector(selector))
 		._arguments_(args)
 	);
     };
@@ -272,15 +326,30 @@ function Smalltalk(){
 	    return jsProperty
 	}
 	smalltalk.Error._signal_(receiver + ' is not a Jtalk object and "' + jsSelector + '" is undefined')
-    }
+    };
 
 	
+    /* Handle thisContext pseudo variable */
+    
+    pushContext = function(receiver, selector, temps) {
+	if(thisContext) {
+	    return thisContext = thisContext.newContext({receiver: receiver, selector: selector, temps: temps});
+	} else {
+	    return thisContext = new SmalltalkMethodContext({receiver: receiver, selector: selector, temps: temps});
+	}
+    };
+
+    popContext = function(context) {
+	if(context) {
+	    context.removeYourself();
+	}
+    };
 
     /* Convert a string to a valid smalltalk selector.
        if you modify the following functions, also change String>>asSelector
        accordingly */
 
-    function convertSelector(selector) {
+    st.convertSelector = function(selector) {
 	if(selector.match(/__/)) {
 	    return convertBinarySelector(selector);
 	} else {
@@ -327,24 +396,41 @@ function Smalltalk(){
     };
 }
 
-function SmalltalkMethodContext() {
-    this.stack = [];
+function SmalltalkMethodContext(spec) {
+    var that = this;
+    spec = spec || {};
+    that.homeContext = spec.homeContext;
+    that.selector = spec.selector;
+    that.receiver = spec.receiver;
+    that.temps = spec.temps || {};
+
+    that.newContext = function(spec) {
+	spec = spec || {};
+	return new SmalltalkMethodContext({homeContext: that, receiver: spec.receiver, selector: spec.selector, temps: spec.temps});
+    }
 
-    this.push = function(context) {
-	stack.push(context);
-    };
-    
-    this.pop = function() {
-	stack.pop();
-    };
+    that.removeYourself = function() {
+	thisContext = that.homeContext;
+    }
 }
 
 /* Global Smalltalk objects. nil and thisContext shouldn't be globals. */
 
 var nil = new SmalltalkNil();
 var smalltalk = new Smalltalk();
-var thisContext = nil;
+var thisContext = undefined;
+
 
+/* Utilities */
+
+Array.prototype.remove = function(s){
+    var index = this.indexOf(s);
+    if(this.indexOf(s) != -1)this.splice(index, 1);
+}
+
+if(this.jQuery) {
+    this.jQuery.allowJavaScriptCalls = true;
+}
 
 /****************************************************************************************/
 
@@ -374,7 +460,8 @@ smalltalk.mapClassName("Array", "Kernel", Array, smalltalk.SequenceableCollectio
 smalltalk.mapClassName("RegularExpression", "Kernel", RegExp, smalltalk.String);
 
 smalltalk.mapClassName("Error", "Kernel", Error, smalltalk.Object);
+smalltalk.mapClassName("MethodContext", "Kernel", SmalltalkMethodContext, smalltalk.Object);
 
 if(this.CanvasRenderingContext2D) {
     smalltalk.mapClassName("CanvasRenderingContext", "Canvas", CanvasRenderingContext2D, smalltalk.Object);
-}
+}

+ 26 - 3
st/Canvas.st

@@ -94,7 +94,11 @@ with: anObject
 
 initialize
     super initialize.
-    root := TagBrush fromString: 'div' canvas: self
+    root ifNil: [root := TagBrush fromString: 'div' canvas: self]
+!
+
+initializeFromJQuery: aJQuery
+    root := TagBrush fromJQuery: aJQuery canvas: self
 ! !
 
 !HTMLCanvas methodsFor: 'tags'!
@@ -207,6 +211,15 @@ canvas
 	^self tag: 'canvas'
 ! !
 
+!HTMLCanvas class methodsFor: 'instance creation'!
+
+onJQuery: aJQuery
+	^self basicNew
+		initializeFromJQuery: aJQuery;
+		initialize;
+		yourself
+! !
+
 Object subclass: #TagBrush
 	instanceVariableNames: 'canvas element'
 	category: 'Canvas'!
@@ -336,6 +349,11 @@ onClick: aBlock
 initializeFromString: aString canvas: aCanvas
     element := self createElementFor: aString.
     canvas := aCanvas
+!
+
+initializeFromJQuery: aJQuery canvas: aCanvas
+    element := aJQuery jquery get: 0.
+    canvas := aCanvas
 ! !
 
 !TagBrush methodsFor: 'private'!
@@ -354,6 +372,12 @@ fromString: aString canvas: aCanvas
     ^self new
 	initializeFromString: aString canvas: aCanvas;
 	yourself
+!
+
+fromJQuery: aJQuery canvas: aCanvas
+    ^self new
+	initializeFromJQuery: aJQuery canvas: aCanvas;
+	yourself
 ! !
 
 Object subclass: #Widget
@@ -399,8 +423,7 @@ appendToBrush: aTagBrush
 !
 
 appendToJQuery: aJQuery
-    self render.
-    aJQuery append: self root asJQuery
+   self renderOn: (HTMLCanvas onJQuery: aJQuery)
 ! !
 
 !Widget methodsFor: 'rendering'!

+ 3 - 2
st/Compiler.st

@@ -461,7 +461,8 @@ recompile: aClass
 
 recompileAll
 	Smalltalk current classes do: [:each |
-		self recompile: each]
+		Transcript show: each; cr.
+		[self recompile: each] valueWithTimeout: 100]
 !
 
 setupClass: aClass
@@ -690,6 +691,6 @@ Object subclass: #DoIt
 
 !DoIt methodsFor: ''!
 
-doIt ^[<self["@"+'foo']>] value
+doIt ^[Compiler new recompileAll] value
 ! !
 

+ 86 - 37
st/IDE.st

@@ -1,5 +1,5 @@
 Widget subclass: #TabManager
-	instanceVariableNames: 'selectedTab tabs opened'
+	instanceVariableNames: 'selectedTab tabs opened ul'
 	category: 'IDE'!
 
 !TabManager methodsFor: 'accessing'!
@@ -40,18 +40,19 @@ onWindowResize: aBlock
 
 open
     opened ifFalse: [
-	self root asJQuery show.
 	'body' asJQuery addClass: 'jtalkBody'.
 	'#jtalk' asJQuery show.
+	ul asJQuery show.
 	self updateBodyMargin.
-	selectedTab root asJQuery show.
+	selectedTab show.
 	opened := true]
 !
 
 close
     opened ifTrue: [
-	self root asJQuery hide.
 	'#jtalk' asJQuery hide.
+	ul asJQuery hide.
+	selectedTab hide.
 	self removeBodyMargin.
 	'body' asJQuery removeClass: 'jtalkBody'.
 	opened := false]
@@ -65,15 +66,16 @@ selectTab: aWidget
     self open.
     selectedTab := aWidget.
     self tabs do: [:each |
-	each root asJQuery hide].
-    aWidget root asJQuery show.
+	each hide].
+    aWidget show.
+	
     self update
 !
 
 closeTab: aWidget
     self removeTab: aWidget.
     self selectTab: self tabs last.
-    aWidget root asJQuery remove.
+    aWidget remove.
     self update
 ! !
 
@@ -82,7 +84,7 @@ closeTab: aWidget
 addTab: aWidget
     self tabs add: aWidget.
     '#jtalk' asJQuery append: aWidget.
-    aWidget root asJQuery hide
+    aWidget hide
 !
 
 removeTab: aWidget
@@ -111,19 +113,10 @@ initialize
 !TabManager methodsFor: 'rendering'!
 
 renderOn: html
-    html ul
-	id: 'jtalkTabs';
-	with: [
-	    html li 
-		class: 'closeAll';
-		with: 'x';
-		onClick: [self close].
-	    self tabs do: [:each |
-		self renderTabFor: each on: html].
-	    html li
-		class: 'newtab';
-		with: ' + ';
-		onClick: [self newBrowserTab]]
+	ul := html ul
+		id: 'jtalkTabs';
+		yourself.
+	self renderTabs
 !
 
 renderTabFor: aWidget on: html
@@ -140,6 +133,26 @@ renderTabFor: aWidget on: html
 		class: 'close';
 		with: 'x';
 		onClick: [self closeTab: aWidget]]]
+!
+
+renderTabs
+	ul contents: [:html |
+	    html li 
+		class: 'closeAll';
+		with: 'x';
+		onClick: [self close].
+	    self tabs do: [:each |
+		self renderTabFor: each on: html].
+	    html li
+		class: 'newtab';
+		with: ' + ';
+		onClick: [self newBrowserTab]]
+! !
+
+!TabManager methodsFor: 'updating'!
+
+update
+	self renderTabs
 ! !
 
 TabManager class instanceVariableNames: 'current'!
@@ -155,7 +168,7 @@ new
 ! !
 
 Widget subclass: #TabWidget
-	instanceVariableNames: ''
+	instanceVariableNames: 'div'
 	category: 'IDE'!
 
 !TabWidget methodsFor: 'accessing'!
@@ -167,29 +180,49 @@ label
 !TabWidget methodsFor: 'actions'!
 
 open
-    TabManager current
-	addTab: self;
-	selectTab: self
+    TabManager current addTab: self.
+    TabManager current selectTab: self
+!
+
+show
+	div asJQuery show
+!
+
+hide
+	div asJQuery hide
+!
+
+remove
+	div asJQuery remove
 ! !
 
 !TabWidget methodsFor: 'rendering'!
 
 renderOn: html
-    html root
-	class: 'jtalkTool';
-	with: [
-	    html div
-		class: 'jt_box';
-		with: [self renderBoxOn: html].
-	    html div
-		class: 'jt_buttons';
-		with: [self renderButtonsOn: html]]
+	div := html div
+		class: 'jtalkTool';
+		yourself.
+	self renderTab
 !
 
 renderBoxOn: html
 !
 
 renderButtonsOn: html
+!
+
+update
+	self renderTab
+!
+
+renderTab
+	div contents: [:html |
+	    html div
+		class: 'jt_box';
+		with: [self renderBoxOn: html].
+	    html div
+		class: 'jt_buttons';
+		with: [self renderButtonsOn: html]]
 ! !
 
 !TabWidget methodsFor: 'testing'!
@@ -593,7 +626,7 @@ compileMethodDefinitionFor: aClass
     node := compiler parse: source.
     node isParseFailure ifTrue: [
 	^self alert: 'PARSE ERROR: ', node reason, ', position: ', node position asString].
-    compiler currentClass: selectedClass.
+    compiler currentClass: aClass.
     method := compiler eval: (compiler compileNode: node).
     method category: selectedProtocol.
     compiler unknownVariables do: [:each |
@@ -818,7 +851,7 @@ renderButtonsOn: html
     self updateSourceAndButtons
 !
 
-renderInputOn: html
+renderInputOn: html 
 	input := html input 
 		class: 'implementors';
 		yourself.
@@ -1301,7 +1334,7 @@ inspectOn: anInspector
 	| variables |
 	variables := Dictionary new.
 	variables at: '#self' put: self.
-	self class instanceVariableNames do: [:each |
+	self class allInstanceVariableNames do: [:each |
 		variables at: each put: (self instVarAt: each)].
 	anInspector 
 		setLabel: self printString;
@@ -1350,6 +1383,22 @@ inspectOn: anInspector
 	anInspector setLabel: label
 ! !
 
+!MethodContext methodsFor: '*IDE'!
+
+inspectOn: anInspector
+	| variables |
+	variables := Dictionary new.
+	variables at: '#self' put: self.
+	variables at: '#home' put: self home.
+	variables at: '#receiver' put: self receiver.
+	variables at: '#selector' put: self selector.
+	self class instanceVariableNames do: [:each |
+		variables at: each put: (self instVarAt: each)].
+	anInspector 
+		setLabel: self printString;
+		setVariables: variables
+! !
+
 !Dictionary methodsFor: '*IDE'!
 
 inspectOn: anInspector

+ 24 - 15
st/JQuery.st

@@ -28,6 +28,12 @@ empty
     ^self call: 'empty'
 ! !
 
+!JQuery methodsFor: 'accessing'!
+
+jquery
+	^jquery
+! !
+
 !JQuery methodsFor: 'attributes'!
 
 removeAttribute: aString
@@ -52,11 +58,11 @@ val: aString
 !JQuery methodsFor: 'css'!
 
 cssAt: aString
-	{'return self[''@jquery''].css(aString)'}
+	<return self['@jquery'].css(aString)>
 !
 
 cssAt: aString put: anotherString
-    {'self[''@jquery''].css(aString, anotherString)'}
+    <self['@jquery'].css(aString, anotherString)>
 !
 
 addClass: aString
@@ -170,7 +176,7 @@ remove
 
 on: anEventString do: aBlock
     "Attach aBlock for anEventString on the element"
-    {'self[''@jquery''].bind(anEventString, function(e){aBlock(e, self)})'}
+    <self['@jquery'].bind(anEventString, function(e){aBlock(e, self)})>
 !
 
 removeEvents: aString
@@ -187,11 +193,11 @@ initializeWithJQueryObject: anObject
 !JQuery methodsFor: 'private'!
 
 call: aString
-	{'return self[''@jquery''][aString]()'}
+	<return self['@jquery'][aString]()>
 !
 
 call: aString withArgument: anObject
-    {'return self[''@jquery''][aString](anObject)'}
+    <return self['@jquery'][aString](anObject)>
 ! !
 
 !JQuery methodsFor: 'testing'!
@@ -205,7 +211,7 @@ hasClass: aString
 
 fromString: aString
     | newJQuery |
-    {'newJQuery = jQuery(String(aString))'}.
+    <newJQuery = jQuery(String(aString))>.
     ^self from: newJQuery
 !
 
@@ -216,15 +222,21 @@ from: anObject
 !
 
 window
-	{'return self._from_(jQuery(window))'}
+	<return self._from_(jQuery(window))>
 !
 
 body
-	{'return self._from_(jQuery(body))'}
+	<return self._from_(jQuery('body'))>
 !
 
 document
-	{'return self._from_(jQuery(document))'}
+	<return self._from_(jQuery(document))>
+!
+
+fromElement: anElement
+    | newJQuery |
+    <newJQuery = jQuery(anElement)>.
+    ^self from: newJQuery
 ! !
 
 Object subclass: #Ajax
@@ -257,7 +269,7 @@ url: aString
 !Ajax methodsFor: 'actions'!
 
 send
-    {'jQuery.ajax(self[''@settings''])'}
+    <jQuery.ajax(self['@settings'])>
 ! !
 
 !Ajax methodsFor: 'initialization'!
@@ -278,10 +290,7 @@ url: aString
 !BlockClosure methodsFor: '*JQuery'!
 
 appendToJQuery: aJQuery
-	| canvas |
-	canvas := HTMLCanvas new.
-	self value: canvas.
-	aJQuery append: canvas
+	self value: (HTMLCanvas onJQuery: aJQuery)
 ! !
 
 !String methodsFor: '*JQuery'!
@@ -291,7 +300,7 @@ asJQuery
 !
 
 appendToJQuery: aJQuery
-    {'aJQuery._appendElement_(String(self))'}
+    <aJQuery._appendElement_(String(self))>
 ! !
 
 !HTMLCanvas methodsFor: '*JQuery'!

+ 103 - 2
st/Kernel.st

@@ -128,6 +128,10 @@ doesNotUnderstand: aMessage
 		receiver: self;
 		message: aMessage;
 		signal
+!
+
+halt
+	self error: 'Halt encountered'
 ! !
 
 !Object methodsFor: 'initialization'!
@@ -357,6 +361,14 @@ protocolsDo: aBlock
  			add: m]. 
 	self protocols do: [:category |
 		aBlock value: category value: (methodsByCategory at: category)]
+!
+
+allInstanceVariableNames
+	| result |
+	result := self instanceVariableNames.
+	self superclass ifNotNil: [
+	    result addAll: self superclass allInstanceVariableNames].
+	^result
 ! !
 
 !Behavior methodsFor: 'instance creation'!
@@ -1638,7 +1650,7 @@ compile: aString
 !
 
 exec: aString
-	<return self.exec(aString)>
+	<return self.exec(aString) || nil>
 !
 
 test: aString
@@ -1667,12 +1679,16 @@ messageText
 
 messageText: aString
 	messageText := aString
+!
+
+context
+	<return self.context>
 ! !
 
 !Error methodsFor: 'signaling'!
 
 signal
-	<console.log(self._messageText()); throw(self)>
+	<self.context = thisContext; self.smalltalkError = true; throw(self)>
 ! !
 
 !Error class methodsFor: 'instance creation'!
@@ -1683,6 +1699,36 @@ signal: aString
 		signal
 ! !
 
+Object subclass: #MethodContext
+	instanceVariableNames: ''
+	category: 'Kernel'!
+
+!MethodContext methodsFor: 'accessing'!
+
+receiver
+	<return self.receiver>
+!
+
+selector
+	<return smalltalk.convertSelector(self.selector)>
+!
+
+home
+	<return self.homeContext>
+!
+
+temps
+	<return self.temps>
+!
+
+printString
+	^super printString, '(', self asString, ')'
+!
+
+asString
+	^self receiver class printString, ' >> ', self selector
+! !
+
 Object subclass: #Association
 	instanceVariableNames: 'key value'
 	category: 'Kernel'!
@@ -2286,3 +2332,58 @@ messageText
 	^self receiver asString, ' does not understand #', self message selector
 ! !
 
+Object subclass: #ErrorHandler
+	instanceVariableNames: ''
+	category: 'Kernel'!
+
+!ErrorHandler methodsFor: 'error handling'!
+
+handleError: anError
+	anError context ifNotNil: [self logErrorContext: anError context].
+	self logError: anError
+! !
+
+!ErrorHandler methodsFor: 'private'!
+
+logContext: aContext
+	aContext home ifNotNil: [
+		self logContext: aContext home].
+	self log: aContext receiver asString, '>>', aContext selector
+!
+
+logErrorContext: aContext
+	aContext ifNotNil: [
+		aContext home ifNotNil: [
+			self logContext: aContext home]]
+!
+
+logError: anError
+	self log: anError messageText
+!
+
+log: aString
+	console log: aString
+! !
+
+ErrorHandler class instanceVariableNames: 'current'!
+
+!ErrorHandler class methodsFor: 'accessing'!
+
+current
+	^current
+!
+
+setCurrent: anHandler
+	current := anHandler
+! !
+
+!ErrorHandler class methodsFor: 'initialization'!
+
+initialize
+	self register
+!
+
+register
+	ErrorHandler setCurrent: self new
+! !
+

+ 12 - 7
st/SUnit.st

@@ -87,7 +87,7 @@ testError
 ! !
 
 TabWidget subclass: #ProgressBar
-	instanceVariableNames: 'percent progressDiv'
+	instanceVariableNames: 'percent progressDiv div'
 	category: 'SUnit'!
 
 !ProgressBar methodsFor: 'accessing'!
@@ -103,19 +103,24 @@ percent: aNumber
 !ProgressBar methodsFor: 'rendering'!
 
 renderOn: html 
-	html div 
+	div := html div 
 		class: 'progress_bar';
-		with: [
-			html div 
-				class: 'progress';
-				style: 'width:', self percent asString, '%']
+		yourself.
+	self renderProgressBar
+!
+
+renderProgressBar
+	div contents: [:html |
+		html div 
+			class: 'progress';
+			style: 'width:', self percent asString, '%']
 ! !
 
 !ProgressBar methodsFor: 'updating'!
 
 updatePercent: aNumber
 	self percent: aNumber.
-	self update
+	self renderProgressBar
 ! !
 
 Error subclass: #TestFailure