1
0
Selaa lähdekoodia

- 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 vuotta sitten
vanhempi
commit
2737561109
15 muutettua tiedostoa jossa 984 lisäystä ja 192 poistoa
  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 (){
 fn: function (){
 var self=this;
 var self=this;
 smalltalk.send(self, "_initialize", [], smalltalk.Object);
 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;},
 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);
 smalltalk.HTMLCanvas);
 
 
@@ -299,7 +299,7 @@ return smalltalk.send(smalltalk.TagBrush, "_fromString_canvas_", [aString, self]
 return self;},
 return self;},
 source: unescape('newTag%3A%20aString%0A%20%20%20%20%5ETagBrush%20fromString%3A%20aString%20canvas%3A%20self'),
 source: unescape('newTag%3A%20aString%0A%20%20%20%20%5ETagBrush%20fromString%3A%20aString%20canvas%3A%20self'),
 messageSends: ["fromString:canvas:"],
 messageSends: ["fromString:canvas:"],
-referencedClasses: [smalltalk.TagBrush]
+referencedClasses: [smalltalk.nil]
 }),
 }),
 smalltalk.HTMLCanvas);
 smalltalk.HTMLCanvas);
 
 
@@ -693,6 +693,36 @@ referencedClasses: []
 }),
 }),
 smalltalk.HTMLCanvas);
 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');
 smalltalk.addClass('TagBrush', smalltalk.Object, ['canvas', 'element'], 'Canvas');
@@ -1138,6 +1168,22 @@ referencedClasses: []
 }),
 }),
 smalltalk.TagBrush);
 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(
 smalltalk.addMethod(
 '_fromString_canvas_',
 '_fromString_canvas_',
@@ -1154,6 +1200,21 @@ referencedClasses: []
 }),
 }),
 smalltalk.TagBrush.klass);
 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.addClass('Widget', smalltalk.Object, ['root'], 'Canvas');
 smalltalk.addMethod(
 smalltalk.addMethod(
@@ -1193,12 +1254,11 @@ selector: 'appendToJQuery:',
 category: 'adding',
 category: 'adding',
 fn: function (aJQuery){
 fn: function (aJQuery){
 var self=this;
 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;},
 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);
 smalltalk.Widget);
 
 

+ 12 - 12
js/Compiler.js

@@ -288,7 +288,7 @@ return (function($rec){smalltalk.send($rec, "_receiver_", [smalltalk.send(self,
 return 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'),
 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:"],
 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);
 smalltalk.SendNode);
 
 
@@ -525,7 +525,7 @@ return (function($rec){smalltalk.send($rec, "_nodes_", [smalltalk.send(self, "_n
 return self;},
 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'),
 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"],
 messageSends: ["nodes:", "nodes", "temps:", "temps", "yourself", "new"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.BlockSequenceNode]
 }),
 }),
 smalltalk.SequenceNode);
 smalltalk.SequenceNode);
 
 
@@ -1005,7 +1005,7 @@ return smalltalk.send(smalltalk.send(smalltalk.DoIt, "_new", []), "_doIt", []);
 return self;},
 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'),
 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"],
 messageSends: ["addCompiledMethod:", "eval:", "compileExpression:", "doIt", "new"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.DoIt]
 }),
 }),
 smalltalk.Compiler);
 smalltalk.Compiler);
 
 
@@ -1055,7 +1055,7 @@ return smalltalk.send(self, "_compileNode_", [smalltalk.send(self, "_parseExpres
 return self;},
 return self;},
 source: unescape('compileExpression%3A%20aString%0A%09self%20currentClass%3A%20DoIt.%0A%09%5Eself%20compileNode%3A%20%28self%20parseExpression%3A%20aString%29'),
 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:"],
 messageSends: ["currentClass:", "compileNode:", "parseExpression:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.DoIt]
 }),
 }),
 smalltalk.Compiler);
 smalltalk.Compiler);
 
 
@@ -1478,11 +1478,11 @@ selector: 'recompileAll',
 category: 'compiling',
 category: 'compiling',
 fn: function (){
 fn: function (){
 var self=this;
 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;},
 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);
 smalltalk.Compiler);
 
 
@@ -1573,11 +1573,11 @@ selector: 'doIt',
 category: '',
 category: '',
 fn: function (){
 fn: function (){
 var self=this;
 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;},
 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);
 smalltalk.DoIt);
 
 

+ 1 - 1
js/Examples.js

@@ -271,7 +271,7 @@ self['@movingPiece']=smalltalk.send(smalltalk.TetrisPiece, "_atRandom", []);
 return self;},
 return self;},
 source: unescape('newPiece%0A%09movingPiece%20%3A%3D%20TetrisPiece%20atRandom'),
 source: unescape('newPiece%0A%09movingPiece%20%3A%3D%20TetrisPiece%20atRandom'),
 messageSends: ["atRandom"],
 messageSends: ["atRandom"],
-referencedClasses: []
+referencedClasses: [smalltalk.TetrisPiece]
 }),
 }),
 smalltalk.Tetris);
 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(
 smalltalk.addMethod(
 '_tabs',
 '_tabs',
 smalltalk.method({
 smalltalk.method({
@@ -115,10 +115,10 @@ selector: 'open',
 category: 'actions',
 category: 'actions',
 fn: function (){
 fn: function (){
 var self=this;
 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;},
 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: []
 referencedClasses: []
 }),
 }),
 smalltalk.TabManager);
 smalltalk.TabManager);
@@ -130,10 +130,10 @@ selector: 'close',
 category: 'actions',
 category: 'actions',
 fn: function (){
 fn: function (){
 var self=this;
 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;},
 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: []
 referencedClasses: []
 }),
 }),
 smalltalk.TabManager);
 smalltalk.TabManager);
@@ -149,7 +149,7 @@ smalltalk.send(smalltalk.Browser, "_open", []);
 return self;},
 return self;},
 source: unescape('newBrowserTab%0A%20%20%20%20Browser%20open'),
 source: unescape('newBrowserTab%0A%20%20%20%20Browser%20open'),
 messageSends: ["open"],
 messageSends: ["open"],
-referencedClasses: []
+referencedClasses: [smalltalk.nil]
 }),
 }),
 smalltalk.TabManager);
 smalltalk.TabManager);
 
 
@@ -162,12 +162,12 @@ fn: function (aWidget){
 var self=this;
 var self=this;
 smalltalk.send(self, "_open", []);
 smalltalk.send(self, "_open", []);
 self['@selectedTab']=aWidget;
 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", []);
 smalltalk.send(self, "_update", []);
 return self;},
 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: []
 referencedClasses: []
 }),
 }),
 smalltalk.TabManager);
 smalltalk.TabManager);
@@ -181,11 +181,11 @@ fn: function (aWidget){
 var self=this;
 var self=this;
 smalltalk.send(self, "_removeTab_", [aWidget]);
 smalltalk.send(self, "_removeTab_", [aWidget]);
 smalltalk.send(self, "_selectTab_", [smalltalk.send(smalltalk.send(self, "_tabs", []), "_last", [])]);
 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", []);
 smalltalk.send(self, "_update", []);
 return self;},
 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: []
 referencedClasses: []
 }),
 }),
 smalltalk.TabManager);
 smalltalk.TabManager);
@@ -199,10 +199,10 @@ fn: function (aWidget){
 var self=this;
 var self=this;
 smalltalk.send(smalltalk.send(self, "_tabs", []), "_add_", [aWidget]);
 smalltalk.send(smalltalk.send(self, "_tabs", []), "_add_", [aWidget]);
 smalltalk.send(smalltalk.send(unescape("%23jtalk"), "_asJQuery", []), "_append_", [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;},
 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: []
 referencedClasses: []
 }),
 }),
 smalltalk.TabManager);
 smalltalk.TabManager);
@@ -239,7 +239,7 @@ smalltalk.send(self, "_selectTab_", [smalltalk.send(smalltalk.send(self, "_tabs"
 return self;},
 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'),
 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:"],
 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);
 smalltalk.TabManager);
 
 
@@ -250,10 +250,11 @@ selector: 'renderOn:',
 category: 'rendering',
 category: 'rendering',
 fn: function (html){
 fn: function (html){
 var self=this;
 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;},
 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: []
 referencedClasses: []
 }),
 }),
 smalltalk.TabManager);
 smalltalk.TabManager);
@@ -276,6 +277,36 @@ referencedClasses: []
 }),
 }),
 smalltalk.TabManager);
 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.TabManager.klass.iVarNames = ['current'];
 smalltalk.addMethod(
 smalltalk.addMethod(
@@ -309,7 +340,7 @@ referencedClasses: []
 smalltalk.TabManager.klass);
 smalltalk.TabManager.klass);
 
 
 
 
-smalltalk.addClass('TabWidget', smalltalk.Widget, [], 'IDE');
+smalltalk.addClass('TabWidget', smalltalk.Widget, ['div'], 'IDE');
 smalltalk.addMethod(
 smalltalk.addMethod(
 '_label',
 '_label',
 smalltalk.method({
 smalltalk.method({
@@ -332,10 +363,11 @@ selector: 'open',
 category: 'actions',
 category: 'actions',
 fn: function (){
 fn: function (){
 var self=this;
 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;},
 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]
 referencedClasses: [smalltalk.TabManager]
 }),
 }),
 smalltalk.TabWidget);
 smalltalk.TabWidget);
@@ -347,10 +379,11 @@ selector: 'renderOn:',
 category: 'rendering',
 category: 'rendering',
 fn: function (html){
 fn: function (html){
 var self=this;
 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;},
 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: []
 referencedClasses: []
 }),
 }),
 smalltalk.TabWidget);
 smalltalk.TabWidget);
@@ -400,6 +433,81 @@ referencedClasses: []
 }),
 }),
 smalltalk.TabWidget);
 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(
 smalltalk.addMethod(
 '_open',
 '_open',
@@ -1241,7 +1349,7 @@ smalltalk.send(self['@selectedProtocol'], "_ifNil_", [(function(){return self['@
 compiler=smalltalk.send(smalltalk.Compiler, "_new", []);
 compiler=smalltalk.send(smalltalk.Compiler, "_new", []);
 node=smalltalk.send(compiler, "_parse_", [source]);
 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(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])]);
 method=smalltalk.send(compiler, "_eval_", [smalltalk.send(compiler, "_compileNode_", [node])]);
 smalltalk.send(method, "_category_", [self['@selectedProtocol']]);
 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])}})})();})]);})]);
 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]);
 smalltalk.send(self, "_selectMethod_", [method]);
 return self;
 return self;
 } catch(e) {if(e.name === 'stReturn' && e.selector === '_compileMethodDefinitionFor_'){return e.fn()} throw(e)}},
 } 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:"],
 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]
 referencedClasses: [smalltalk.Compiler]
 }),
 }),
@@ -1285,7 +1393,7 @@ smalltalk.send(self['@selectedCategory'], "_ifNotNil_", [(function(){(function($
 return self;},
 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'),
 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"],
 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);
 smalltalk.Browser);
 
 
@@ -1484,7 +1592,7 @@ smalltalk.send(smalltalk.ReferencesBrowser, "_search_", [aString]);
 return self;},
 return self;},
 source: unescape('searchReferencesOf%3A%20aString%0A%09ReferencesBrowser%20search%3A%20aString'),
 source: unescape('searchReferencesOf%3A%20aString%0A%09ReferencesBrowser%20search%3A%20aString'),
 messageSends: ["search:"],
 messageSends: ["search:"],
-referencedClasses: []
+referencedClasses: [smalltalk.nil]
 }),
 }),
 smalltalk.Browser);
 smalltalk.Browser);
 
 
@@ -1499,7 +1607,7 @@ smalltalk.send(smalltalk.ReferencesBrowser, "_search_", [smalltalk.send(self['@s
 return self;},
 return self;},
 source: unescape('searchClassReferences%0A%09ReferencesBrowser%20search%3A%20selectedClass%20name'),
 source: unescape('searchClassReferences%0A%09ReferencesBrowser%20search%3A%20selectedClass%20name'),
 messageSends: ["search:", "name"],
 messageSends: ["search:", "name"],
-referencedClasses: []
+referencedClasses: [smalltalk.nil]
 }),
 }),
 smalltalk.Browser);
 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", []));
 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", [])]);})]);})]);
 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;},
 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"],
 messageSends: ["class:", "yourself", "input", "onKeyPress:", "ifTrue:", unescape("%3D"), "keyCode", "search:", "val", "asJQuery"],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -2491,11 +2599,11 @@ var self=this;
 var variables=nil;
 var variables=nil;
 variables=smalltalk.send(smalltalk.Dictionary, "_new", []);
 variables=smalltalk.send(smalltalk.Dictionary, "_new", []);
 smalltalk.send(variables, "_at_put_", [unescape("%23self"), self]);
 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);
 (function($rec){smalltalk.send($rec, "_setLabel_", [smalltalk.send(self, "_printString", [])]);return smalltalk.send($rec, "_setVariables_", [variables]);})(anInspector);
 return self;},
 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]
 referencedClasses: [smalltalk.Dictionary]
 }),
 }),
 smalltalk.Object);
 smalltalk.Object);
@@ -2562,6 +2670,28 @@ referencedClasses: []
 }),
 }),
 smalltalk.String);
 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(
 smalltalk.addMethod(
 '_inspectOn_',
 '_inspectOn_',
 smalltalk.method({
 smalltalk.method({

+ 47 - 18
js/JQuery.js

@@ -75,6 +75,21 @@ referencedClasses: []
 }),
 }),
 smalltalk.JQuery);
 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(
 smalltalk.addMethod(
 '_removeAttribute_',
 '_removeAttribute_',
 smalltalk.method({
 smalltalk.method({
@@ -144,7 +159,7 @@ fn: function (aString){
 var self=this;
 var self=this;
 return self['@jquery'].css(aString);
 return self['@jquery'].css(aString);
 return self;},
 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: [],
 messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -159,7 +174,7 @@ fn: function (aString, anotherString){
 var self=this;
 var self=this;
 self['@jquery'].css(aString, anotherString);
 self['@jquery'].css(aString, anotherString);
 return self;},
 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: [],
 messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -519,7 +534,7 @@ fn: function (anEventString, aBlock){
 var self=this;
 var self=this;
 self['@jquery'].bind(anEventString, function(e){aBlock(e, self)});
 self['@jquery'].bind(anEventString, function(e){aBlock(e, self)});
 return 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: [],
 messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -564,7 +579,7 @@ fn: function (aString){
 var self=this;
 var self=this;
 return self['@jquery'][aString]();
 return self['@jquery'][aString]();
 return self;},
 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: [],
 messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -579,7 +594,7 @@ fn: function (aString, anObject){
 var self=this;
 var self=this;
 return self['@jquery'][aString](anObject);
 return self['@jquery'][aString](anObject);
 return self;},
 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: [],
 messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -612,7 +627,7 @@ var newJQuery=nil;
 newJQuery = jQuery(String(aString));
 newJQuery = jQuery(String(aString));
 return smalltalk.send(self, "_from_", [newJQuery]);
 return smalltalk.send(self, "_from_", [newJQuery]);
 return self;},
 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:"],
 messageSends: ["from:"],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -642,7 +657,7 @@ fn: function (){
 var self=this;
 var self=this;
 return self._from_(jQuery(window));
 return self._from_(jQuery(window));
 return self;},
 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: [],
 messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -655,9 +670,9 @@ selector: 'body',
 category: 'instance creation',
 category: 'instance creation',
 fn: function (){
 fn: function (){
 var self=this;
 var self=this;
-return self._from_(jQuery(body));
+return self._from_(jQuery('body'));
 return self;},
 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: [],
 messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -672,12 +687,29 @@ fn: function (){
 var self=this;
 var self=this;
 return self._from_(jQuery(document));
 return self._from_(jQuery(document));
 return self;},
 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: [],
 messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
 smalltalk.JQuery.klass);
 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.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/')
 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;
 var self=this;
 jQuery.ajax(self['@settings']);
 jQuery.ajax(self['@settings']);
 return self;},
 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: [],
 messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -796,13 +828,10 @@ selector: 'appendToJQuery:',
 category: '*JQuery',
 category: '*JQuery',
 fn: function (aJQuery){
 fn: function (aJQuery){
 var self=this;
 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;},
 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]
 referencedClasses: [smalltalk.HTMLCanvas]
 }),
 }),
 smalltalk.BlockClosure);
 smalltalk.BlockClosure);
@@ -831,7 +860,7 @@ fn: function (aJQuery){
 var self=this;
 var self=this;
 aJQuery._appendElement_(String(self));
 aJQuery._appendElement_(String(self));
 return 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: [],
 messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),

+ 286 - 4
js/Kernel.js

@@ -678,6 +678,21 @@ referencedClasses: [smalltalk.Object]
 }),
 }),
 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(
 smalltalk.addMethod(
 '_initialize',
 '_initialize',
@@ -1092,6 +1107,24 @@ referencedClasses: [smalltalk.nil,smalltalk.Array]
 }),
 }),
 smalltalk.Behavior);
 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');
 smalltalk.addClass('Class', smalltalk.Behavior, [], 'Kernel');
@@ -4738,9 +4771,9 @@ selector: 'exec:',
 category: 'evaluating',
 category: 'evaluating',
 fn: function (aString){
 fn: function (aString){
 var self=this;
 var self=this;
-return self.exec(aString);
+return self.exec(aString) || nil;
 return self;},
 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: [],
 messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -4831,9 +4864,24 @@ selector: 'signal',
 category: 'signaling',
 category: 'signaling',
 fn: function (){
 fn: function (){
 var self=this;
 var self=this;
-console.log(self._messageText()); throw(self);
+self.context = thisContext; self.smalltalkError = true; throw(self);
 return 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: [],
 messageSends: [],
 referencedClasses: []
 referencedClasses: []
 }),
 }),
@@ -4856,6 +4904,99 @@ referencedClasses: []
 smalltalk.Error.klass);
 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.addClass('Association', smalltalk.Object, ['key', 'value'], 'Kernel');
 smalltalk.addMethod(
 smalltalk.addMethod(
 '__eq',
 '__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;},
 return self;},
 source: unescape('flatten%0A%09%5EPPFlattenParser%20on%3A%20self'),
 source: unescape('flatten%0A%09%5EPPFlattenParser%20on%3A%20self'),
 messageSends: ["on:"],
 messageSends: ["on:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPFlattenParser]
 }),
 }),
 smalltalk.PPParser);
 smalltalk.PPParser);
 
 
@@ -55,7 +55,7 @@ return smalltalk.send(smalltalk.PPSourceParser, "_on_", [self]);
 return self;},
 return self;},
 source: unescape('withSource%0A%09%5EPPSourceParser%20on%3A%20self'),
 source: unescape('withSource%0A%09%5EPPSourceParser%20on%3A%20self'),
 messageSends: ["on:"],
 messageSends: ["on:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPSourceParser]
 }),
 }),
 smalltalk.PPParser);
 smalltalk.PPParser);
 
 
@@ -70,7 +70,7 @@ return smalltalk.send(smalltalk.PPActionParser, "_on_block_", [self, aBlock]);
 return self;},
 return self;},
 source: unescape('%3D%3D%3E%20aBlock%0A%09%5EPPActionParser%20on%3A%20self%20block%3A%20aBlock'),
 source: unescape('%3D%3D%3E%20aBlock%0A%09%5EPPActionParser%20on%3A%20self%20block%3A%20aBlock'),
 messageSends: ["on:block:"],
 messageSends: ["on:block:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPActionParser]
 }),
 }),
 smalltalk.PPParser);
 smalltalk.PPParser);
 
 
@@ -85,7 +85,7 @@ return smalltalk.send(smalltalk.PPSequenceParser, "_with_with_", [self, aParser]
 return self;},
 return self;},
 source: unescape('%2C%20aParser%0A%09%5EPPSequenceParser%20with%3A%20self%20with%3A%20aParser'),
 source: unescape('%2C%20aParser%0A%09%5EPPSequenceParser%20with%3A%20self%20with%3A%20aParser'),
 messageSends: ["with:with:"],
 messageSends: ["with:with:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPSequenceParser]
 }),
 }),
 smalltalk.PPParser);
 smalltalk.PPParser);
 
 
@@ -100,7 +100,7 @@ return smalltalk.send(smalltalk.PPChoiceParser, "_with_with_", [self, aParser]);
 return self;},
 return self;},
 source: unescape('/%20aParser%0A%09%5EPPChoiceParser%20with%3A%20self%20with%3A%20aParser'),
 source: unescape('/%20aParser%0A%09%5EPPChoiceParser%20with%3A%20self%20with%3A%20aParser'),
 messageSends: ["with:with:"],
 messageSends: ["with:with:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPChoiceParser]
 }),
 }),
 smalltalk.PPParser);
 smalltalk.PPParser);
 
 
@@ -115,7 +115,7 @@ return smalltalk.send(smalltalk.PPRepeatingParser, "_on_min_", [self, (1)]);
 return self;},
 return self;},
 source: unescape('plus%0A%09%5EPPRepeatingParser%20on%3A%20self%20min%3A%201'),
 source: unescape('plus%0A%09%5EPPRepeatingParser%20on%3A%20self%20min%3A%201'),
 messageSends: ["on:min:"],
 messageSends: ["on:min:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPRepeatingParser]
 }),
 }),
 smalltalk.PPParser);
 smalltalk.PPParser);
 
 
@@ -130,7 +130,7 @@ return smalltalk.send(smalltalk.PPRepeatingParser, "_on_min_", [self, (0)]);
 return self;},
 return self;},
 source: unescape('star%0A%09%5EPPRepeatingParser%20on%3A%20self%20min%3A%200'),
 source: unescape('star%0A%09%5EPPRepeatingParser%20on%3A%20self%20min%3A%200'),
 messageSends: ["on:min:"],
 messageSends: ["on:min:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPRepeatingParser]
 }),
 }),
 smalltalk.PPParser);
 smalltalk.PPParser);
 
 
@@ -145,7 +145,7 @@ return smalltalk.send(smalltalk.PPNotParser, "_on_", [self]);
 return self;},
 return self;},
 source: unescape('not%0A%09%5EPPNotParser%20on%3A%20self'),
 source: unescape('not%0A%09%5EPPNotParser%20on%3A%20self'),
 messageSends: ["on:"],
 messageSends: ["on:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPNotParser]
 }),
 }),
 smalltalk.PPParser);
 smalltalk.PPParser);
 
 
@@ -160,7 +160,7 @@ return smalltalk.send(self, "__slash", [smalltalk.send(smalltalk.PPEpsilonParser
 return self;},
 return self;},
 source: unescape('optional%0A%09%5Eself%20/%20PPEpsilonParser%20new'),
 source: unescape('optional%0A%09%5Eself%20/%20PPEpsilonParser%20new'),
 messageSends: [unescape("/"), "new"],
 messageSends: [unescape("/"), "new"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPEpsilonParser]
 }),
 }),
 smalltalk.PPParser);
 smalltalk.PPParser);
 
 
@@ -211,7 +211,7 @@ return smalltalk.send(smalltalk.send(result, "_isParseFailure", []), "_ifTrue_if
 return self;},
 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'),
 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"],
 messageSends: ["memoizedParse:", "with:with:", "new", "ifTrue:ifFalse:", "isParseFailure", "error:", "messageFor:", "contents", "first"],
-referencedClasses: [smalltalk.nil,smalltalk.nil]
+referencedClasses: [smalltalk.PPSequenceParser,smalltalk.PPEOFParser]
 }),
 }),
 smalltalk.PPParser);
 smalltalk.PPParser);
 
 
@@ -229,7 +229,7 @@ return smalltalk.send(smalltalk.send(aStream, "_atEnd", []), "_ifFalse_ifTrue_",
 return self;},
 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'),
 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"],
 messageSends: ["ifFalse:ifTrue:", "atEnd", "reason:at:", "new", unescape("%2C"), "contents", "lf", "position"],
-referencedClasses: [smalltalk.nil,smalltalk.String]
+referencedClasses: [smalltalk.PPFailure,smalltalk.String]
 }),
 }),
 smalltalk.PPEOFParser);
 smalltalk.PPEOFParser);
 
 
@@ -247,7 +247,7 @@ return smalltalk.send(smalltalk.send(aStream, "_atEnd", []), "_ifTrue_ifFalse_",
 return self;},
 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'),
 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"],
 messageSends: ["ifTrue:ifFalse:", "atEnd", "reason:at:", "new", "position", "next"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPFailure]
 }),
 }),
 smalltalk.PPAnyParser);
 smalltalk.PPAnyParser);
 
 
@@ -317,7 +317,7 @@ return smalltalk.send(smalltalk.send(result, "__eq", [smalltalk.send(self, "_str
 return self;},
 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'),
 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"],
 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);
 smalltalk.PPStringParser);
 
 
@@ -350,7 +350,7 @@ return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(aStream, "_pe
 return self;},
 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'),
 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"],
 messageSends: ["ifTrue:ifFalse:", "and:", "notNil", "peek", "match:", "next", "reason:at:", "new", "position"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPFailure]
 }),
 }),
 smalltalk.PPCharacterParser);
 smalltalk.PPCharacterParser);
 
 
@@ -638,7 +638,7 @@ return smalltalk.send(smalltalk.send(element, "_isParseFailure", []), "_ifTrue_i
 return self;},
 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'),
 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"],
 messageSends: ["basicParse:", "ifTrue:ifFalse:", "isParseFailure", "reason:at:", "position"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.PPFailure]
 }),
 }),
 smalltalk.PPNotParser);
 smalltalk.PPNotParser);
 
 
@@ -1342,7 +1342,7 @@ nextChunk=smalltalk.send(smalltalk.send(self, "_chunkParser", []), "_parse_", [a
 return self;},
 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'),
 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:"],
 messageSends: ["ifFalse:", "atEnd", "parse:", "chunkParser", "ifNotNil:", "ifTrue:ifFalse:", "isInstructionChunk", "scanFrom:", "loadExpression:", "new", "contents", "import:"],
-referencedClasses: [smalltalk.nil]
+referencedClasses: [smalltalk.Compiler]
 }),
 }),
 smalltalk.Importer);
 smalltalk.Importer);
 
 

+ 27 - 11
js/SUnit.js

@@ -55,7 +55,7 @@ var self=this;
 return self;},
 return self;},
 source: unescape('signalFailure%3A%20aString%0A%09TestFailure%20new%0A%09%09messageText%3A%20aString%3B%0A%09%09signal'),
 source: unescape('signalFailure%3A%20aString%0A%09TestFailure%20new%0A%09%09messageText%3A%20aString%3B%0A%09%09signal'),
 messageSends: ["messageText:", "signal", "new"],
 messageSends: ["messageText:", "signal", "new"],
-referencedClasses: []
+referencedClasses: [smalltalk.nil]
 }),
 }),
 smalltalk.TestCase);
 smalltalk.TestCase);
 
 
@@ -132,7 +132,7 @@ smalltalk.send(smalltalk.send(self, "_methods", []), "_do_", [(function(each){sm
 return self;},
 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'),
 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"],
 messageSends: ["do:", "methods", "on:do:", "perform:", "addFailure:", unescape("%2C"), "name", "class", "addError:", "increaseRuns"],
-referencedClasses: [smalltalk.Error]
+referencedClasses: [smalltalk.nil,smalltalk.Error]
 }),
 }),
 smalltalk.TestCase);
 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(
 smalltalk.addMethod(
 '_percent',
 '_percent',
 smalltalk.method({
 smalltalk.method({
@@ -254,10 +254,11 @@ selector: 'renderOn:',
 category: 'rendering',
 category: 'rendering',
 fn: function (html){
 fn: function (html){
 var self=this;
 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;},
 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: []
 referencedClasses: []
 }),
 }),
 smalltalk.ProgressBar);
 smalltalk.ProgressBar);
@@ -270,10 +271,25 @@ category: 'updating',
 fn: function (aNumber){
 fn: function (aNumber){
 var self=this;
 var self=this;
 smalltalk.send(self, "_percent_", [aNumber]);
 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;},
 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: []
 referencedClasses: []
 }),
 }),
 smalltalk.ProgressBar);
 smalltalk.ProgressBar);
@@ -531,7 +547,7 @@ smalltalk.send(aCollection, "_do_", [(function(each){return smalltalk.send((func
 return self;},
 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.'),
 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"],
 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);
 smalltalk.TestRunner);
 
 
@@ -547,7 +563,7 @@ self['@result']=smalltalk.send(smalltalk.TestResult, "_new", []);
 return self;},
 return self;},
 source: unescape('initialize%0A%09super%20initialize.%0A%09result%20%3A%3D%20TestResult%20new'),
 source: unescape('initialize%0A%09super%20initialize.%0A%09result%20%3A%3D%20TestResult%20new'),
 messageSends: ["initialize", "new"],
 messageSends: ["initialize", "new"],
-referencedClasses: []
+referencedClasses: [smalltalk.nil]
 }),
 }),
 smalltalk.TestRunner);
 smalltalk.TestRunner);
 
 

+ 103 - 16
js/boot.js

@@ -221,7 +221,7 @@ function Smalltalk(){
     /* Handles Smalltalk message send. Automatically converts undefined to the nil object.
     /* Handles Smalltalk message send. Automatically converts undefined to the nil object.
        If the receiver does not understand the selector, call its #doesNotUnderstand: method */
        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") {
 	if(typeof receiver === "undefined") {
 	    receiver = nil;
 	    receiver = nil;
 	}
 	}
@@ -233,13 +233,67 @@ function Smalltalk(){
 	return messageNotUnderstood(receiver, selector, args);
 	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.
     /* Handles #dnu: *and* JavaScript method calls.
        if the receiver has no klass, we consider it a JS object (outside of the
        if the receiver has no klass, we consider it a JS object (outside of the
        Jtalk system). Else assume that the receiver understands #doesNotUnderstand: */
        Jtalk system). Else assume that the receiver understands #doesNotUnderstand: */
 
 
     function messageNotUnderstood(receiver, selector, args) {
     function messageNotUnderstood(receiver, selector, args) {
 	/* Handles JS method calls. */
 	/* Handles JS method calls. */
-	if(receiver.klass === undefined) {
+	if(receiver.klass === undefined || receiver.allowJavaScriptCalls) {
 	    return callJavaScriptMethod(receiver, selector, args);
 	    return callJavaScriptMethod(receiver, selector, args);
 	}
 	}
 
 
@@ -248,7 +302,7 @@ function Smalltalk(){
 	
 	
 	return receiver._doesNotUnderstand_(
 	return receiver._doesNotUnderstand_(
 	    st.Message._new()
 	    st.Message._new()
-		._selector_(convertSelector(selector))
+		._selector_(st.convertSelector(selector))
 		._arguments_(args)
 		._arguments_(args)
 	);
 	);
     };
     };
@@ -272,15 +326,30 @@ function Smalltalk(){
 	    return jsProperty
 	    return jsProperty
 	}
 	}
 	smalltalk.Error._signal_(receiver + ' is not a Jtalk object and "' + jsSelector + '" is undefined')
 	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.
     /* Convert a string to a valid smalltalk selector.
        if you modify the following functions, also change String>>asSelector
        if you modify the following functions, also change String>>asSelector
        accordingly */
        accordingly */
 
 
-    function convertSelector(selector) {
+    st.convertSelector = function(selector) {
 	if(selector.match(/__/)) {
 	if(selector.match(/__/)) {
 	    return convertBinarySelector(selector);
 	    return convertBinarySelector(selector);
 	} else {
 	} 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. */
 /* Global Smalltalk objects. nil and thisContext shouldn't be globals. */
 
 
 var nil = new SmalltalkNil();
 var nil = new SmalltalkNil();
 var smalltalk = new Smalltalk();
 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("RegularExpression", "Kernel", RegExp, smalltalk.String);
 
 
 smalltalk.mapClassName("Error", "Kernel", Error, smalltalk.Object);
 smalltalk.mapClassName("Error", "Kernel", Error, smalltalk.Object);
+smalltalk.mapClassName("MethodContext", "Kernel", SmalltalkMethodContext, smalltalk.Object);
 
 
 if(this.CanvasRenderingContext2D) {
 if(this.CanvasRenderingContext2D) {
     smalltalk.mapClassName("CanvasRenderingContext", "Canvas", CanvasRenderingContext2D, smalltalk.Object);
     smalltalk.mapClassName("CanvasRenderingContext", "Canvas", CanvasRenderingContext2D, smalltalk.Object);
-}
+}

+ 26 - 3
st/Canvas.st

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

+ 3 - 2
st/Compiler.st

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

+ 86 - 37
st/IDE.st

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

+ 24 - 15
st/JQuery.st

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

+ 103 - 2
st/Kernel.st

@@ -128,6 +128,10 @@ doesNotUnderstand: aMessage
 		receiver: self;
 		receiver: self;
 		message: aMessage;
 		message: aMessage;
 		signal
 		signal
+!
+
+halt
+	self error: 'Halt encountered'
 ! !
 ! !
 
 
 !Object methodsFor: 'initialization'!
 !Object methodsFor: 'initialization'!
@@ -357,6 +361,14 @@ protocolsDo: aBlock
  			add: m]. 
  			add: m]. 
 	self protocols do: [:category |
 	self protocols do: [:category |
 		aBlock value: category value: (methodsByCategory at: 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'!
 !Behavior methodsFor: 'instance creation'!
@@ -1638,7 +1650,7 @@ compile: aString
 !
 !
 
 
 exec: aString
 exec: aString
-	<return self.exec(aString)>
+	<return self.exec(aString) || nil>
 !
 !
 
 
 test: aString
 test: aString
@@ -1667,12 +1679,16 @@ messageText
 
 
 messageText: aString
 messageText: aString
 	messageText := aString
 	messageText := aString
+!
+
+context
+	<return self.context>
 ! !
 ! !
 
 
 !Error methodsFor: 'signaling'!
 !Error methodsFor: 'signaling'!
 
 
 signal
 signal
-	<console.log(self._messageText()); throw(self)>
+	<self.context = thisContext; self.smalltalkError = true; throw(self)>
 ! !
 ! !
 
 
 !Error class methodsFor: 'instance creation'!
 !Error class methodsFor: 'instance creation'!
@@ -1683,6 +1699,36 @@ signal: aString
 		signal
 		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
 Object subclass: #Association
 	instanceVariableNames: 'key value'
 	instanceVariableNames: 'key value'
 	category: 'Kernel'!
 	category: 'Kernel'!
@@ -2286,3 +2332,58 @@ messageText
 	^self receiver asString, ' does not understand #', self message selector
 	^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
 TabWidget subclass: #ProgressBar
-	instanceVariableNames: 'percent progressDiv'
+	instanceVariableNames: 'percent progressDiv div'
 	category: 'SUnit'!
 	category: 'SUnit'!
 
 
 !ProgressBar methodsFor: 'accessing'!
 !ProgressBar methodsFor: 'accessing'!
@@ -103,19 +103,24 @@ percent: aNumber
 !ProgressBar methodsFor: 'rendering'!
 !ProgressBar methodsFor: 'rendering'!
 
 
 renderOn: html 
 renderOn: html 
-	html div 
+	div := html div 
 		class: 'progress_bar';
 		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'!
 !ProgressBar methodsFor: 'updating'!
 
 
 updatePercent: aNumber
 updatePercent: aNumber
 	self percent: aNumber.
 	self percent: aNumber.
-	self update
+	self renderProgressBar
 ! !
 ! !
 
 
 Error subclass: #TestFailure
 Error subclass: #TestFailure