Browse Source

Merge branch 'pluggable-exporters-with-new-loaders' into requirejs-wip

Conflicts:
	bin/amberc.js
	js/Canvas.deploy.js
	js/Canvas.js
Herbert Vojčík 10 years ago
parent
commit
78d8df042c

+ 1 - 1
bin/amberc.js

@@ -134,7 +134,7 @@ function AmberC(amber_dir, closure_jar) {
 	this.kernel_libraries = ['@boot', '@smalltalk', '@nil', '@_st', 'Kernel-Objects', 'Kernel-Classes', 'Kernel-Methods',
 							'Kernel-Collections', 'Kernel-Exceptions', 'Kernel-Transcript',
 							'Kernel-Announcements'];
-	this.compiler_libraries = this.kernel_libraries.concat(['@parser', 'Importer-Exporter',
+	this.compiler_libraries = this.kernel_libraries.concat(['@parser', 'Importer-Exporter', 'Compiler-Exceptions',
 							'Compiler-Core', 'Compiler-AST', 'Compiler-Exceptions', 'Compiler-IR', 'Compiler-Inlining', 'Compiler-Semantic']);
 }
 

+ 12 - 0
bower.json

@@ -0,0 +1,12 @@
+{
+  "name": "amber",
+  "version": "0.11.0",
+  "main": "js/amber.js",
+  "ignore": [
+    "**/.*",
+    "node_modules",
+    "bower_components",
+    "test",
+    "tests"
+  ]
+}

+ 70 - 3
js/Canvas.deploy.js

@@ -2,6 +2,73 @@ define("amber/Canvas", ["amber_vm/smalltalk","amber_vm/nil","amber_vm/_st"], fun
 smalltalk.addPackage('Canvas');
 smalltalk.packages["Canvas"].transport = {"type":"amd","amdNamespace":"amber"};
 
+smalltalk.addClass('BrowserInterface', smalltalk.Object, [], 'Canvas');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "ajax:",
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(jQuery)._ajax_(anObject);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"ajax:",{anObject:anObject},smalltalk.BrowserInterface)})},
+messageSends: ["ajax:"]}),
+smalltalk.BrowserInterface);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "alert:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(window)._alert_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"alert:",{aString:aString},smalltalk.BrowserInterface)})},
+messageSends: ["alert:"]}),
+smalltalk.BrowserInterface);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "confirm:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(window)._confirm_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"confirm:",{aString:aString},smalltalk.BrowserInterface)})},
+messageSends: ["confirm:"]}),
+smalltalk.BrowserInterface);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "isAvailable",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return typeof window !== "undefined" && typeof jQuery !== "undefined";
+return self}, function($ctx1) {$ctx1.fill(self,"isAvailable",{},smalltalk.BrowserInterface)})},
+messageSends: []}),
+smalltalk.BrowserInterface);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "prompt:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(window)._prompt_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"prompt:",{aString:aString},smalltalk.BrowserInterface)})},
+messageSends: ["prompt:"]}),
+smalltalk.BrowserInterface);
+
+
+smalltalk.BrowserInterface.klass.iVarNames = ['uiWorker','ajaxWorker'];
+
 smalltalk.addClass('HTMLCanvas', smalltalk.Object, ['root'], 'Canvas');
 smalltalk.addMethod(
 smalltalk.method({
@@ -1911,10 +1978,10 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(window)._jQuery_(self._element());
+$1=_st(self._element())._asJQuery();
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"asJQuery",{},smalltalk.TagBrush)})},
-messageSends: ["jQuery:", "element"]}),
+messageSends: ["asJQuery", "element"]}),
 smalltalk.TagBrush);
 
 smalltalk.addMethod(
@@ -2611,7 +2678,7 @@ messageSends: ["initializeFromString:canvas:", "new", "yourself"]}),
 smalltalk.StyleTag.klass);
 
 
-smalltalk.addClass('Widget', smalltalk.Object, [], 'Canvas');
+smalltalk.addClass('Widget', smalltalk.InterfacingObject, [], 'Canvas');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "appendToBrush:",

+ 97 - 4
js/Canvas.js

@@ -2,6 +2,99 @@ define("amber/Canvas", ["amber_vm/smalltalk","amber_vm/nil","amber_vm/_st"], fun
 smalltalk.addPackage('Canvas');
 smalltalk.packages["Canvas"].transport = {"type":"amd","amdNamespace":"amber"};
 
+smalltalk.addClass('BrowserInterface', smalltalk.Object, [], 'Canvas');
+smalltalk.BrowserInterface.comment="I am platform interface class that tries to use window and jQuery; that is, one for browser environment.\x0a\x0a## API\x0a\x0a    self isAvailable. \x22true if window and jQuery exist\x22.\x0a\x0a    self alert: 'Hey, there is a problem'.\x0a    self confirm: 'Affirmative?'.\x0a    self prompt: 'Your name:'.\x0a\x0a    self ajax: #{\x0a        'url' -> '/patch.js'. 'type' -> 'GET'. dataType->'script'\x0a    }.\x0a";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "ajax:",
+category: 'actions',
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(jQuery)._ajax_(anObject);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"ajax:",{anObject:anObject},smalltalk.BrowserInterface)})},
+args: ["anObject"],
+source: "ajax: anObject\x0a\x09^jQuery ajax: anObject",
+messageSends: ["ajax:"],
+referencedClasses: []
+}),
+smalltalk.BrowserInterface);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "alert:",
+category: 'actions',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(window)._alert_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"alert:",{aString:aString},smalltalk.BrowserInterface)})},
+args: ["aString"],
+source: "alert: aString\x0a\x09^window alert: aString",
+messageSends: ["alert:"],
+referencedClasses: []
+}),
+smalltalk.BrowserInterface);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "confirm:",
+category: 'actions',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(window)._confirm_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"confirm:",{aString:aString},smalltalk.BrowserInterface)})},
+args: ["aString"],
+source: "confirm: aString\x0a\x09^window confirm: aString",
+messageSends: ["confirm:"],
+referencedClasses: []
+}),
+smalltalk.BrowserInterface);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "isAvailable",
+category: 'testing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return typeof window !== "undefined" && typeof jQuery !== "undefined";
+return self}, function($ctx1) {$ctx1.fill(self,"isAvailable",{},smalltalk.BrowserInterface)})},
+args: [],
+source: "isAvailable\x0a<return typeof window !== \x22undefined\x22 && typeof jQuery !== \x22undefined\x22>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.BrowserInterface);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "prompt:",
+category: 'actions',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(window)._prompt_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"prompt:",{aString:aString},smalltalk.BrowserInterface)})},
+args: ["aString"],
+source: "prompt: aString\x0a\x09^window prompt: aString",
+messageSends: ["prompt:"],
+referencedClasses: []
+}),
+smalltalk.BrowserInterface);
+
+
+smalltalk.BrowserInterface.klass.iVarNames = ['uiWorker','ajaxWorker'];
+
 smalltalk.addClass('HTMLCanvas', smalltalk.Object, ['root'], 'Canvas');
 smalltalk.HTMLCanvas.comment="I am a canvas for building HTML.\x0a\x0aI provide the `#tag:` method to create a `TagBrush` (wrapping a DOM element) and convenience methods in the `tags` protocol.\x0a\x0a## API\x0a\x0aMy instances are used as the argument of the `#renderOn:` method of `Widget` objects.\x0a\x0aThe `#with:` method is used to compose HTML, nesting tags. `#with:` can take a `TagBrush`, a `String`, a `BlockClosure` or a `Widget` as argument.\x0a\x0a## Usage example:\x0a\x0a    aCanvas a \x0a        with: [ aCanvas span with: 'click me' ];\x0a        onClick: [ window alert: 'clicked!' ]";
 smalltalk.addMethod(
@@ -2625,12 +2718,12 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(window)._jQuery_(self._element());
+$1=_st(self._element())._asJQuery();
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"asJQuery",{},smalltalk.TagBrush)})},
 args: [],
-source: "asJQuery\x0a\x09^window jQuery: self element",
-messageSends: ["jQuery:", "element"],
+source: "asJQuery\x0a\x09^self element asJQuery",
+messageSends: ["asJQuery", "element"],
 referencedClasses: []
 }),
 smalltalk.TagBrush);
@@ -3630,7 +3723,7 @@ referencedClasses: []
 smalltalk.StyleTag.klass);
 
 
-smalltalk.addClass('Widget', smalltalk.Object, [], 'Canvas');
+smalltalk.addClass('Widget', smalltalk.InterfacingObject, [], 'Canvas');
 smalltalk.Widget.comment="I am a presenter building HTML. Subclasses are typically reusable components.\x0a\x0a## API\x0a\x0aUse `#renderContentOn:` to build HTML. (See `HTMLCanvas` and `TagBrush` classes for more about building HTML).\x0a\x0aTo add a widget to the page, the convenience method `#appendToJQuery:` is very useful.\x0a\x0aExemple: \x0a\x0a    Counter new appendToJQuery: 'body' asJQuery";
 smalltalk.addMethod(
 smalltalk.method({

+ 21 - 32
js/Helios-Core.deploy.js

@@ -826,7 +826,7 @@ fn: function (aString,aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-_st(_st(window)._jQuery_("#helper"))._remove();
+_st("#helper"._asJQuery())._remove();
 _st((function(html){
 return smalltalk.withContext(function($ctx2) {
 $1=_st(html)._div();
@@ -837,10 +837,10 @@ return $2;
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
 _st(aBlock)._value();
-return _st(_st(window)._jQuery_("#helper"))._remove();
+return _st("#helper"._asJQuery())._remove();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._valueWithTimeout_((10));
 return self}, function($ctx1) {$ctx1.fill(self,"withHelperLabelled:do:",{aString:aString,aBlock:aBlock},smalltalk.HLToolModel)})},
-messageSends: ["remove", "jQuery:", "appendToJQuery:", "asJQuery", "id:", "div", "with:", "valueWithTimeout:", "value"]}),
+messageSends: ["remove", "asJQuery", "appendToJQuery:", "id:", "div", "with:", "valueWithTimeout:", "value"]}),
 smalltalk.HLToolModel);
 
 
@@ -1145,17 +1145,6 @@ smalltalk.HLTabWidget.klass);
 
 
 smalltalk.addClass('HLWidget', smalltalk.Widget, ['wrapper'], 'Helios-Core');
-smalltalk.addMethod(
-smalltalk.method({
-selector: "alert:",
-fn: function (aString){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-_st(window)._alert_(aString);
-return self}, function($ctx1) {$ctx1.fill(self,"alert:",{aString:aString},smalltalk.HLWidget)})},
-messageSends: ["alert:"]}),
-smalltalk.HLWidget);
-
 smalltalk.addMethod(
 smalltalk.method({
 selector: "bindKeyDown:up:",
@@ -1543,9 +1532,9 @@ selector: "activateFirstListItem",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self._activateListItem_(_st(window)._jQuery_(_st(_st(_st(self["@wrapper"])._asJQuery())._find_("li.inactive"))._get_((0))));
+self._activateListItem_(_st(_st(_st(self["@wrapper"])._asJQuery())._find_("li.inactive"))._eq_((0)));
 return self}, function($ctx1) {$ctx1.fill(self,"activateFirstListItem",{},smalltalk.HLListWidget)})},
-messageSends: ["activateListItem:", "jQuery:", "get:", "find:", "asJQuery"]}),
+messageSends: ["activateListItem:", "eq:", "find:", "asJQuery"]}),
 smalltalk.HLListWidget);
 
 smalltalk.addMethod(
@@ -2572,10 +2561,10 @@ selector: "refresh",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(window)._jQuery_(".navbar"))._remove();
+_st(".navbar"._asJQuery())._remove();
 self._appendToJQuery_("body"._asJQuery());
 return self}, function($ctx1) {$ctx1.fill(self,"refresh",{},smalltalk.HLManager)})},
-messageSends: ["remove", "jQuery:", "appendToJQuery:", "asJQuery"]}),
+messageSends: ["remove", "asJQuery", "appendToJQuery:"]}),
 smalltalk.HLManager);
 
 smalltalk.addMethod(
@@ -2861,7 +2850,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-_st(_st(window)._jQuery_("body"))._keydown_((function(e){
+_st("body"._asJQuery())._keydown_((function(e){
 return smalltalk.withContext(function($ctx2) {
 $1=_st(_st(_st(e)._keyCode()).__gt_eq((37)))._and_((function(){
 return smalltalk.withContext(function($ctx3) {
@@ -2872,7 +2861,7 @@ return false;
 };
 }, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"clearKeydownEvent",{},smalltalk.HLManager.klass)})},
-messageSends: ["keydown:", "ifTrue:", "and:", "<=", "keyCode", ">=", "jQuery:"]}),
+messageSends: ["keydown:", "ifTrue:", "and:", "<=", "keyCode", ">=", "asJQuery"]}),
 smalltalk.HLManager.klass);
 
 smalltalk.addMethod(
@@ -2947,14 +2936,14 @@ selector: "remove",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(window)._jQuery_(".dialog"))._removeClass_("active");
+_st(".dialog"._asJQuery())._removeClass_("active");
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
-_st(_st(window)._jQuery_("#overlay"))._remove();
-return _st(_st(window)._jQuery_(".dialog"))._remove();
+_st("#overlay"._asJQuery())._remove();
+return _st(".dialog"._asJQuery())._remove();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._valueWithTimeout_((300));
 return self}, function($ctx1) {$ctx1.fill(self,"remove",{},smalltalk.HLModalWidget)})},
-messageSends: ["removeClass:", "jQuery:", "valueWithTimeout:", "remove"]}),
+messageSends: ["removeClass:", "asJQuery", "valueWithTimeout:", "remove"]}),
 smalltalk.HLModalWidget);
 
 smalltalk.addMethod(
@@ -2985,10 +2974,10 @@ _st($3)._renderMainOn_(html);
 $4=_st($3)._renderButtonsOn_(html);
 return $4;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
-_st(_st(window)._jQuery_(".dialog"))._addClass_("active");
+_st(".dialog"._asJQuery())._addClass_("active");
 self._setupKeyBindings();
 return self}, function($ctx1) {$ctx1.fill(self,"renderContentOn:",{html:html,confirmButton:confirmButton},smalltalk.HLModalWidget)})},
-messageSends: ["id:", "div", "class:", ",", "cssClass", "with:", "renderMainOn:", "renderButtonsOn:", "addClass:", "jQuery:", "setupKeyBindings"]}),
+messageSends: ["id:", "div", "class:", ",", "cssClass", "with:", "renderMainOn:", "renderButtonsOn:", "addClass:", "asJQuery", "setupKeyBindings"]}),
 smalltalk.HLModalWidget);
 
 smalltalk.addMethod(
@@ -3008,7 +2997,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-_st(_st(window)._jQuery_(".dialog"))._keyup_((function(e){
+_st(".dialog"._asJQuery())._keyup_((function(e){
 return smalltalk.withContext(function($ctx2) {
 $1=_st(_st(e)._keyCode()).__eq((27));
 if(smalltalk.assert($1)){
@@ -3016,7 +3005,7 @@ return self._cancel();
 };
 }, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"setupKeyBindings",{},smalltalk.HLModalWidget)})},
-messageSends: ["keyup:", "ifTrue:", "cancel", "=", "keyCode", "jQuery:"]}),
+messageSends: ["keyup:", "ifTrue:", "cancel", "=", "keyCode", "asJQuery"]}),
 smalltalk.HLModalWidget);
 
 
@@ -3143,14 +3132,14 @@ selector: "remove",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(window)._jQuery_(".dialog"))._removeClass_("active");
+_st(".dialog"._asJQuery())._removeClass_("active");
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
-_st(_st(window)._jQuery_("#overlay"))._remove();
-return _st(_st(window)._jQuery_(".dialog"))._remove();
+_st("#overlay"._asJQuery())._remove();
+return _st(".dialog"._asJQuery())._remove();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._valueWithTimeout_((300));
 return self}, function($ctx1) {$ctx1.fill(self,"remove",{},smalltalk.HLConfirmationWidget)})},
-messageSends: ["removeClass:", "jQuery:", "valueWithTimeout:", "remove"]}),
+messageSends: ["removeClass:", "asJQuery", "valueWithTimeout:", "remove"]}),
 smalltalk.HLConfirmationWidget);
 
 smalltalk.addMethod(

+ 29 - 45
js/Helios-Core.js

@@ -1074,7 +1074,7 @@ fn: function (aString,aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-_st(_st(window)._jQuery_("#helper"))._remove();
+_st("#helper"._asJQuery())._remove();
 _st((function(html){
 return smalltalk.withContext(function($ctx2) {
 $1=_st(html)._div();
@@ -1085,12 +1085,12 @@ return $2;
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
 _st(aBlock)._value();
-return _st(_st(window)._jQuery_("#helper"))._remove();
+return _st("#helper"._asJQuery())._remove();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._valueWithTimeout_((10));
 return self}, function($ctx1) {$ctx1.fill(self,"withHelperLabelled:do:",{aString:aString,aBlock:aBlock},smalltalk.HLToolModel)})},
 args: ["aString", "aBlock"],
-source: "withHelperLabelled: aString do: aBlock\x0a\x09\x22TODO: doesn't belong here\x22\x0a\x0a\x09(window jQuery: '#helper') remove.\x0a\x0a\x09[ :html |\x0a\x09\x09html div \x0a\x09\x09\x09id: 'helper';\x0a\x09\x09\x09with: aString ] appendToJQuery: 'body' asJQuery.\x0a\x09\x0a\x09[\x0a\x09\x09aBlock value.\x0a\x09\x09(window jQuery: '#helper') remove\x0a\x09] \x0a\x09\x09valueWithTimeout: 10",
-messageSends: ["remove", "jQuery:", "appendToJQuery:", "asJQuery", "id:", "div", "with:", "valueWithTimeout:", "value"],
+source: "withHelperLabelled: aString do: aBlock\x0a\x09\x22TODO: doesn't belong here\x22\x0a\x0a\x09'#helper' asJQuery remove.\x0a\x0a\x09[ :html |\x0a\x09\x09html div \x0a\x09\x09\x09id: 'helper';\x0a\x09\x09\x09with: aString ] appendToJQuery: 'body' asJQuery.\x0a\x09\x0a\x09[\x0a\x09\x09aBlock value.\x0a\x09\x09'#helper' asJQuery remove\x0a\x09] \x0a\x09\x09valueWithTimeout: 10",
+messageSends: ["remove", "asJQuery", "appendToJQuery:", "id:", "div", "with:", "valueWithTimeout:", "value"],
 referencedClasses: []
 }),
 smalltalk.HLToolModel);
@@ -1500,22 +1500,6 @@ smalltalk.HLTabWidget.klass);
 
 smalltalk.addClass('HLWidget', smalltalk.Widget, ['wrapper'], 'Helios-Core');
 smalltalk.HLWidget.comment="I am the abstract superclass of all Helios widgets.\x0a\x0aI provide common methods, additional behavior to widgets useful for Helios, like dialog creation, command execution and tab creation.\x0a\x0a## API\x0a\x0a1. Rendering\x0a\x0a    Instead of overriding `#renderOn:` as with other Widget subclasses, my subclasses should override `#renderContentOn:`.\x0a\x0a2. Refreshing\x0a\x0a    To re-render a widget, use `#refresh`.\x0a\x0a3. Key bindings registration and tabs\x0a\x0a    When displayed as a tab, the widget has a chance to register keybindings with the `#registerBindingsOn:` hook method.\x0a    \x0a4. Unregistration\x0a\x0a    When a widget has subscribed to announcements or other actions that need to be cleared when closing the tab, the hook method `#unregister` will be called by helios.\x0a\x0a5. Tabs\x0a\x0a   To enable a widget class to be open as a tab, override the class-side `#canBeOpenAsTab` method to answer `true`. `#tabClass` and `#tabPriority` can be overridden too to respectively change the css class of the tab and the order of tabs in the main menu.\x0a\x0a6. Command execution\x0a\x0a    An helios command (instance of `HLCommand` or one of its subclass) can be executed with `#execute:`.";
-smalltalk.addMethod(
-smalltalk.method({
-selector: "alert:",
-category: 'actions',
-fn: function (aString){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-_st(window)._alert_(aString);
-return self}, function($ctx1) {$ctx1.fill(self,"alert:",{aString:aString},smalltalk.HLWidget)})},
-args: ["aString"],
-source: "alert: aString\x0a\x09window alert: aString",
-messageSends: ["alert:"],
-referencedClasses: []
-}),
-smalltalk.HLWidget);
-
 smalltalk.addMethod(
 smalltalk.method({
 selector: "bindKeyDown:up:",
@@ -2050,11 +2034,11 @@ category: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self._activateListItem_(_st(window)._jQuery_(_st(_st(_st(self["@wrapper"])._asJQuery())._find_("li.inactive"))._get_((0))));
+self._activateListItem_(_st(_st(_st(self["@wrapper"])._asJQuery())._find_("li.inactive"))._eq_((0)));
 return self}, function($ctx1) {$ctx1.fill(self,"activateFirstListItem",{},smalltalk.HLListWidget)})},
 args: [],
-source: "activateFirstListItem\x0a\x09self activateListItem: (window jQuery: ((wrapper asJQuery find: 'li.inactive') get: 0))",
-messageSends: ["activateListItem:", "jQuery:", "get:", "find:", "asJQuery"],
+source: "activateFirstListItem\x0a\x09self activateListItem: ((wrapper asJQuery find: 'li.inactive') eq: 0)",
+messageSends: ["activateListItem:", "eq:", "find:", "asJQuery"],
 referencedClasses: []
 }),
 smalltalk.HLListWidget);
@@ -3389,12 +3373,12 @@ category: 'rendering',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(window)._jQuery_(".navbar"))._remove();
+_st(".navbar"._asJQuery())._remove();
 self._appendToJQuery_("body"._asJQuery());
 return self}, function($ctx1) {$ctx1.fill(self,"refresh",{},smalltalk.HLManager)})},
 args: [],
-source: "refresh\x0a\x09(window jQuery: '.navbar') remove.\x0a\x09self appendToJQuery: 'body' asJQuery",
-messageSends: ["remove", "jQuery:", "appendToJQuery:", "asJQuery"],
+source: "refresh\x0a\x09'.navbar' asJQuery remove.\x0a\x09self appendToJQuery: 'body' asJQuery",
+messageSends: ["remove", "asJQuery", "appendToJQuery:"],
 referencedClasses: []
 }),
 smalltalk.HLManager);
@@ -3748,7 +3732,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-_st(_st(window)._jQuery_("body"))._keydown_((function(e){
+_st("body"._asJQuery())._keydown_((function(e){
 return smalltalk.withContext(function($ctx2) {
 $1=_st(_st(_st(e)._keyCode()).__gt_eq((37)))._and_((function(){
 return smalltalk.withContext(function($ctx3) {
@@ -3760,8 +3744,8 @@ return false;
 }, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"clearKeydownEvent",{},smalltalk.HLManager.klass)})},
 args: [],
-source: "clearKeydownEvent\x0a\x09\x22Prevent default keydown event with arrow key from scrolling the parent page\x0a\x09when helios is run inside a frame.\x22\x0a\x09\x0a\x09(window jQuery: 'body') keydown: [ :e | \x0a\x09\x09(e keyCode >= 37 and: [ e keyCode <= 40 ])\x0a\x09\x09\x09ifTrue: [ false ] ]",
-messageSends: ["keydown:", "ifTrue:", "and:", "<=", "keyCode", ">=", "jQuery:"],
+source: "clearKeydownEvent\x0a\x09\x22Prevent default keydown event with arrow key from scrolling the parent page\x0a\x09when helios is run inside a frame.\x22\x0a\x09\x0a\x09'body' asJQuery keydown: [ :e | \x0a\x09\x09(e keyCode >= 37 and: [ e keyCode <= 40 ])\x0a\x09\x09\x09ifTrue: [ false ] ]",
+messageSends: ["keydown:", "ifTrue:", "and:", "<=", "keyCode", ">=", "asJQuery"],
 referencedClasses: []
 }),
 smalltalk.HLManager.klass);
@@ -3865,16 +3849,16 @@ category: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(window)._jQuery_(".dialog"))._removeClass_("active");
+_st(".dialog"._asJQuery())._removeClass_("active");
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
-_st(_st(window)._jQuery_("#overlay"))._remove();
-return _st(_st(window)._jQuery_(".dialog"))._remove();
+_st("#overlay"._asJQuery())._remove();
+return _st(".dialog"._asJQuery())._remove();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._valueWithTimeout_((300));
 return self}, function($ctx1) {$ctx1.fill(self,"remove",{},smalltalk.HLModalWidget)})},
 args: [],
-source: "remove\x0a\x09(window jQuery: '.dialog') removeClass: 'active'.\x0a\x09[ \x0a\x09\x09(window jQuery: '#overlay') remove.\x0a\x09\x09(window jQuery: '.dialog') remove\x0a\x09] valueWithTimeout: 300",
-messageSends: ["removeClass:", "jQuery:", "valueWithTimeout:", "remove"],
+source: "remove\x0a\x09'.dialog' asJQuery removeClass: 'active'.\x0a\x09[ \x0a\x09\x09'#overlay' asJQuery remove.\x0a\x09\x09'.dialog' asJQuery remove\x0a\x09] valueWithTimeout: 300",
+messageSends: ["removeClass:", "asJQuery", "valueWithTimeout:", "remove"],
 referencedClasses: []
 }),
 smalltalk.HLModalWidget);
@@ -3913,12 +3897,12 @@ _st($3)._renderMainOn_(html);
 $4=_st($3)._renderButtonsOn_(html);
 return $4;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
-_st(_st(window)._jQuery_(".dialog"))._addClass_("active");
+_st(".dialog"._asJQuery())._addClass_("active");
 self._setupKeyBindings();
 return self}, function($ctx1) {$ctx1.fill(self,"renderContentOn:",{html:html,confirmButton:confirmButton},smalltalk.HLModalWidget)})},
 args: ["html"],
-source: "renderContentOn: html\x0a\x09| confirmButton |\x0a\x09\x0a\x09html div id: 'overlay'.\x0a\x09html div \x0a\x09\x09class: 'dialog ', self cssClass;\x0a\x09\x09with: [\x0a\x09\x09\x09self\x0a\x09\x09\x09\x09renderMainOn: html;\x0a\x09\x09\x09\x09renderButtonsOn: html ].\x0a\x0a\x09(window jQuery: '.dialog') addClass: 'active'.\x0a\x09self setupKeyBindings",
-messageSends: ["id:", "div", "class:", ",", "cssClass", "with:", "renderMainOn:", "renderButtonsOn:", "addClass:", "jQuery:", "setupKeyBindings"],
+source: "renderContentOn: html\x0a\x09| confirmButton |\x0a\x09\x0a\x09html div id: 'overlay'.\x0a\x09html div \x0a\x09\x09class: 'dialog ', self cssClass;\x0a\x09\x09with: [\x0a\x09\x09\x09self\x0a\x09\x09\x09\x09renderMainOn: html;\x0a\x09\x09\x09\x09renderButtonsOn: html ].\x0a\x0a\x09'.dialog' asJQuery addClass: 'active'.\x0a\x09self setupKeyBindings",
+messageSends: ["id:", "div", "class:", ",", "cssClass", "with:", "renderMainOn:", "renderButtonsOn:", "addClass:", "asJQuery", "setupKeyBindings"],
 referencedClasses: []
 }),
 smalltalk.HLModalWidget);
@@ -3946,7 +3930,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-_st(_st(window)._jQuery_(".dialog"))._keyup_((function(e){
+_st(".dialog"._asJQuery())._keyup_((function(e){
 return smalltalk.withContext(function($ctx2) {
 $1=_st(_st(e)._keyCode()).__eq((27));
 if(smalltalk.assert($1)){
@@ -3955,8 +3939,8 @@ return self._cancel();
 }, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"setupKeyBindings",{},smalltalk.HLModalWidget)})},
 args: [],
-source: "setupKeyBindings\x0a\x09(window jQuery: '.dialog') keyup: [ :e |\x0a\x09\x09e keyCode = 27 ifTrue: [ self cancel ] ]",
-messageSends: ["keyup:", "ifTrue:", "cancel", "=", "keyCode", "jQuery:"],
+source: "setupKeyBindings\x0a\x09'.dialog' asJQuery keyup: [ :e |\x0a\x09\x09e keyCode = 27 ifTrue: [ self cancel ] ]",
+messageSends: ["keyup:", "ifTrue:", "cancel", "=", "keyCode", "asJQuery"],
 referencedClasses: []
 }),
 smalltalk.HLModalWidget);
@@ -4127,16 +4111,16 @@ category: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(window)._jQuery_(".dialog"))._removeClass_("active");
+_st(".dialog"._asJQuery())._removeClass_("active");
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
-_st(_st(window)._jQuery_("#overlay"))._remove();
-return _st(_st(window)._jQuery_(".dialog"))._remove();
+_st("#overlay"._asJQuery())._remove();
+return _st(".dialog"._asJQuery())._remove();
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._valueWithTimeout_((300));
 return self}, function($ctx1) {$ctx1.fill(self,"remove",{},smalltalk.HLConfirmationWidget)})},
 args: [],
-source: "remove\x0a\x09(window jQuery: '.dialog') removeClass: 'active'.\x0a\x09[ \x0a\x09\x09(window jQuery: '#overlay') remove.\x0a\x09\x09(window jQuery: '.dialog') remove\x0a\x09] valueWithTimeout: 300",
-messageSends: ["removeClass:", "jQuery:", "valueWithTimeout:", "remove"],
+source: "remove\x0a\x09'.dialog' asJQuery removeClass: 'active'.\x0a\x09[ \x0a\x09\x09'#overlay' asJQuery remove.\x0a\x09\x09'.dialog' asJQuery remove\x0a\x09] valueWithTimeout: 300",
+messageSends: ["removeClass:", "asJQuery", "valueWithTimeout:", "remove"],
 referencedClasses: []
 }),
 smalltalk.HLConfirmationWidget);

+ 5 - 5
js/Helios-KeyBindings.deploy.js

@@ -1170,12 +1170,12 @@ selector: "setupEvents",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(window)._jQuery_("body"))._keydown_((function(event){
+_st("body"._asJQuery())._keydown_((function(event){
 return smalltalk.withContext(function($ctx2) {
 return self._handleKeyDown_(event);
 }, function($ctx2) {$ctx2.fillBlock({event:event},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"setupEvents",{},smalltalk.HLKeyBinder)})},
-messageSends: ["keydown:", "handleKeyDown:", "jQuery:"]}),
+messageSends: ["keydown:", "handleKeyDown:", "asJQuery"]}),
 smalltalk.HLKeyBinder);
 
 smalltalk.addMethod(
@@ -1390,7 +1390,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-_st(_st(window)._jQuery_("#helper"))._remove();
+_st("#helper"._asJQuery())._remove();
 _st((function(html){
 return smalltalk.withContext(function($ctx2) {
 $1=_st(html)._div();
@@ -1400,10 +1400,10 @@ return $2;
 }, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1)})}))._appendToJQuery_("body"._asJQuery());
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
-return _st(_st(window)._jQuery_("#helper"))._fadeOut_((1000));
+return _st("#helper"._asJQuery())._fadeOut_((1000));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._valueWithTimeout_((2000));
 return self}, function($ctx1) {$ctx1.fill(self,"renderStart",{},smalltalk.HLKeyBinderHelper)})},
-messageSends: ["remove", "jQuery:", "appendToJQuery:", "asJQuery", "id:", "div", "with:", ",", "activationKeyLabel", "keyBinder", "valueWithTimeout:", "fadeOut:"]}),
+messageSends: ["remove", "asJQuery", "appendToJQuery:", "id:", "div", "with:", ",", "activationKeyLabel", "keyBinder", "valueWithTimeout:", "fadeOut:"]}),
 smalltalk.HLKeyBinderHelper);
 
 smalltalk.addMethod(

+ 7 - 7
js/Helios-KeyBindings.js

@@ -1541,14 +1541,14 @@ category: 'events',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(window)._jQuery_("body"))._keydown_((function(event){
+_st("body"._asJQuery())._keydown_((function(event){
 return smalltalk.withContext(function($ctx2) {
 return self._handleKeyDown_(event);
 }, function($ctx2) {$ctx2.fillBlock({event:event},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"setupEvents",{},smalltalk.HLKeyBinder)})},
 args: [],
-source: "setupEvents\x0a\x09(window jQuery: 'body') keydown: [ :event | self handleKeyDown: event ]",
-messageSends: ["keydown:", "handleKeyDown:", "jQuery:"],
+source: "setupEvents\x0a\x09'body' asJQuery keydown: [ :event | self handleKeyDown: event ]",
+messageSends: ["keydown:", "handleKeyDown:", "asJQuery"],
 referencedClasses: []
 }),
 smalltalk.HLKeyBinder);
@@ -1831,7 +1831,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-_st(_st(window)._jQuery_("#helper"))._remove();
+_st("#helper"._asJQuery())._remove();
 _st((function(html){
 return smalltalk.withContext(function($ctx2) {
 $1=_st(html)._div();
@@ -1841,12 +1841,12 @@ return $2;
 }, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1)})}))._appendToJQuery_("body"._asJQuery());
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
-return _st(_st(window)._jQuery_("#helper"))._fadeOut_((1000));
+return _st("#helper"._asJQuery())._fadeOut_((1000));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._valueWithTimeout_((2000));
 return self}, function($ctx1) {$ctx1.fill(self,"renderStart",{},smalltalk.HLKeyBinderHelper)})},
 args: [],
-source: "renderStart\x0a\x09(window jQuery: '#helper') remove.\x0a\x0a\x09[ :html |\x0a\x09\x09html div \x0a\x09\x09\x09id: 'helper';\x0a\x09\x09\x09with: 'Press ', self keyBinder activationKeyLabel, ' to start' ] appendToJQuery: 'body' asJQuery.\x0a\x09\x0a\x09[ (window jQuery: '#helper') fadeOut: 1000 ] \x0a\x09\x09valueWithTimeout: 2000",
-messageSends: ["remove", "jQuery:", "appendToJQuery:", "asJQuery", "id:", "div", "with:", ",", "activationKeyLabel", "keyBinder", "valueWithTimeout:", "fadeOut:"],
+source: "renderStart\x0a\x09'#helper' asJQuery remove.\x0a\x0a\x09[ :html |\x0a\x09\x09html div \x0a\x09\x09\x09id: 'helper';\x0a\x09\x09\x09with: 'Press ', self keyBinder activationKeyLabel, ' to start' ] appendToJQuery: 'body' asJQuery.\x0a\x09\x0a\x09[ '#helper' asJQuery fadeOut: 1000 ] \x0a\x09\x09valueWithTimeout: 2000",
+messageSends: ["remove", "asJQuery", "appendToJQuery:", "id:", "div", "with:", ",", "activationKeyLabel", "keyBinder", "valueWithTimeout:", "fadeOut:"],
 referencedClasses: []
 }),
 smalltalk.HLKeyBinderHelper);

+ 3 - 3
js/Helios-Workspace.deploy.js

@@ -687,9 +687,9 @@ var variables,classNames,pseudoVariables;
 function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-variables=_st(_st(_st(_st(window)._jQuery_(_st(_st(anEditor)._display())._wrapper()))._find_("span.cm-variable"))._get())._collect_((function(each){
+variables=_st(_st(_st(_st(_st(_st(anEditor)._display())._wrapper())._asJQuery())._find_("span.cm-variable"))._get())._collect_((function(each){
 return smalltalk.withContext(function($ctx2) {
-return _st(_st(window)._jQuery_(each))._html();
+return _st(_st(each)._asJQuery())._html();
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 classNames=_st(_st(_st($Smalltalk())._current())._classes())._collect_((function(each){
 return smalltalk.withContext(function($ctx2) {
@@ -705,7 +705,7 @@ return _st(each).__eq(_st(aToken)._string());
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"variableHintFor:token:",{anEditor:anEditor,aToken:aToken,variables:variables,classNames:classNames,pseudoVariables:pseudoVariables},smalltalk.HLCodeWidget)})},
-messageSends: ["collect:", "html", "jQuery:", "get", "find:", "wrapper", "display", "name", "classes", "current", "pseudoVariableNames", "reject:", "=", "string", "select:", "includesSubString:", "asArray", "asSet", ","]}),
+messageSends: ["collect:", "html", "asJQuery", "get", "find:", "wrapper", "display", "name", "classes", "current", "pseudoVariableNames", "reject:", "=", "string", "select:", "includesSubString:", "asArray", "asSet", ","]}),
 smalltalk.HLCodeWidget);
 
 

+ 4 - 4
js/Helios-Workspace.js

@@ -918,9 +918,9 @@ var variables,classNames,pseudoVariables;
 function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-variables=_st(_st(_st(_st(window)._jQuery_(_st(_st(anEditor)._display())._wrapper()))._find_("span.cm-variable"))._get())._collect_((function(each){
+variables=_st(_st(_st(_st(_st(_st(anEditor)._display())._wrapper())._asJQuery())._find_("span.cm-variable"))._get())._collect_((function(each){
 return smalltalk.withContext(function($ctx2) {
-return _st(_st(window)._jQuery_(each))._html();
+return _st(_st(each)._asJQuery())._html();
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 classNames=_st(_st(_st($Smalltalk())._current())._classes())._collect_((function(each){
 return smalltalk.withContext(function($ctx2) {
@@ -937,8 +937,8 @@ return _st(each).__eq(_st(aToken)._string());
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"variableHintFor:token:",{anEditor:anEditor,aToken:aToken,variables:variables,classNames:classNames,pseudoVariables:pseudoVariables},smalltalk.HLCodeWidget)})},
 args: ["anEditor", "aToken"],
-source: "variableHintFor: anEditor token: aToken\x0a\x09| variables classNames pseudoVariables |\x0a\x09\x0a\x09variables := ((window jQuery: anEditor display wrapper) find: 'span.cm-variable') get\x0a\x09\x09collect: [ :each | (window jQuery: each) html ].\x0a\x09\x0a\x09classNames := Smalltalk current classes collect: [ :each | each name ].\x0a\x09pseudoVariables := Smalltalk current pseudoVariableNames.\x0a\x09\x0a\x09^ ((variables, classNames, pseudoVariables) asSet asArray \x0a\x09\x09select: [ :each | each includesSubString: aToken string ])\x0a\x09\x09reject: [ :each | each = aToken string ]",
-messageSends: ["collect:", "html", "jQuery:", "get", "find:", "wrapper", "display", "name", "classes", "current", "pseudoVariableNames", "reject:", "=", "string", "select:", "includesSubString:", "asArray", "asSet", ","],
+source: "variableHintFor: anEditor token: aToken\x0a\x09| variables classNames pseudoVariables |\x0a\x09\x0a\x09variables := (anEditor display wrapper asJQuery find: 'span.cm-variable') get\x0a\x09\x09collect: [ :each | each asJQuery html ].\x0a\x09\x0a\x09classNames := Smalltalk current classes collect: [ :each | each name ].\x0a\x09pseudoVariables := Smalltalk current pseudoVariableNames.\x0a\x09\x0a\x09^ ((variables, classNames, pseudoVariables) asSet asArray \x0a\x09\x09select: [ :each | each includesSubString: aToken string ])\x0a\x09\x09reject: [ :each | each = aToken string ]",
+messageSends: ["collect:", "html", "asJQuery", "get", "find:", "wrapper", "display", "name", "classes", "current", "pseudoVariableNames", "reject:", "=", "string", "select:", "includesSubString:", "asArray", "asSet", ","],
 referencedClasses: ["Smalltalk"]
 }),
 smalltalk.HLCodeWidget);

+ 28 - 30
js/IDE.deploy.js

@@ -474,7 +474,7 @@ return smalltalk.withContext(function($ctx2) {
 return _st(compiler)._parseExpression_(aString);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_($Error(),(function(ex){
 return smalltalk.withContext(function($ctx2) {
-$1=_st(window)._alert_(_st(ex)._messageText());
+$1=self._alert_(_st(ex)._messageText());
 throw $early=[$1];
 }, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
 $2=_st(compiler)._evaluateExpression_on_(aString,self._receiver());
@@ -891,13 +891,9 @@ selector: "onResize:",
 fn: function (aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-jQuery('#amber').resizable({
-	handles: 'n',
-	resize: aBlock,
-	minHeight: 230
-});
+_st("#amber"._asJQuery())._resizable_(smalltalk.HashedCollection._from_(["handles".__minus_gt("n"),"resize".__minus_gt(aBlock),"minHeight".__minus_gt((230))]));
 return self}, function($ctx1) {$ctx1.fill(self,"onResize:",{aBlock:aBlock},smalltalk.TabManager)})},
-messageSends: []}),
+messageSends: ["resizable:", "->", "asJQuery"]}),
 smalltalk.TabManager);
 
 smalltalk.addMethod(
@@ -906,9 +902,9 @@ selector: "onWindowResize:",
 fn: function (aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-jQuery(window).resize(aBlock);
+_st(_st(window)._asJQuery())._resize_(aBlock);
 return self}, function($ctx1) {$ctx1.fill(self,"onWindowResize:",{aBlock:aBlock},smalltalk.TabManager)})},
-messageSends: []}),
+messageSends: ["resize:", "asJQuery"]}),
 smalltalk.TabManager);
 
 smalltalk.addMethod(
@@ -1186,9 +1182,12 @@ selector: "updatePosition",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-jQuery('#amber').css('top', '').css('bottom', '0px');
+var $1,$2;
+$1="#amber"._asJQuery();
+_st($1)._css_put_("top","");
+$2=_st($1)._css_put_("bottom","0px");
 return self}, function($ctx1) {$ctx1.fill(self,"updatePosition",{},smalltalk.TabManager)})},
-messageSends: []}),
+messageSends: ["css:put:", "asJQuery"]}),
 smalltalk.TabManager);
 
 
@@ -1232,11 +1231,11 @@ function $Browser(){return smalltalk.Browser||(typeof Browser=="undefined"?nil:B
 function $TabManager(){return smalltalk.TabManager||(typeof TabManager=="undefined"?nil:TabManager)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-$1=_st(_st(_st(window)._jQuery_("#amber"))._length()).__eq((0));
+$1=_st(_st("#amber"._asJQuery())._length()).__eq((0));
 if(smalltalk.assert($1)){
 _st($Browser())._open();
 } else {
-$2=_st(_st(window)._jQuery_("#amber"))._is_(":visible");
+$2=_st("#amber"._asJQuery())._is_(":visible");
 if(smalltalk.assert($2)){
 _st(_st($TabManager())._current())._close();
 } else {
@@ -1244,7 +1243,7 @@ _st(_st($TabManager())._current())._open();
 };
 };
 return self}, function($ctx1) {$ctx1.fill(self,"toggleAmberIDE",{},smalltalk.TabManager.klass)})},
-messageSends: ["ifTrue:ifFalse:", "open", "close", "current", "is:", "jQuery:", "=", "length"]}),
+messageSends: ["ifTrue:ifFalse:", "open", "close", "current", "is:", "asJQuery", "=", "length"]}),
 smalltalk.TabManager.klass);
 
 
@@ -1446,7 +1445,7 @@ function $Object(){return smalltalk.Object||(typeof Object=="undefined"?nil:Obje
 function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3;
-className=_st(window)._prompt_("New class");
+className=self._prompt_("New class");
 $1=_st(_st(className)._notNil())._and_((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(className)._notEmpty();
@@ -1471,7 +1470,7 @@ var self=this;
 var newProtocol;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-newProtocol=_st(window)._prompt_("New method protocol");
+newProtocol=self._prompt_("New method protocol");
 $1=_st(_st(newProtocol)._notNil())._and_((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(newProtocol)._notEmpty();
@@ -1504,7 +1503,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=self["@unsavedChanges"];
 if(smalltalk.assert($2)){
-$1=_st(window)._confirm_("Cancel changes?");
+$1=self._confirm_("Cancel changes?");
 } else {
 $1=true;
 };
@@ -1706,6 +1705,7 @@ fn: function (aClass){
 var self=this;
 var compiler,method,source,node;
 function $Compiler(){return smalltalk.Compiler||(typeof Compiler=="undefined"?nil:Compiler)}
+function $PlatformInterface(){return smalltalk.PlatformInterface||(typeof PlatformInterface=="undefined"?nil:PlatformInterface)}
 function $ClassBuilder(){return smalltalk.ClassBuilder||(typeof ClassBuilder=="undefined"?nil:ClassBuilder)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3,$4,$5,$6;
@@ -1724,23 +1724,21 @@ _st(compiler)._source_(source);
 node=_st(compiler)._parse_(source);
 $2=_st(node)._isParseFailure();
 if(smalltalk.assert($2)){
-$3=_st(window)._alert_(_st(_st("PARSE ERROR: ".__comma(_st(node)._reason())).__comma(", position: ")).__comma(_st(_st(node)._position())._asString()));
+$3=self._alert_(_st(_st("PARSE ERROR: ".__comma(_st(node)._reason())).__comma(", position: ")).__comma(_st(_st(node)._position())._asString()));
 return $3;
 };
 _st(compiler)._currentClass_(aClass);
 method=_st(compiler)._eval_(_st(compiler)._compileNode_(node));
 _st(_st(compiler)._unknownVariables())._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
-$4=_st(window)._at_(each);
-if(($receiver = $4) == nil || $receiver == undefined){
-$5=_st(window)._confirm_(_st("Declare '".__comma(each)).__comma("' as instance variable?"));
+$4=_st($PlatformInterface())._existsGlobal_(each);
+if(! smalltalk.assert($4)){
+$5=self._confirm_(_st("Declare '".__comma(each)).__comma("' as instance variable?"));
 if(smalltalk.assert($5)){
 self._addInstanceVariableNamed_toClass_(each,aClass);
 $6=self._compileMethodDefinitionFor_(aClass);
 throw $early=[$6];
 };
-} else {
-return $4;
 };
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 _st(_st($ClassBuilder())._new())._installMethod_forClass_category_(method,aClass,self["@selectedProtocol"]);
@@ -1749,7 +1747,7 @@ self._selectMethod_(method);
 return self}
 catch(e) {if(e===$early)return e[0]; throw e}
 }, function($ctx1) {$ctx1.fill(self,"compileMethodDefinitionFor:",{aClass:aClass,compiler:compiler,method:method,source:source,node:node},smalltalk.Browser)})},
-messageSends: ["val", "ifNil:", "category", "new", "source:", "parse:", "ifTrue:", "alert:", ",", "asString", "position", "reason", "isParseFailure", "currentClass:", "eval:", "compileNode:", "do:", "addInstanceVariableNamed:toClass:", "compileMethodDefinitionFor:", "confirm:", "at:", "unknownVariables", "installMethod:forClass:category:", "updateMethodsList", "selectMethod:"]}),
+messageSends: ["val", "ifNil:", "category", "new", "source:", "parse:", "ifTrue:", "alert:", ",", "asString", "position", "reason", "isParseFailure", "currentClass:", "eval:", "compileNode:", "do:", "ifFalse:", "addInstanceVariableNamed:toClass:", "compileMethodDefinitionFor:", "confirm:", "existsGlobal:", "unknownVariables", "installMethod:forClass:category:", "updateMethodsList", "selectMethod:"]}),
 smalltalk.Browser);
 
 smalltalk.addMethod(
@@ -1762,7 +1760,7 @@ function $ClassBuilder(){return smalltalk.ClassBuilder||(typeof ClassBuilder=="u
 function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3;
-className=_st(window)._prompt_("Copy class");
+className=self._prompt_("Copy class");
 $1=_st(_st(className)._notNil())._and_((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(className)._notEmpty();
@@ -2068,7 +2066,7 @@ var self=this;
 function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(window)._confirm_(_st("Do you really want to remove ".__comma(_st(self["@selectedClass"])._name())).__comma("?"));
+$1=self._confirm_(_st("Do you really want to remove ".__comma(_st(self["@selectedClass"])._name())).__comma("?"));
 if(smalltalk.assert($1)){
 _st(_st($Smalltalk())._current())._removeClass_(self["@selectedClass"]);
 self._resetClassesList();
@@ -2087,7 +2085,7 @@ return smalltalk.withContext(function($ctx1) {
 var $1,$2,$3;
 $1=self._cancelChanges();
 if(smalltalk.assert($1)){
-$2=_st(window)._confirm_(_st("Do you really want to remove #".__comma(_st(self["@selectedMethod"])._selector())).__comma("?"));
+$2=self._confirm_(_st("Do you really want to remove #".__comma(_st(self["@selectedMethod"])._selector())).__comma("?"));
 if(smalltalk.assert($2)){
 $3=_st(self["@selectedTab"]).__eq("instance");
 if(smalltalk.assert($3)){
@@ -2110,7 +2108,7 @@ var self=this;
 function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(window)._confirm_(_st("Do you really want to remove the whole package ".__comma(self["@selectedPackage"])).__comma(" with all its classes?"));
+$1=self._confirm_(_st("Do you really want to remove the whole package ".__comma(self["@selectedPackage"])).__comma(" with all its classes?"));
 if(smalltalk.assert($1)){
 _st(_st($Smalltalk())._current())._removePackage_(self["@selectedPackage"]);
 self._updateCategoriesList();
@@ -2127,7 +2125,7 @@ var self=this;
 var newName;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3;
-newName=_st(window)._prompt_("Rename class ".__comma(_st(self["@selectedClass"])._name()));
+newName=self._prompt_("Rename class ".__comma(_st(self["@selectedClass"])._name()));
 $1=_st(_st(newName)._notNil())._and_((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(newName)._notEmpty();
@@ -2152,7 +2150,7 @@ var newName;
 function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-newName=_st(window)._prompt_("Rename package ".__comma(self["@selectedPackage"]));
+newName=self._prompt_("Rename package ".__comma(self["@selectedPackage"]));
 $1=newName;
 if(($receiver = $1) == nil || $receiver == undefined){
 $1;

+ 44 - 46
js/IDE.js

@@ -610,7 +610,7 @@ return smalltalk.withContext(function($ctx2) {
 return _st(compiler)._parseExpression_(aString);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_($Error(),(function(ex){
 return smalltalk.withContext(function($ctx2) {
-$1=_st(window)._alert_(_st(ex)._messageText());
+$1=self._alert_(_st(ex)._messageText());
 throw $early=[$1];
 }, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
 $2=_st(compiler)._evaluateExpression_on_(aString,self._receiver());
@@ -619,7 +619,7 @@ return $2;
 catch(e) {if(e===$early)return e[0]; throw e}
 }, function($ctx1) {$ctx1.fill(self,"eval:",{aString:aString,compiler:compiler},smalltalk.SourceArea)})},
 args: ["aString"],
-source: "eval: aString\x0a\x09| compiler |\x0a\x09compiler := Compiler new.\x0a\x09[ compiler parseExpression: aString ] on: Error do: [:ex |\x0a\x09\x09^window alert: ex messageText].\x0a\x09^compiler evaluateExpression: aString on: self receiver",
+source: "eval: aString\x0a\x09| compiler |\x0a\x09compiler := Compiler new.\x0a\x09[ compiler parseExpression: aString ] on: Error do: [:ex |\x0a\x09\x09^self alert: ex messageText].\x0a\x09^compiler evaluateExpression: aString on: self receiver",
 messageSends: ["new", "on:do:", "alert:", "messageText", "parseExpression:", "evaluateExpression:on:", "receiver"],
 referencedClasses: ["Compiler", "Error"]
 }),
@@ -1157,15 +1157,11 @@ category: 'actions',
 fn: function (aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-jQuery('#amber').resizable({
-	handles: 'n',
-	resize: aBlock,
-	minHeight: 230
-});
+_st("#amber"._asJQuery())._resizable_(smalltalk.HashedCollection._from_(["handles".__minus_gt("n"),"resize".__minus_gt(aBlock),"minHeight".__minus_gt((230))]));
 return self}, function($ctx1) {$ctx1.fill(self,"onResize:",{aBlock:aBlock},smalltalk.TabManager)})},
 args: ["aBlock"],
-source: "onResize: aBlock\x0a\x09<jQuery('#amber').resizable({\x0a\x09handles: 'n',\x0a\x09resize: aBlock,\x0a\x09minHeight: 230\x0a})>",
-messageSends: [],
+source: "onResize: aBlock\x0a\x09'#amber' asJQuery resizable: #{\x0a\x09\x09'handles' -> 'n'.\x0a\x09\x09'resize' -> aBlock.\x0a\x09\x09'minHeight' -> 230\x0a\x09}",
+messageSends: ["resizable:", "->", "asJQuery"],
 referencedClasses: []
 }),
 smalltalk.TabManager);
@@ -1177,11 +1173,11 @@ category: 'actions',
 fn: function (aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-jQuery(window).resize(aBlock);
+_st(_st(window)._asJQuery())._resize_(aBlock);
 return self}, function($ctx1) {$ctx1.fill(self,"onWindowResize:",{aBlock:aBlock},smalltalk.TabManager)})},
 args: ["aBlock"],
-source: "onWindowResize: aBlock\x0a\x09<jQuery(window).resize(aBlock)>",
-messageSends: [],
+source: "onWindowResize: aBlock\x0a\x09window asJQuery resize: aBlock",
+messageSends: ["resize:", "asJQuery"],
 referencedClasses: []
 }),
 smalltalk.TabManager);
@@ -1527,11 +1523,14 @@ category: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-jQuery('#amber').css('top', '').css('bottom', '0px');
+var $1,$2;
+$1="#amber"._asJQuery();
+_st($1)._css_put_("top","");
+$2=_st($1)._css_put_("bottom","0px");
 return self}, function($ctx1) {$ctx1.fill(self,"updatePosition",{},smalltalk.TabManager)})},
 args: [],
-source: "updatePosition\x0a\x09<jQuery('#amber').css('top', '').css('bottom', '0px')>",
-messageSends: [],
+source: "updatePosition\x0a\x09'#amber' asJQuery\x0a\x09\x09css: 'top' put: '';\x0a\x09\x09css: 'bottom' put: '0px'",
+messageSends: ["css:put:", "asJQuery"],
 referencedClasses: []
 }),
 smalltalk.TabManager);
@@ -1588,11 +1587,11 @@ function $Browser(){return smalltalk.Browser||(typeof Browser=="undefined"?nil:B
 function $TabManager(){return smalltalk.TabManager||(typeof TabManager=="undefined"?nil:TabManager)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-$1=_st(_st(_st(window)._jQuery_("#amber"))._length()).__eq((0));
+$1=_st(_st("#amber"._asJQuery())._length()).__eq((0));
 if(smalltalk.assert($1)){
 _st($Browser())._open();
 } else {
-$2=_st(_st(window)._jQuery_("#amber"))._is_(":visible");
+$2=_st("#amber"._asJQuery())._is_(":visible");
 if(smalltalk.assert($2)){
 _st(_st($TabManager())._current())._close();
 } else {
@@ -1601,8 +1600,8 @@ _st(_st($TabManager())._current())._open();
 };
 return self}, function($ctx1) {$ctx1.fill(self,"toggleAmberIDE",{},smalltalk.TabManager.klass)})},
 args: [],
-source: "toggleAmberIDE\x0a\x09(window jQuery: '#amber') length = 0\x0a\x09\x09ifTrue: [ Browser open ]\x0a\x09\x09ifFalse: [\x0a\x09\x09\x09((window jQuery: '#amber') is: ':visible')\x0a\x09\x09\x09\x09ifTrue: [ TabManager current close ]\x0a\x09\x09\x09\x09ifFalse: [ TabManager current open ] ]",
-messageSends: ["ifTrue:ifFalse:", "open", "close", "current", "is:", "jQuery:", "=", "length"],
+source: "toggleAmberIDE\x0a\x09'#amber' asJQuery length = 0\x0a\x09\x09ifTrue: [ Browser open ]\x0a\x09\x09ifFalse: [\x0a\x09\x09\x09('#amber' asJQuery is: ':visible')\x0a\x09\x09\x09\x09ifTrue: [ TabManager current close ]\x0a\x09\x09\x09\x09ifFalse: [ TabManager current open ] ]",
+messageSends: ["ifTrue:ifFalse:", "open", "close", "current", "is:", "asJQuery", "=", "length"],
 referencedClasses: ["Browser", "TabManager"]
 }),
 smalltalk.TabManager.klass);
@@ -1877,7 +1876,7 @@ function $Object(){return smalltalk.Object||(typeof Object=="undefined"?nil:Obje
 function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3;
-className=_st(window)._prompt_("New class");
+className=self._prompt_("New class");
 $1=_st(_st(className)._notNil())._and_((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(className)._notEmpty();
@@ -1892,7 +1891,7 @@ self._selectClass_(_st(_st($Smalltalk())._current())._at_(className));
 };
 return self}, function($ctx1) {$ctx1.fill(self,"addNewClass",{className:className},smalltalk.Browser)})},
 args: [],
-source: "addNewClass\x0a\x09| className |\x0a\x09className := window prompt: 'New class'.\x0a\x09(className notNil and: [className notEmpty]) ifTrue: [\x0a\x09\x09Object subclass: className instanceVariableNames: '' package: self selectedPackage.\x0a\x09\x09\x09self\x0a\x09\x09\x09resetClassesList;\x0a\x09\x09\x09updateClassesList.\x0a\x09\x09self selectClass: (Smalltalk current at: className)]",
+source: "addNewClass\x0a\x09| className |\x0a\x09className := self prompt: 'New class'.\x0a\x09(className notNil and: [className notEmpty]) ifTrue: [\x0a\x09\x09Object subclass: className instanceVariableNames: '' package: self selectedPackage.\x0a\x09\x09\x09self\x0a\x09\x09\x09resetClassesList;\x0a\x09\x09\x09updateClassesList.\x0a\x09\x09self selectClass: (Smalltalk current at: className)]",
 messageSends: ["prompt:", "ifTrue:", "subclass:instanceVariableNames:package:", "selectedPackage", "resetClassesList", "updateClassesList", "selectClass:", "at:", "current", "and:", "notEmpty", "notNil"],
 referencedClasses: ["Object", "Smalltalk"]
 }),
@@ -1907,7 +1906,7 @@ var self=this;
 var newProtocol;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-newProtocol=_st(window)._prompt_("New method protocol");
+newProtocol=self._prompt_("New method protocol");
 $1=_st(_st(newProtocol)._notNil())._and_((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(newProtocol)._notEmpty();
@@ -1918,7 +1917,7 @@ self._setMethodProtocol_(newProtocol);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"addNewProtocol",{newProtocol:newProtocol},smalltalk.Browser)})},
 args: [],
-source: "addNewProtocol\x0a\x09| newProtocol |\x0a\x09newProtocol := window prompt: 'New method protocol'.\x0a\x09(newProtocol notNil and: [newProtocol notEmpty]) ifTrue: [\x0a\x09selectedMethod category: newProtocol.\x0a\x09self setMethodProtocol: newProtocol]",
+source: "addNewProtocol\x0a\x09| newProtocol |\x0a\x09newProtocol := self prompt: 'New method protocol'.\x0a\x09(newProtocol notNil and: [newProtocol notEmpty]) ifTrue: [\x0a\x09selectedMethod category: newProtocol.\x0a\x09self setMethodProtocol: newProtocol]",
 messageSends: ["prompt:", "ifTrue:", "category:", "setMethodProtocol:", "and:", "notEmpty", "notNil"],
 referencedClasses: []
 }),
@@ -1950,14 +1949,14 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=self["@unsavedChanges"];
 if(smalltalk.assert($2)){
-$1=_st(window)._confirm_("Cancel changes?");
+$1=self._confirm_("Cancel changes?");
 } else {
 $1=true;
 };
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"cancelChanges",{},smalltalk.Browser)})},
 args: [],
-source: "cancelChanges\x0a\x09^unsavedChanges\x0a\x09ifTrue: [window confirm: 'Cancel changes?']\x0a\x09ifFalse: [true]",
+source: "cancelChanges\x0a\x09^unsavedChanges\x0a\x09ifTrue: [self confirm: 'Cancel changes?']\x0a\x09ifFalse: [true]",
 messageSends: ["ifTrue:ifFalse:", "confirm:"],
 referencedClasses: []
 }),
@@ -2202,6 +2201,7 @@ fn: function (aClass){
 var self=this;
 var compiler,method,source,node;
 function $Compiler(){return smalltalk.Compiler||(typeof Compiler=="undefined"?nil:Compiler)}
+function $PlatformInterface(){return smalltalk.PlatformInterface||(typeof PlatformInterface=="undefined"?nil:PlatformInterface)}
 function $ClassBuilder(){return smalltalk.ClassBuilder||(typeof ClassBuilder=="undefined"?nil:ClassBuilder)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3,$4,$5,$6;
@@ -2220,23 +2220,21 @@ _st(compiler)._source_(source);
 node=_st(compiler)._parse_(source);
 $2=_st(node)._isParseFailure();
 if(smalltalk.assert($2)){
-$3=_st(window)._alert_(_st(_st("PARSE ERROR: ".__comma(_st(node)._reason())).__comma(", position: ")).__comma(_st(_st(node)._position())._asString()));
+$3=self._alert_(_st(_st("PARSE ERROR: ".__comma(_st(node)._reason())).__comma(", position: ")).__comma(_st(_st(node)._position())._asString()));
 return $3;
 };
 _st(compiler)._currentClass_(aClass);
 method=_st(compiler)._eval_(_st(compiler)._compileNode_(node));
 _st(_st(compiler)._unknownVariables())._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
-$4=_st(window)._at_(each);
-if(($receiver = $4) == nil || $receiver == undefined){
-$5=_st(window)._confirm_(_st("Declare '".__comma(each)).__comma("' as instance variable?"));
+$4=_st($PlatformInterface())._existsGlobal_(each);
+if(! smalltalk.assert($4)){
+$5=self._confirm_(_st("Declare '".__comma(each)).__comma("' as instance variable?"));
 if(smalltalk.assert($5)){
 self._addInstanceVariableNamed_toClass_(each,aClass);
 $6=self._compileMethodDefinitionFor_(aClass);
 throw $early=[$6];
 };
-} else {
-return $4;
 };
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
 _st(_st($ClassBuilder())._new())._installMethod_forClass_category_(method,aClass,self["@selectedProtocol"]);
@@ -2246,9 +2244,9 @@ return self}
 catch(e) {if(e===$early)return e[0]; throw e}
 }, function($ctx1) {$ctx1.fill(self,"compileMethodDefinitionFor:",{aClass:aClass,compiler:compiler,method:method,source:source,node:node},smalltalk.Browser)})},
 args: ["aClass"],
-source: "compileMethodDefinitionFor: aClass\x0a\x09| compiler method source node |\x0a\x09source := sourceArea val.\x0a\x09selectedProtocol ifNil: [ selectedProtocol := selectedMethod category ].\x0a\x09compiler := Compiler new.\x0a\x09compiler source: source.\x0a\x09node := compiler parse: source.\x0a\x09node isParseFailure ifTrue: [\x0a\x09^window alert: 'PARSE ERROR: ', node reason, ', position: ', node position asString].\x0a\x09compiler currentClass: aClass.\x0a\x09method := compiler eval: (compiler compileNode: node).\x0a\x09compiler unknownVariables do: [:each |\x0a\x09\x09\x22Do not try to redeclare javascript's objects\x22\x0a\x09\x09(window at: each) ifNil: [\x0a\x09\x09(window confirm: 'Declare ''', each, ''' as instance variable?') ifTrue: [\x0a\x09\x09\x09self addInstanceVariableNamed: each toClass: aClass.\x0a\x09\x09\x09^self compileMethodDefinitionFor: aClass]]].\x0a\x09ClassBuilder new installMethod: method forClass: aClass category: selectedProtocol.\x0a\x09self updateMethodsList.\x0a\x09self selectMethod: method",
-messageSends: ["val", "ifNil:", "category", "new", "source:", "parse:", "ifTrue:", "alert:", ",", "asString", "position", "reason", "isParseFailure", "currentClass:", "eval:", "compileNode:", "do:", "addInstanceVariableNamed:toClass:", "compileMethodDefinitionFor:", "confirm:", "at:", "unknownVariables", "installMethod:forClass:category:", "updateMethodsList", "selectMethod:"],
-referencedClasses: ["Compiler", "ClassBuilder"]
+source: "compileMethodDefinitionFor: aClass\x0a\x09| compiler method source node |\x0a\x09source := sourceArea val.\x0a\x09selectedProtocol ifNil: [ selectedProtocol := selectedMethod category ].\x0a\x09compiler := Compiler new.\x0a\x09compiler source: source.\x0a\x09node := compiler parse: source.\x0a\x09node isParseFailure ifTrue: [\x0a\x09^self alert: 'PARSE ERROR: ', node reason, ', position: ', node position asString].\x0a\x09compiler currentClass: aClass.\x0a\x09method := compiler eval: (compiler compileNode: node).\x0a\x09compiler unknownVariables do: [:each |\x0a\x09\x09\x22Do not try to redeclare javascript's objects\x22\x0a\x09\x09(PlatformInterface existsGlobal: each) ifFalse: [\x0a\x09\x09(self confirm: 'Declare ''', each, ''' as instance variable?') ifTrue: [\x0a\x09\x09\x09self addInstanceVariableNamed: each toClass: aClass.\x0a\x09\x09\x09^self compileMethodDefinitionFor: aClass]]].\x0a\x09ClassBuilder new installMethod: method forClass: aClass category: selectedProtocol.\x0a\x09self updateMethodsList.\x0a\x09self selectMethod: method",
+messageSends: ["val", "ifNil:", "category", "new", "source:", "parse:", "ifTrue:", "alert:", ",", "asString", "position", "reason", "isParseFailure", "currentClass:", "eval:", "compileNode:", "do:", "ifFalse:", "addInstanceVariableNamed:toClass:", "compileMethodDefinitionFor:", "confirm:", "existsGlobal:", "unknownVariables", "installMethod:forClass:category:", "updateMethodsList", "selectMethod:"],
+referencedClasses: ["Compiler", "PlatformInterface", "ClassBuilder"]
 }),
 smalltalk.Browser);
 
@@ -2263,7 +2261,7 @@ function $ClassBuilder(){return smalltalk.ClassBuilder||(typeof ClassBuilder=="u
 function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3;
-className=_st(window)._prompt_("Copy class");
+className=self._prompt_("Copy class");
 $1=_st(_st(className)._notNil())._and_((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(className)._notEmpty();
@@ -2278,7 +2276,7 @@ self._selectClass_(_st(_st($Smalltalk())._current())._at_(className));
 };
 return self}, function($ctx1) {$ctx1.fill(self,"copyClass",{className:className},smalltalk.Browser)})},
 args: [],
-source: "copyClass\x0a\x09| className |\x0a\x09className := window prompt: 'Copy class'.\x0a\x09(className notNil and: [className notEmpty]) ifTrue: [\x0a\x09\x09ClassBuilder new copyClass: self selectedClass named: className.\x0a\x09\x09\x09self\x0a\x09\x09\x09resetClassesList;\x0a\x09\x09\x09updateClassesList.\x0a\x09\x09self selectClass: (Smalltalk current at: className)]",
+source: "copyClass\x0a\x09| className |\x0a\x09className := self prompt: 'Copy class'.\x0a\x09(className notNil and: [className notEmpty]) ifTrue: [\x0a\x09\x09ClassBuilder new copyClass: self selectedClass named: className.\x0a\x09\x09\x09self\x0a\x09\x09\x09resetClassesList;\x0a\x09\x09\x09updateClassesList.\x0a\x09\x09self selectClass: (Smalltalk current at: className)]",
 messageSends: ["prompt:", "ifTrue:", "copyClass:named:", "selectedClass", "new", "resetClassesList", "updateClassesList", "selectClass:", "at:", "current", "and:", "notEmpty", "notNil"],
 referencedClasses: ["ClassBuilder", "Smalltalk"]
 }),
@@ -2639,7 +2637,7 @@ var self=this;
 function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(window)._confirm_(_st("Do you really want to remove ".__comma(_st(self["@selectedClass"])._name())).__comma("?"));
+$1=self._confirm_(_st("Do you really want to remove ".__comma(_st(self["@selectedClass"])._name())).__comma("?"));
 if(smalltalk.assert($1)){
 _st(_st($Smalltalk())._current())._removeClass_(self["@selectedClass"]);
 self._resetClassesList();
@@ -2647,7 +2645,7 @@ self._selectClass_(nil);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"removeClass",{},smalltalk.Browser)})},
 args: [],
-source: "removeClass\x0a\x09(window confirm: 'Do you really want to remove ', selectedClass name, '?')\x0a\x09ifTrue: [\x0a\x09\x09Smalltalk current removeClass: selectedClass.\x0a\x09\x09self resetClassesList.\x0a\x09\x09self selectClass: nil]",
+source: "removeClass\x0a\x09(self confirm: 'Do you really want to remove ', selectedClass name, '?')\x0a\x09ifTrue: [\x0a\x09\x09Smalltalk current removeClass: selectedClass.\x0a\x09\x09self resetClassesList.\x0a\x09\x09self selectClass: nil]",
 messageSends: ["ifTrue:", "removeClass:", "current", "resetClassesList", "selectClass:", "confirm:", ",", "name"],
 referencedClasses: ["Smalltalk"]
 }),
@@ -2663,7 +2661,7 @@ return smalltalk.withContext(function($ctx1) {
 var $1,$2,$3;
 $1=self._cancelChanges();
 if(smalltalk.assert($1)){
-$2=_st(window)._confirm_(_st("Do you really want to remove #".__comma(_st(self["@selectedMethod"])._selector())).__comma("?"));
+$2=self._confirm_(_st("Do you really want to remove #".__comma(_st(self["@selectedMethod"])._selector())).__comma("?"));
 if(smalltalk.assert($2)){
 $3=_st(self["@selectedTab"]).__eq("instance");
 if(smalltalk.assert($3)){
@@ -2676,7 +2674,7 @@ self._selectMethod_(nil);
 };
 return self}, function($ctx1) {$ctx1.fill(self,"removeMethod",{},smalltalk.Browser)})},
 args: [],
-source: "removeMethod\x0a\x09self cancelChanges ifTrue: [\x0a\x09(window confirm: 'Do you really want to remove #', selectedMethod selector, '?')\x0a\x09\x09ifTrue: [\x0a\x09\x09selectedTab = #instance\x0a\x09\x09\x09ifTrue: [selectedClass removeCompiledMethod: selectedMethod]\x0a\x09\x09\x09ifFalse: [selectedClass class removeCompiledMethod: selectedMethod].\x0a\x09\x09self selectMethod: nil]]",
+source: "removeMethod\x0a\x09self cancelChanges ifTrue: [\x0a\x09(self confirm: 'Do you really want to remove #', selectedMethod selector, '?')\x0a\x09\x09ifTrue: [\x0a\x09\x09selectedTab = #instance\x0a\x09\x09\x09ifTrue: [selectedClass removeCompiledMethod: selectedMethod]\x0a\x09\x09\x09ifFalse: [selectedClass class removeCompiledMethod: selectedMethod].\x0a\x09\x09self selectMethod: nil]]",
 messageSends: ["ifTrue:", "ifTrue:ifFalse:", "removeCompiledMethod:", "class", "=", "selectMethod:", "confirm:", ",", "selector", "cancelChanges"],
 referencedClasses: []
 }),
@@ -2691,14 +2689,14 @@ var self=this;
 function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st(window)._confirm_(_st("Do you really want to remove the whole package ".__comma(self["@selectedPackage"])).__comma(" with all its classes?"));
+$1=self._confirm_(_st("Do you really want to remove the whole package ".__comma(self["@selectedPackage"])).__comma(" with all its classes?"));
 if(smalltalk.assert($1)){
 _st(_st($Smalltalk())._current())._removePackage_(self["@selectedPackage"]);
 self._updateCategoriesList();
 };
 return self}, function($ctx1) {$ctx1.fill(self,"removePackage",{},smalltalk.Browser)})},
 args: [],
-source: "removePackage\x0a\x0a\x09(window confirm: 'Do you really want to remove the whole package ', selectedPackage, ' with all its classes?')\x0a\x09ifTrue: [\x0a\x09\x09Smalltalk current removePackage: selectedPackage.\x0a\x09\x09self updateCategoriesList]",
+source: "removePackage\x0a\x0a\x09(self confirm: 'Do you really want to remove the whole package ', selectedPackage, ' with all its classes?')\x0a\x09ifTrue: [\x0a\x09\x09Smalltalk current removePackage: selectedPackage.\x0a\x09\x09self updateCategoriesList]",
 messageSends: ["ifTrue:", "removePackage:", "current", "updateCategoriesList", "confirm:", ","],
 referencedClasses: ["Smalltalk"]
 }),
@@ -2713,7 +2711,7 @@ var self=this;
 var newName;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3;
-newName=_st(window)._prompt_("Rename class ".__comma(_st(self["@selectedClass"])._name()));
+newName=self._prompt_("Rename class ".__comma(_st(self["@selectedClass"])._name()));
 $1=_st(_st(newName)._notNil())._and_((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(newName)._notEmpty();
@@ -2727,7 +2725,7 @@ $3;
 };
 return self}, function($ctx1) {$ctx1.fill(self,"renameClass",{newName:newName},smalltalk.Browser)})},
 args: [],
-source: "renameClass\x0a\x09| newName |\x0a\x09newName := window prompt: 'Rename class ', selectedClass name.\x0a\x09(newName notNil and: [newName notEmpty]) ifTrue: [\x0a\x09selectedClass rename: newName.\x0a\x09self\x0a\x09\x09updateClassesList;\x0a\x09\x09updateSourceAndButtons]",
+source: "renameClass\x0a\x09| newName |\x0a\x09newName := self prompt: 'Rename class ', selectedClass name.\x0a\x09(newName notNil and: [newName notEmpty]) ifTrue: [\x0a\x09selectedClass rename: newName.\x0a\x09self\x0a\x09\x09updateClassesList;\x0a\x09\x09updateSourceAndButtons]",
 messageSends: ["prompt:", ",", "name", "ifTrue:", "rename:", "updateClassesList", "updateSourceAndButtons", "and:", "notEmpty", "notNil"],
 referencedClasses: []
 }),
@@ -2743,7 +2741,7 @@ var newName;
 function $Smalltalk(){return smalltalk.Smalltalk||(typeof Smalltalk=="undefined"?nil:Smalltalk)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2;
-newName=_st(window)._prompt_("Rename package ".__comma(self["@selectedPackage"]));
+newName=self._prompt_("Rename package ".__comma(self["@selectedPackage"]));
 $1=newName;
 if(($receiver = $1) == nil || $receiver == undefined){
 $1;
@@ -2756,7 +2754,7 @@ self._updateCategoriesList();
 };
 return self}, function($ctx1) {$ctx1.fill(self,"renamePackage",{newName:newName},smalltalk.Browser)})},
 args: [],
-source: "renamePackage\x0a\x0a\x09| newName |\x0a\x09newName := window prompt: 'Rename package ', selectedPackage.\x0a\x09newName ifNotNil: [\x0a\x09newName notEmpty ifTrue: [\x0a\x09Smalltalk current renamePackage: selectedPackage to: newName.\x0a\x09self updateCategoriesList]]",
+source: "renamePackage\x0a\x0a\x09| newName |\x0a\x09newName := self prompt: 'Rename package ', selectedPackage.\x0a\x09newName ifNotNil: [\x0a\x09newName notEmpty ifTrue: [\x0a\x09Smalltalk current renamePackage: selectedPackage to: newName.\x0a\x09self updateCategoriesList]]",
 messageSends: ["prompt:", ",", "ifNotNil:", "ifTrue:", "renamePackage:to:", "current", "updateCategoriesList", "notEmpty"],
 referencedClasses: ["Smalltalk"]
 }),

+ 6 - 6
js/Importer-Exporter.deploy.js

@@ -781,19 +781,19 @@ smalltalk.Importer);
 
 
 
-smalltalk.addClass('PackageHandler', smalltalk.Object, [], 'Importer-Exporter');
+smalltalk.addClass('PackageHandler', smalltalk.InterfacingObject, [], 'Importer-Exporter');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "ajaxPutAt:data:",
 fn: function (aURL,aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(jQuery)._ajax_options_(aURL,smalltalk.HashedCollection._from_(["type".__minus_gt("PUT"),"data".__minus_gt(aString),"contentType".__minus_gt("text/plain;charset=UTF-8"),"error".__minus_gt((function(xhr){
+self._ajax_(smalltalk.HashedCollection._from_(["url".__minus_gt(aURL),"type".__minus_gt("PUT"),"data".__minus_gt(aString),"contentType".__minus_gt("text/plain;charset=UTF-8"),"error".__minus_gt((function(xhr){
 return smalltalk.withContext(function($ctx2) {
 return self._error_(_st(_st(_st("Commiting ".__comma(aURL)).__comma(" failed with reason: \x22")).__comma(_st(xhr)._responseText())).__comma("\x22"));
 }, function($ctx2) {$ctx2.fillBlock({xhr:xhr},$ctx1)})}))]));
 return self}, function($ctx1) {$ctx1.fill(self,"ajaxPutAt:data:",{aURL:aURL,aString:aString},smalltalk.PackageHandler)})},
-messageSends: ["ajax:options:", "->", "error:", ",", "responseText"]}),
+messageSends: ["ajax:", "->", "error:", ",", "responseText"]}),
 smalltalk.PackageHandler);
 
 smalltalk.addMethod(
@@ -1105,7 +1105,7 @@ var url;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 url=_st(_st(_st("/".__comma(aString)).__comma("/js/")).__comma(packageName)).__comma(".js");
-_st(jQuery)._ajax_options_(url,smalltalk.HashedCollection._from_(["type".__minus_gt("GET"),"dataType".__minus_gt("script"),"complete".__minus_gt((function(jqXHR,textStatus){
+self._ajax_(smalltalk.HashedCollection._from_(["url".__minus_gt(url),"type".__minus_gt("GET"),"dataType".__minus_gt("script"),"complete".__minus_gt((function(jqXHR,textStatus){
 return smalltalk.withContext(function($ctx2) {
 $1=_st(_st(jqXHR)._readyState()).__eq((4));
 if(smalltalk.assert($1)){
@@ -1113,10 +1113,10 @@ return self._setupPackageNamed_prefix_(packageName,aString);
 };
 }, function($ctx2) {$ctx2.fillBlock({jqXHR:jqXHR,textStatus:textStatus},$ctx1)})})),"error".__minus_gt((function(){
 return smalltalk.withContext(function($ctx2) {
-return _st(window)._alert_("Could not load package at: ".__comma(url));
+return self._alert_("Could not load package at: ".__comma(url));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))]));
 return self}, function($ctx1) {$ctx1.fill(self,"loadPackage:prefix:",{packageName:packageName,aString:aString,url:url},smalltalk.LegacyPackageHandler)})},
-messageSends: [",", "ajax:options:", "->", "ifTrue:", "setupPackageNamed:prefix:", "=", "readyState", "alert:"]}),
+messageSends: [",", "ajax:", "->", "ifTrue:", "setupPackageNamed:prefix:", "=", "readyState", "alert:"]}),
 smalltalk.LegacyPackageHandler);
 
 smalltalk.addMethod(

+ 8 - 8
js/Importer-Exporter.js

@@ -956,7 +956,7 @@ smalltalk.Importer);
 
 
 
-smalltalk.addClass('PackageHandler', smalltalk.Object, [], 'Importer-Exporter');
+smalltalk.addClass('PackageHandler', smalltalk.InterfacingObject, [], 'Importer-Exporter');
 smalltalk.PackageHandler.comment="I am responsible for handling package loading and committing.\x0a\x0aI should not be used directly. Instead, use the corresponding `Package` methods.";
 smalltalk.addMethod(
 smalltalk.method({
@@ -965,14 +965,14 @@ category: 'private',
 fn: function (aURL,aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(jQuery)._ajax_options_(aURL,smalltalk.HashedCollection._from_(["type".__minus_gt("PUT"),"data".__minus_gt(aString),"contentType".__minus_gt("text/plain;charset=UTF-8"),"error".__minus_gt((function(xhr){
+self._ajax_(smalltalk.HashedCollection._from_(["url".__minus_gt(aURL),"type".__minus_gt("PUT"),"data".__minus_gt(aString),"contentType".__minus_gt("text/plain;charset=UTF-8"),"error".__minus_gt((function(xhr){
 return smalltalk.withContext(function($ctx2) {
 return self._error_(_st(_st(_st("Commiting ".__comma(aURL)).__comma(" failed with reason: \x22")).__comma(_st(xhr)._responseText())).__comma("\x22"));
 }, function($ctx2) {$ctx2.fillBlock({xhr:xhr},$ctx1)})}))]));
 return self}, function($ctx1) {$ctx1.fill(self,"ajaxPutAt:data:",{aURL:aURL,aString:aString},smalltalk.PackageHandler)})},
 args: ["aURL", "aString"],
-source: "ajaxPutAt: aURL data: aString\x0a\x09jQuery\x0a\x09\x09ajax: aURL \x0a\x09\x09options: #{ \x0a\x09\x09\x09'type' -> 'PUT'.\x0a\x09\x09\x09'data' -> aString.\x0a\x09\x09\x09'contentType' -> 'text/plain;charset=UTF-8'.\x0a\x09\x09\x09'error' -> [ :xhr | self error: 'Commiting ' , aURL , ' failed with reason: \x22' , (xhr responseText) , '\x22'] }",
-messageSends: ["ajax:options:", "->", "error:", ",", "responseText"],
+source: "ajaxPutAt: aURL data: aString\x0a\x09self\x0a\x09\x09ajax: #{\x0a\x09\x09\x09'url' -> aURL.\x0a\x09\x09\x09'type' -> 'PUT'.\x0a\x09\x09\x09'data' -> aString.\x0a\x09\x09\x09'contentType' -> 'text/plain;charset=UTF-8'.\x0a\x09\x09\x09'error' -> [ :xhr | self error: 'Commiting ' , aURL , ' failed with reason: \x22' , (xhr responseText) , '\x22'] }",
+messageSends: ["ajax:", "->", "error:", ",", "responseText"],
 referencedClasses: []
 }),
 smalltalk.PackageHandler);
@@ -1384,7 +1384,7 @@ var url;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 url=_st(_st(_st("/".__comma(aString)).__comma("/js/")).__comma(packageName)).__comma(".js");
-_st(jQuery)._ajax_options_(url,smalltalk.HashedCollection._from_(["type".__minus_gt("GET"),"dataType".__minus_gt("script"),"complete".__minus_gt((function(jqXHR,textStatus){
+self._ajax_(smalltalk.HashedCollection._from_(["url".__minus_gt(url),"type".__minus_gt("GET"),"dataType".__minus_gt("script"),"complete".__minus_gt((function(jqXHR,textStatus){
 return smalltalk.withContext(function($ctx2) {
 $1=_st(_st(jqXHR)._readyState()).__eq((4));
 if(smalltalk.assert($1)){
@@ -1392,12 +1392,12 @@ return self._setupPackageNamed_prefix_(packageName,aString);
 };
 }, function($ctx2) {$ctx2.fillBlock({jqXHR:jqXHR,textStatus:textStatus},$ctx1)})})),"error".__minus_gt((function(){
 return smalltalk.withContext(function($ctx2) {
-return _st(window)._alert_("Could not load package at: ".__comma(url));
+return self._alert_("Could not load package at: ".__comma(url));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))]));
 return self}, function($ctx1) {$ctx1.fill(self,"loadPackage:prefix:",{packageName:packageName,aString:aString,url:url},smalltalk.LegacyPackageHandler)})},
 args: ["packageName", "aString"],
-source: "loadPackage: packageName prefix: aString\x0a\x09| url |\x0a\x09url := '/', aString, '/js/', packageName, '.js'.\x0a\x09jQuery\x0a\x09\x09ajax: url\x0a\x09\x09options: #{\x0a\x09\x09\x09'type' -> 'GET'.\x0a\x09\x09\x09'dataType' -> 'script'.\x0a\x09\x09\x09'complete' -> [ :jqXHR :textStatus |\x0a\x09\x09\x09\x09jqXHR readyState = 4\x0a\x09\x09\x09\x09\x09ifTrue: [ self setupPackageNamed: packageName prefix: aString ] ].\x0a\x09\x09\x09'error' -> [ window alert: 'Could not load package at: ', url ]\x0a\x09\x09}",
-messageSends: [",", "ajax:options:", "->", "ifTrue:", "setupPackageNamed:prefix:", "=", "readyState", "alert:"],
+source: "loadPackage: packageName prefix: aString\x0a\x09| url |\x0a\x09url := '/', aString, '/js/', packageName, '.js'.\x0a\x09self\x0a\x09\x09ajax: #{\x0a\x09\x09\x09'url' -> url.\x0a\x09\x09\x09'type' -> 'GET'.\x0a\x09\x09\x09'dataType' -> 'script'.\x0a\x09\x09\x09'complete' -> [ :jqXHR :textStatus |\x0a\x09\x09\x09\x09jqXHR readyState = 4\x0a\x09\x09\x09\x09\x09ifTrue: [ self setupPackageNamed: packageName prefix: aString ] ].\x0a\x09\x09\x09'error' -> [ self alert: 'Could not load package at: ', url ]\x0a\x09\x09}",
+messageSends: [",", "ajax:", "->", "ifTrue:", "setupPackageNamed:prefix:", "=", "readyState", "alert:"],
 referencedClasses: []
 }),
 smalltalk.LegacyPackageHandler);

+ 1 - 4
js/Kernel-Classes.deploy.js

@@ -180,10 +180,7 @@ selector: "basicRemoveCompiledMethod:",
 fn: function (aMethod){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-
-		smalltalk.removeMethod(aMethod)
-		smalltalk.init(self);
-	;
+smalltalk.removeMethod(aMethod,self);
 return self}, function($ctx1) {$ctx1.fill(self,"basicRemoveCompiledMethod:",{aMethod:aMethod},smalltalk.Behavior)})},
 messageSends: []}),
 smalltalk.Behavior);

+ 2 - 5
js/Kernel-Classes.js

@@ -227,13 +227,10 @@ category: 'private',
 fn: function (aMethod){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-
-		smalltalk.removeMethod(aMethod)
-		smalltalk.init(self);
-	;
+smalltalk.removeMethod(aMethod,self);
 return self}, function($ctx1) {$ctx1.fill(self,"basicRemoveCompiledMethod:",{aMethod:aMethod},smalltalk.Behavior)})},
 args: ["aMethod"],
-source: "basicRemoveCompiledMethod: aMethod\x0a\x09<\x0a\x09\x09smalltalk.removeMethod(aMethod)\x0a\x09\x09smalltalk.init(self);\x0a\x09>",
+source: "basicRemoveCompiledMethod: aMethod\x0a\x09<smalltalk.removeMethod(aMethod,self)>",
 messageSends: [],
 referencedClasses: []
 }),

+ 6 - 9
js/Kernel-Methods.deploy.js

@@ -1296,16 +1296,13 @@ smalltalk.method({
 selector: "exists:",
 fn: function (aString){
 var self=this;
+function $PlatformInterface(){return smalltalk.PlatformInterface||(typeof PlatformInterface=="undefined"?nil:PlatformInterface)}
 return smalltalk.withContext(function($ctx1) { 
-
-		if(aString in window) {
-			return true
-		} else {
-			return false
-		}
-	;
-return self}, function($ctx1) {$ctx1.fill(self,"exists:",{aString:aString},smalltalk.NativeFunction.klass)})},
-messageSends: []}),
+var $1;
+$1=_st($PlatformInterface())._existsGlobal_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"exists:",{aString:aString},smalltalk.NativeFunction.klass)})},
+messageSends: ["existsGlobal:"]}),
 smalltalk.NativeFunction.klass);
 
 

+ 8 - 11
js/Kernel-Methods.js

@@ -1754,19 +1754,16 @@ selector: "exists:",
 category: 'testing',
 fn: function (aString){
 var self=this;
+function $PlatformInterface(){return smalltalk.PlatformInterface||(typeof PlatformInterface=="undefined"?nil:PlatformInterface)}
 return smalltalk.withContext(function($ctx1) { 
-
-		if(aString in window) {
-			return true
-		} else {
-			return false
-		}
-	;
-return self}, function($ctx1) {$ctx1.fill(self,"exists:",{aString:aString},smalltalk.NativeFunction.klass)})},
+var $1;
+$1=_st($PlatformInterface())._existsGlobal_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"exists:",{aString:aString},smalltalk.NativeFunction.klass)})},
 args: ["aString"],
-source: "exists: aString\x0a\x09<\x0a\x09\x09if(aString in window) {\x0a\x09\x09\x09return true\x0a\x09\x09} else {\x0a\x09\x09\x09return false\x0a\x09\x09}\x0a\x09>",
-messageSends: [],
-referencedClasses: []
+source: "exists: aString\x0a\x09^PlatformInterface existsGlobal: aString",
+messageSends: ["existsGlobal:"],
+referencedClasses: ["PlatformInterface"]
 }),
 smalltalk.NativeFunction.klass);
 

+ 247 - 54
js/Kernel-Objects.deploy.js

@@ -1572,7 +1572,114 @@ messageSends: ["new"]}),
 smalltalk.Date.klass);
 
 
-smalltalk.addClass('Environment', smalltalk.Object, [], 'Kernel-Objects');
+smalltalk.addClass('InspectorHandler', smalltalk.Object, [], 'Kernel-Objects');
+
+smalltalk.InspectorHandler.klass.iVarNames = ['inspector'];
+smalltalk.addMethod(
+smalltalk.method({
+selector: "inspect:",
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(self._inspector())._inspect_(anObject);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"inspect:",{anObject:anObject},smalltalk.InspectorHandler.klass)})},
+messageSends: ["inspect:", "inspector"]}),
+smalltalk.InspectorHandler.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "inspector",
+fn: function (){
+var self=this;
+function $Transcript(){return smalltalk.Transcript||(typeof Transcript=="undefined"?nil:Transcript)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@inspector"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@inspector"]=$Transcript();
+$1=self["@inspector"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"inspector",{},smalltalk.InspectorHandler.klass)})},
+messageSends: ["ifNil:"]}),
+smalltalk.InspectorHandler.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "register:",
+fn: function (anInspector){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@inspector"]=anInspector;
+return self}, function($ctx1) {$ctx1.fill(self,"register:",{anInspector:anInspector},smalltalk.InspectorHandler.klass)})},
+messageSends: []}),
+smalltalk.InspectorHandler.klass);
+
+
+smalltalk.addClass('InterfacingObject', smalltalk.Object, [], 'Kernel-Objects');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "ajax:",
+fn: function (anObject){
+var self=this;
+function $PlatformInterface(){return smalltalk.PlatformInterface||(typeof PlatformInterface=="undefined"?nil:PlatformInterface)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st($PlatformInterface())._ajax_(anObject);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"ajax:",{anObject:anObject},smalltalk.InterfacingObject)})},
+messageSends: ["ajax:"]}),
+smalltalk.InterfacingObject);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "alert:",
+fn: function (aString){
+var self=this;
+function $PlatformInterface(){return smalltalk.PlatformInterface||(typeof PlatformInterface=="undefined"?nil:PlatformInterface)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st($PlatformInterface())._alert_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"alert:",{aString:aString},smalltalk.InterfacingObject)})},
+messageSends: ["alert:"]}),
+smalltalk.InterfacingObject);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "confirm:",
+fn: function (aString){
+var self=this;
+function $PlatformInterface(){return smalltalk.PlatformInterface||(typeof PlatformInterface=="undefined"?nil:PlatformInterface)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st($PlatformInterface())._confirm_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"confirm:",{aString:aString},smalltalk.InterfacingObject)})},
+messageSends: ["confirm:"]}),
+smalltalk.InterfacingObject);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "prompt:",
+fn: function (aString){
+var self=this;
+function $PlatformInterface(){return smalltalk.PlatformInterface||(typeof PlatformInterface=="undefined"?nil:PlatformInterface)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st($PlatformInterface())._prompt_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"prompt:",{aString:aString},smalltalk.InterfacingObject)})},
+messageSends: ["prompt:"]}),
+smalltalk.InterfacingObject);
+
+
+
+smalltalk.addClass('Environment', smalltalk.InterfacingObject, [], 'Kernel-Objects');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "addInstVarNamed:to:",
@@ -1789,7 +1896,7 @@ return smalltalk.withContext(function($ctx2) {
 return _st(compiler)._parseExpression_(aString);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_($Error(),(function(ex){
 return smalltalk.withContext(function($ctx2) {
-$1=_st(window)._alert_(_st(ex)._messageText());
+$1=self._alert_(_st(ex)._messageText());
 throw $early=[$1];
 }, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
 $2=_st(compiler)._evaluateExpression_on_(aString,aReceiver);
@@ -2050,54 +2157,6 @@ smalltalk.Environment);
 
 
 
-smalltalk.addClass('InspectorHandler', smalltalk.Object, [], 'Kernel-Objects');
-
-smalltalk.InspectorHandler.klass.iVarNames = ['inspector'];
-smalltalk.addMethod(
-smalltalk.method({
-selector: "inspect:",
-fn: function (anObject){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st(self._inspector())._inspect_(anObject);
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"inspect:",{anObject:anObject},smalltalk.InspectorHandler.klass)})},
-messageSends: ["inspect:", "inspector"]}),
-smalltalk.InspectorHandler.klass);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "inspector",
-fn: function (){
-var self=this;
-function $Transcript(){return smalltalk.Transcript||(typeof Transcript=="undefined"?nil:Transcript)}
-return smalltalk.withContext(function($ctx1) { 
-var $2,$1;
-$2=self["@inspector"];
-if(($receiver = $2) == nil || $receiver == undefined){
-self["@inspector"]=$Transcript();
-$1=self["@inspector"];
-} else {
-$1=$2;
-};
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"inspector",{},smalltalk.InspectorHandler.klass)})},
-messageSends: ["ifNil:"]}),
-smalltalk.InspectorHandler.klass);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "register:",
-fn: function (anInspector){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-self["@inspector"]=anInspector;
-return self}, function($ctx1) {$ctx1.fill(self,"register:",{anInspector:anInspector},smalltalk.InspectorHandler.klass)})},
-messageSends: []}),
-smalltalk.InspectorHandler.klass);
-
-
 smalltalk.addClass('JSObjectProxy', smalltalk.Object, ['jsObject'], 'Kernel-Objects');
 smalltalk.addMethod(
 smalltalk.method({
@@ -3178,9 +3237,10 @@ selector: "load:",
 fn: function (aPackageName){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
+self._deprecatedAPI();
 self._load_prefix_(aPackageName,_st(self._defaultCommitPathJs()).__comma("/"));
 return self}, function($ctx1) {$ctx1.fill(self,"load:",{aPackageName:aPackageName},smalltalk.Package.klass)})},
-messageSends: ["load:prefix:", ",", "defaultCommitPathJs"]}),
+messageSends: ["deprecatedAPI", "load:prefix:", ",", "defaultCommitPathJs"]}),
 smalltalk.Package.klass);
 
 smalltalk.addMethod(
@@ -3189,13 +3249,15 @@ selector: "load:prefix:",
 fn: function (aPackageName,aPrefix){
 var self=this;
 function $Package(){return smalltalk.Package||(typeof Package=="undefined"?nil:Package)}
+function $PlatformInterface(){return smalltalk.PlatformInterface||(typeof PlatformInterface=="undefined"?nil:PlatformInterface)}
 return smalltalk.withContext(function($ctx1) { 
-_st(jQuery)._getScript_onSuccess_(_st(_st(aPrefix).__comma(aPackageName)).__comma(".js"),(function(){
+self._deprecatedAPI();
+_st($PlatformInterface())._ajax_(smalltalk.HashedCollection._from_(["url".__minus_gt(_st(_st(aPrefix).__comma(aPackageName)).__comma(".js")),"dataType".__minus_gt("script"),"success".__minus_gt((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(_st($Package())._named_(aPackageName))._setupClasses();
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))]));
 return self}, function($ctx1) {$ctx1.fill(self,"load:prefix:",{aPackageName:aPackageName,aPrefix:aPrefix},smalltalk.Package.klass)})},
-messageSends: ["getScript:onSuccess:", ",", "setupClasses", "named:"]}),
+messageSends: ["deprecatedAPI", "ajax:", "->", ",", "setupClasses", "named:"]}),
 smalltalk.Package.klass);
 
 smalltalk.addMethod(
@@ -3267,6 +3329,120 @@ messageSends: ["do:", "ifFalse:ifTrue:", "add:", "includes:", "superclass", "col
 smalltalk.Package.klass);
 
 
+smalltalk.addClass('PlatformInterface', smalltalk.Object, [], 'Kernel-Objects');
+
+smalltalk.PlatformInterface.klass.iVarNames = ['worker'];
+smalltalk.addMethod(
+smalltalk.method({
+selector: "ajax:",
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@worker"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=self._error_("ajax: not available");
+} else {
+$1=_st(self["@worker"])._ajax_(anObject);
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"ajax:",{anObject:anObject},smalltalk.PlatformInterface.klass)})},
+messageSends: ["ifNotNil:ifNil:", "ajax:", "error:"]}),
+smalltalk.PlatformInterface.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "alert:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@worker"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=self._error_("alert: not available");
+} else {
+$1=_st(self["@worker"])._alert_(aString);
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"alert:",{aString:aString},smalltalk.PlatformInterface.klass)})},
+messageSends: ["ifNotNil:ifNil:", "alert:", "error:"]}),
+smalltalk.PlatformInterface.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "confirm:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@worker"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=self._error_("confirm: not available");
+} else {
+$1=_st(self["@worker"])._confirm_(aString);
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"confirm:",{aString:aString},smalltalk.PlatformInterface.klass)})},
+messageSends: ["ifNotNil:ifNil:", "confirm:", "error:"]}),
+smalltalk.PlatformInterface.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initialize",
+fn: function (){
+var self=this;
+var candidate;
+function $BrowserInterface(){return smalltalk.BrowserInterface||(typeof BrowserInterface=="undefined"?nil:BrowserInterface)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3;
+smalltalk.PlatformInterface.klass.superclass.fn.prototype._initialize.apply(_st(self), []);
+$1=$BrowserInterface();
+if(($receiver = $1) == nil || $receiver == undefined){
+$1;
+} else {
+candidate=_st($BrowserInterface())._new();
+candidate;
+$2=_st(candidate)._isAvailable();
+if(smalltalk.assert($2)){
+self._setWorker_(candidate);
+$3=self;
+return $3;
+};
+};
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{candidate:candidate},smalltalk.PlatformInterface.klass)})},
+messageSends: ["initialize", "ifNotNil:", "new", "ifTrue:", "setWorker:", "isAvailable"]}),
+smalltalk.PlatformInterface.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "prompt:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@worker"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=self._error_("prompt: not available");
+} else {
+$1=_st(self["@worker"])._prompt_(aString);
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"prompt:",{aString:aString},smalltalk.PlatformInterface.klass)})},
+messageSends: ["ifNotNil:ifNil:", "prompt:", "error:"]}),
+smalltalk.PlatformInterface.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "setWorker:",
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@worker"]=anObject;
+return self}, function($ctx1) {$ctx1.fill(self,"setWorker:",{anObject:anObject},smalltalk.PlatformInterface.klass)})},
+messageSends: []}),
+smalltalk.PlatformInterface.klass);
+
+
 smalltalk.addClass('Point', smalltalk.Object, ['x', 'y'], 'Kernel-Objects');
 smalltalk.addMethod(
 smalltalk.method({
@@ -3498,6 +3674,23 @@ return $1;
 messageSends: ["ifNil:", "new"]}),
 smalltalk.ProgressHandler.klass);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "existsGlobal:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+
+	var f = new Function('aString',
+	'if (/^[0-9]/.test(aString) || !/^[\\w_]+$/.test(aString))\n'+
+	'	return false;\n'+
+	'try { eval(aString); return true; } catch (ex) {}\n'+
+	'return false;');
+	return f(aString);;
+return self}, function($ctx1) {$ctx1.fill(self,"existsGlobal:",{aString:aString},smalltalk.PlatformInterface.klass)})},
+messageSends: []}),
+smalltalk.PlatformInterface.klass);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "initialize",

+ 324 - 74
js/Kernel-Objects.js

@@ -2195,7 +2195,151 @@ referencedClasses: []
 smalltalk.Date.klass);
 
 
-smalltalk.addClass('Environment', smalltalk.Object, [], 'Kernel-Objects');
+smalltalk.addClass('InspectorHandler', smalltalk.Object, [], 'Kernel-Objects');
+smalltalk.InspectorHandler.comment="I am responsible for inspecting object.\x0a\x0aMy class-side `inspector` inst var holds the current inspector I'm delegating object inspection to.\x0a\x0aThe default inspector object is the transcript.";
+
+smalltalk.InspectorHandler.klass.iVarNames = ['inspector'];
+smalltalk.addMethod(
+smalltalk.method({
+selector: "inspect:",
+category: 'registration',
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(self._inspector())._inspect_(anObject);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"inspect:",{anObject:anObject},smalltalk.InspectorHandler.klass)})},
+args: ["anObject"],
+source: "inspect: anObject\x0a\x09^ self inspector inspect: anObject",
+messageSends: ["inspect:", "inspector"],
+referencedClasses: []
+}),
+smalltalk.InspectorHandler.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "inspector",
+category: 'accessing',
+fn: function (){
+var self=this;
+function $Transcript(){return smalltalk.Transcript||(typeof Transcript=="undefined"?nil:Transcript)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@inspector"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@inspector"]=$Transcript();
+$1=self["@inspector"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"inspector",{},smalltalk.InspectorHandler.klass)})},
+args: [],
+source: "inspector\x0a\x09^ inspector ifNil: [ inspector := Transcript ]",
+messageSends: ["ifNil:"],
+referencedClasses: ["Transcript"]
+}),
+smalltalk.InspectorHandler.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "register:",
+category: 'registration',
+fn: function (anInspector){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@inspector"]=anInspector;
+return self}, function($ctx1) {$ctx1.fill(self,"register:",{anInspector:anInspector},smalltalk.InspectorHandler.klass)})},
+args: ["anInspector"],
+source: "register: anInspector\x0a\x09inspector := anInspector",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.InspectorHandler.klass);
+
+
+smalltalk.addClass('InterfacingObject', smalltalk.Object, [], 'Kernel-Objects');
+smalltalk.InterfacingObject.comment="I am superclass of all object that interface with user or environment. `Widget` and a few other classes are subclasses of me. I delegate all of the above APIs to `PlatformInterface`.\x0a\x0a## API\x0a\x0a    self alert: 'Hey, there is a problem'.\x0a    self confirm: 'Affirmative?'.\x0a    self prompt: 'Your name:'.\x0a\x0a    self ajax: #{\x0a        'url' -> '/patch.js'. 'type' -> 'GET'. dataType->'script'\x0a    }.\x0a";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "ajax:",
+category: 'actions',
+fn: function (anObject){
+var self=this;
+function $PlatformInterface(){return smalltalk.PlatformInterface||(typeof PlatformInterface=="undefined"?nil:PlatformInterface)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st($PlatformInterface())._ajax_(anObject);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"ajax:",{anObject:anObject},smalltalk.InterfacingObject)})},
+args: ["anObject"],
+source: "ajax: anObject\x0a\x09^PlatformInterface ajax: anObject",
+messageSends: ["ajax:"],
+referencedClasses: ["PlatformInterface"]
+}),
+smalltalk.InterfacingObject);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "alert:",
+category: 'actions',
+fn: function (aString){
+var self=this;
+function $PlatformInterface(){return smalltalk.PlatformInterface||(typeof PlatformInterface=="undefined"?nil:PlatformInterface)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st($PlatformInterface())._alert_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"alert:",{aString:aString},smalltalk.InterfacingObject)})},
+args: ["aString"],
+source: "alert: aString\x0a\x09^PlatformInterface alert: aString",
+messageSends: ["alert:"],
+referencedClasses: ["PlatformInterface"]
+}),
+smalltalk.InterfacingObject);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "confirm:",
+category: 'actions',
+fn: function (aString){
+var self=this;
+function $PlatformInterface(){return smalltalk.PlatformInterface||(typeof PlatformInterface=="undefined"?nil:PlatformInterface)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st($PlatformInterface())._confirm_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"confirm:",{aString:aString},smalltalk.InterfacingObject)})},
+args: ["aString"],
+source: "confirm: aString\x0a\x09^PlatformInterface confirm: aString",
+messageSends: ["confirm:"],
+referencedClasses: ["PlatformInterface"]
+}),
+smalltalk.InterfacingObject);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "prompt:",
+category: 'actions',
+fn: function (aString){
+var self=this;
+function $PlatformInterface(){return smalltalk.PlatformInterface||(typeof PlatformInterface=="undefined"?nil:PlatformInterface)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st($PlatformInterface())._prompt_(aString);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"prompt:",{aString:aString},smalltalk.InterfacingObject)})},
+args: ["aString"],
+source: "prompt: aString\x0a\x09^PlatformInterface prompt: aString",
+messageSends: ["prompt:"],
+referencedClasses: ["PlatformInterface"]
+}),
+smalltalk.InterfacingObject);
+
+
+
+smalltalk.addClass('Environment', smalltalk.InterfacingObject, [], 'Kernel-Objects');
 smalltalk.Environment.comment="I provide an unified entry point to manipulate Amber packages, classes and methods.\x0a\x0aTypical use cases include IDEs, remote access and restricting browsing.";
 smalltalk.addMethod(
 smalltalk.method({
@@ -2479,7 +2623,7 @@ return smalltalk.withContext(function($ctx2) {
 return _st(compiler)._parseExpression_(aString);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_($Error(),(function(ex){
 return smalltalk.withContext(function($ctx2) {
-$1=_st(window)._alert_(_st(ex)._messageText());
+$1=self._alert_(_st(ex)._messageText());
 throw $early=[$1];
 }, function($ctx2) {$ctx2.fillBlock({ex:ex},$ctx1)})}));
 $2=_st(compiler)._evaluateExpression_on_(aString,aReceiver);
@@ -2488,7 +2632,7 @@ return $2;
 catch(e) {if(e===$early)return e[0]; throw e}
 }, function($ctx1) {$ctx1.fill(self,"eval:on:",{aString:aString,aReceiver:aReceiver,compiler:compiler},smalltalk.Environment)})},
 args: ["aString", "aReceiver"],
-source: "eval: aString on: aReceiver\x0a\x09| compiler |\x0a\x09compiler := Compiler new.\x0a\x09[ compiler parseExpression: aString ] on: Error do: [ :ex |\x0a\x09\x09^ window alert: ex messageText ].\x0a\x09^ compiler evaluateExpression: aString on: aReceiver",
+source: "eval: aString on: aReceiver\x0a\x09| compiler |\x0a\x09compiler := Compiler new.\x0a\x09[ compiler parseExpression: aString ] on: Error do: [ :ex |\x0a\x09\x09^ self alert: ex messageText ].\x0a\x09^ compiler evaluateExpression: aString on: aReceiver",
 messageSends: ["new", "on:do:", "alert:", "messageText", "parseExpression:", "evaluateExpression:on:"],
 referencedClasses: ["Compiler", "Error"]
 }),
@@ -2824,70 +2968,6 @@ smalltalk.Environment);
 
 
 
-smalltalk.addClass('InspectorHandler', smalltalk.Object, [], 'Kernel-Objects');
-smalltalk.InspectorHandler.comment="I am responsible for inspecting object.\x0a\x0aMy class-side `inspector` inst var holds the current inspector I'm delegating object inspection to.\x0a\x0aThe default inspector object is the transcript.";
-
-smalltalk.InspectorHandler.klass.iVarNames = ['inspector'];
-smalltalk.addMethod(
-smalltalk.method({
-selector: "inspect:",
-category: 'registration',
-fn: function (anObject){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st(self._inspector())._inspect_(anObject);
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"inspect:",{anObject:anObject},smalltalk.InspectorHandler.klass)})},
-args: ["anObject"],
-source: "inspect: anObject\x0a\x09^ self inspector inspect: anObject",
-messageSends: ["inspect:", "inspector"],
-referencedClasses: []
-}),
-smalltalk.InspectorHandler.klass);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "inspector",
-category: 'accessing',
-fn: function (){
-var self=this;
-function $Transcript(){return smalltalk.Transcript||(typeof Transcript=="undefined"?nil:Transcript)}
-return smalltalk.withContext(function($ctx1) { 
-var $2,$1;
-$2=self["@inspector"];
-if(($receiver = $2) == nil || $receiver == undefined){
-self["@inspector"]=$Transcript();
-$1=self["@inspector"];
-} else {
-$1=$2;
-};
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"inspector",{},smalltalk.InspectorHandler.klass)})},
-args: [],
-source: "inspector\x0a\x09^ inspector ifNil: [ inspector := Transcript ]",
-messageSends: ["ifNil:"],
-referencedClasses: ["Transcript"]
-}),
-smalltalk.InspectorHandler.klass);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "register:",
-category: 'registration',
-fn: function (anInspector){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-self["@inspector"]=anInspector;
-return self}, function($ctx1) {$ctx1.fill(self,"register:",{anInspector:anInspector},smalltalk.InspectorHandler.klass)})},
-args: ["anInspector"],
-source: "register: anInspector\x0a\x09inspector := anInspector",
-messageSends: [],
-referencedClasses: []
-}),
-smalltalk.InspectorHandler.klass);
-
-
 smalltalk.addClass('JSObjectProxy', smalltalk.Object, ['jsObject'], 'Kernel-Objects');
 smalltalk.JSObjectProxy.comment="I handle sending messages to JavaScript objects, making  JavaScript object accessing from Amber fully transparent.\x0aMy instances make intensive use of `#doesNotUnderstand:`.\x0a\x0aMy instances are automatically created by Amber whenever a message is sent to a JavaScript object.\x0a\x0a## Usage examples\x0a\x0aJSObjectProxy objects are instanciated by Amber when a Smalltalk message is sent to a JavaScript object.\x0a\x0a\x09window alert: 'hello world'.\x0a\x09window inspect.\x0a\x09(window jQuery: 'body') append: 'hello world'\x0a\x0aAmber messages sends are converted to JavaScript function calls or object property access _(in this order)_. If n one of them match, a `MessageNotUnderstood` error will be thrown.\x0a\x0a## Message conversion rules\x0a\x0a- `someUser name` becomes `someUser.name`\x0a- `someUser name: 'John'` becomes `someUser name = \x22John\x22`\x0a- `console log: 'hello world'` becomes `console.log('hello world')`\x0a- `(window jQuery: 'foo') css: 'background' color: 'red'` becomes `window.jQuery('foo').css('background', 'red')`\x0a\x0a__Note:__ For keyword-based messages, only the first keyword is kept: `window foo: 1 bar: 2` is equivalent to `window foo: 1 baz: 2`.";
 smalltalk.addMethod(
@@ -4350,11 +4430,12 @@ category: 'loading-storing',
 fn: function (aPackageName){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
+self._deprecatedAPI();
 self._load_prefix_(aPackageName,_st(self._defaultCommitPathJs()).__comma("/"));
 return self}, function($ctx1) {$ctx1.fill(self,"load:",{aPackageName:aPackageName},smalltalk.Package.klass)})},
 args: ["aPackageName"],
-source: "load: aPackageName\x0a\x09self load: aPackageName prefix: self defaultCommitPathJs, '/'",
-messageSends: ["load:prefix:", ",", "defaultCommitPathJs"],
+source: "load: aPackageName\x0a\x09self deprecatedAPI.\x0a\x09self load: aPackageName prefix: self defaultCommitPathJs, '/'",
+messageSends: ["deprecatedAPI", "load:prefix:", ",", "defaultCommitPathJs"],
 referencedClasses: []
 }),
 smalltalk.Package.klass);
@@ -4366,16 +4447,18 @@ category: 'loading-storing',
 fn: function (aPackageName,aPrefix){
 var self=this;
 function $Package(){return smalltalk.Package||(typeof Package=="undefined"?nil:Package)}
+function $PlatformInterface(){return smalltalk.PlatformInterface||(typeof PlatformInterface=="undefined"?nil:PlatformInterface)}
 return smalltalk.withContext(function($ctx1) { 
-_st(jQuery)._getScript_onSuccess_(_st(_st(aPrefix).__comma(aPackageName)).__comma(".js"),(function(){
+self._deprecatedAPI();
+_st($PlatformInterface())._ajax_(smalltalk.HashedCollection._from_(["url".__minus_gt(_st(_st(aPrefix).__comma(aPackageName)).__comma(".js")),"dataType".__minus_gt("script"),"success".__minus_gt((function(){
 return smalltalk.withContext(function($ctx2) {
 return _st(_st($Package())._named_(aPackageName))._setupClasses();
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))]));
 return self}, function($ctx1) {$ctx1.fill(self,"load:prefix:",{aPackageName:aPackageName,aPrefix:aPrefix},smalltalk.Package.klass)})},
 args: ["aPackageName", "aPrefix"],
-source: "load: aPackageName prefix: aPrefix\x0a\x09jQuery\x0a\x09\x09getScript: (aPrefix , aPackageName , '.js')\x0a\x09\x09onSuccess: [\x0a\x09\x09\x09(Package named: aPackageName) setupClasses ]",
-messageSends: ["getScript:onSuccess:", ",", "setupClasses", "named:"],
-referencedClasses: ["Package"]
+source: "load: aPackageName prefix: aPrefix\x0a\x09self deprecatedAPI.\x0a\x09PlatformInterface ajax: #{\x0a\x09\x09'url' -> (aPrefix , aPackageName , '.js').\x0a\x09\x09'dataType' -> 'script'.\x0a\x09\x09'success' -> [\x0a\x09\x09\x09(Package named: aPackageName) setupClasses ]\x0a\x09}",
+messageSends: ["deprecatedAPI", "ajax:", "->", ",", "setupClasses", "named:"],
+referencedClasses: ["Package", "PlatformInterface"]
 }),
 smalltalk.Package.klass);
 
@@ -4463,6 +4546,151 @@ referencedClasses: ["ClassSorterNode", "Array"]
 smalltalk.Package.klass);
 
 
+smalltalk.addClass('PlatformInterface', smalltalk.Object, [], 'Kernel-Objects');
+smalltalk.PlatformInterface.comment="I am single entry point to UI and environment interface.\x0aMy `initialize` tries several options (for now, browser environment only) to set myself up.\x0a\x0a## API\x0a\x0a    PlatformInterface alert: 'Hey, there is a problem'.\x0a    PlatformInterface confirm: 'Affirmative?'.\x0a    PlatformInterface prompt: 'Your name:'.\x0a\x0a    PlatformInterface ajax: #{\x0a        'url' -> '/patch.js'. 'type' -> 'GET'. dataType->'script'\x0a    }.\x0a";
+
+smalltalk.PlatformInterface.klass.iVarNames = ['worker'];
+smalltalk.addMethod(
+smalltalk.method({
+selector: "ajax:",
+category: 'actions',
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@worker"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=self._error_("ajax: not available");
+} else {
+$1=_st(self["@worker"])._ajax_(anObject);
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"ajax:",{anObject:anObject},smalltalk.PlatformInterface.klass)})},
+args: ["anObject"],
+source: "ajax: anObject\x0a\x09^worker\x0a\x09\x09ifNotNil: [ worker ajax: anObject ]\x0a\x09\x09ifNil: [ self error: 'ajax: not available' ]",
+messageSends: ["ifNotNil:ifNil:", "ajax:", "error:"],
+referencedClasses: []
+}),
+smalltalk.PlatformInterface.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "alert:",
+category: 'actions',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@worker"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=self._error_("alert: not available");
+} else {
+$1=_st(self["@worker"])._alert_(aString);
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"alert:",{aString:aString},smalltalk.PlatformInterface.klass)})},
+args: ["aString"],
+source: "alert: aString\x0a\x09^worker\x0a\x09\x09ifNotNil: [ worker alert: aString ]\x0a\x09\x09ifNil: [ self error: 'alert: not available' ]",
+messageSends: ["ifNotNil:ifNil:", "alert:", "error:"],
+referencedClasses: []
+}),
+smalltalk.PlatformInterface.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "confirm:",
+category: 'actions',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@worker"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=self._error_("confirm: not available");
+} else {
+$1=_st(self["@worker"])._confirm_(aString);
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"confirm:",{aString:aString},smalltalk.PlatformInterface.klass)})},
+args: ["aString"],
+source: "confirm: aString\x0a\x09^worker\x0a\x09\x09ifNotNil: [ worker confirm: aString ]\x0a\x09\x09ifNil: [ self error: 'confirm: not available' ]",
+messageSends: ["ifNotNil:ifNil:", "confirm:", "error:"],
+referencedClasses: []
+}),
+smalltalk.PlatformInterface.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initialize",
+category: 'initialization',
+fn: function (){
+var self=this;
+var candidate;
+function $BrowserInterface(){return smalltalk.BrowserInterface||(typeof BrowserInterface=="undefined"?nil:BrowserInterface)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2,$3;
+smalltalk.PlatformInterface.klass.superclass.fn.prototype._initialize.apply(_st(self), []);
+$1=$BrowserInterface();
+if(($receiver = $1) == nil || $receiver == undefined){
+$1;
+} else {
+candidate=_st($BrowserInterface())._new();
+candidate;
+$2=_st(candidate)._isAvailable();
+if(smalltalk.assert($2)){
+self._setWorker_(candidate);
+$3=self;
+return $3;
+};
+};
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{candidate:candidate},smalltalk.PlatformInterface.klass)})},
+args: [],
+source: "initialize\x0a\x09| candidate |\x0a\x09\x0a\x09super initialize.\x0a\x09\x0a\x09BrowserInterface ifNotNil: [\x0a\x09\x09candidate := BrowserInterface new.\x0a\x09\x09candidate isAvailable ifTrue: [ self setWorker: candidate. ^self ]\x0a\x09]",
+messageSends: ["initialize", "ifNotNil:", "new", "ifTrue:", "setWorker:", "isAvailable"],
+referencedClasses: ["BrowserInterface"]
+}),
+smalltalk.PlatformInterface.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "prompt:",
+category: 'actions',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@worker"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=self._error_("prompt: not available");
+} else {
+$1=_st(self["@worker"])._prompt_(aString);
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"prompt:",{aString:aString},smalltalk.PlatformInterface.klass)})},
+args: ["aString"],
+source: "prompt: aString\x0a\x09^worker\x0a\x09\x09ifNotNil: [ worker prompt: aString ]\x0a\x09\x09ifNil: [ self error: 'prompt: not available' ]",
+messageSends: ["ifNotNil:ifNil:", "prompt:", "error:"],
+referencedClasses: []
+}),
+smalltalk.PlatformInterface.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "setWorker:",
+category: 'accessing',
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@worker"]=anObject;
+return self}, function($ctx1) {$ctx1.fill(self,"setWorker:",{anObject:anObject},smalltalk.PlatformInterface.klass)})},
+args: ["anObject"],
+source: "setWorker: anObject\x0a\x09worker := anObject",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.PlatformInterface.klass);
+
+
 smalltalk.addClass('Point', smalltalk.Object, ['x', 'y'], 'Kernel-Objects');
 smalltalk.Point.comment="I represent an x-y pair of numbers usually designating a geometric coordinate.\x0a\x0a## API\x0a\x0aInstances are traditionally created using the binary `#@` message to a number:\x0a\x0a\x09100@120\x0a\x0aPoints can then be arithmetically manipulated:\x0a\x0a\x09100@100 + (10@10)\x0a\x0a...or for example:\x0a\x0a\x09(100@100) * 2\x0a\x0a**NOTE:** Creating a point with a negative y-value will need a space after `@` in order to avoid a parsing error:\x0a\x0a\x09100@ -100 \x22but 100@-100 would not parse\x22";
 smalltalk.addMethod(
@@ -4776,6 +5004,28 @@ referencedClasses: []
 }),
 smalltalk.ProgressHandler.klass);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "existsGlobal:",
+category: 'actions',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+
+	var f = new Function('aString',
+	'if (/^[0-9]/.test(aString) || !/^[\\w_]+$/.test(aString))\n'+
+	'	return false;\n'+
+	'try { eval(aString); return true; } catch (ex) {}\n'+
+	'return false;');
+	return f(aString);;
+return self}, function($ctx1) {$ctx1.fill(self,"existsGlobal:",{aString:aString},smalltalk.PlatformInterface.klass)})},
+args: ["aString"],
+source: "existsGlobal: aString\x0a<\x0a\x09var f = new Function('aString',\x0a\x09'if (/^[0-9]/.test(aString) || !/^[\x5c\x5cw_]+$/.test(aString))\x5cn'+\x0a\x09'\x09return false;\x5cn'+\x0a\x09'try { eval(aString); return true; } catch (ex) {}\x5cn'+\x0a\x09'return false;');\x0a\x09return f(aString);\x0a>",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.PlatformInterface.klass);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "initialize",

+ 337 - 0
js/Kernel-Tests.deploy.js

@@ -2477,6 +2477,343 @@ smalltalk.MessageSendTest);
 
 
 
+smalltalk.addClass('MethodInheritanceTest', smalltalk.TestCase, ['receiverTop', 'receiverMiddle', 'receiverBottom', 'method', 'performBlock'], 'Kernel-Tests');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "codeGeneratorClass",
+fn: function (){
+var self=this;
+function $CodeGenerator(){return smalltalk.CodeGenerator||(typeof CodeGenerator=="undefined"?nil:CodeGenerator)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=$CodeGenerator();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"codeGeneratorClass",{},smalltalk.MethodInheritanceTest)})},
+messageSends: []}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "compiler",
+fn: function (){
+var self=this;
+function $Compiler(){return smalltalk.Compiler||(typeof Compiler=="undefined"?nil:Compiler)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$1;
+$2=_st($Compiler())._new();
+_st($2)._codeGeneratorClass_(self._codeGeneratorClass());
+$3=_st($2)._yourself();
+$1=$3;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"compiler",{},smalltalk.MethodInheritanceTest)})},
+messageSends: ["codeGeneratorClass:", "codeGeneratorClass", "new", "yourself"]}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "deinstallBottom",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._targetClassBottom())._removeCompiledMethod_(self["@method"]);
+return self}, function($ctx1) {$ctx1.fill(self,"deinstallBottom",{},smalltalk.MethodInheritanceTest)})},
+messageSends: ["removeCompiledMethod:", "targetClassBottom"]}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "deinstallMiddle",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._targetClassMiddle())._removeCompiledMethod_(self["@method"]);
+return self}, function($ctx1) {$ctx1.fill(self,"deinstallMiddle",{},smalltalk.MethodInheritanceTest)})},
+messageSends: ["removeCompiledMethod:", "targetClassMiddle"]}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "deinstallTop",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._targetClassTop())._removeCompiledMethod_(self["@method"]);
+return self}, function($ctx1) {$ctx1.fill(self,"deinstallTop",{},smalltalk.MethodInheritanceTest)})},
+messageSends: ["removeCompiledMethod:", "targetClassTop"]}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "installBottom:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@method"]=_st(self._compiler())._install_forClass_category_(aString,self._targetClassBottom(),"tests");
+return self}, function($ctx1) {$ctx1.fill(self,"installBottom:",{aString:aString},smalltalk.MethodInheritanceTest)})},
+messageSends: ["install:forClass:category:", "targetClassBottom", "compiler"]}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "installMiddle:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@method"]=_st(self._compiler())._install_forClass_category_(aString,self._targetClassMiddle(),"tests");
+return self}, function($ctx1) {$ctx1.fill(self,"installMiddle:",{aString:aString},smalltalk.MethodInheritanceTest)})},
+messageSends: ["install:forClass:category:", "targetClassMiddle", "compiler"]}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "installTop:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@method"]=_st(self._compiler())._install_forClass_category_(aString,self._targetClassTop(),"tests");
+return self}, function($ctx1) {$ctx1.fill(self,"installTop:",{aString:aString},smalltalk.MethodInheritanceTest)})},
+messageSends: ["install:forClass:category:", "targetClassTop", "compiler"]}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "setUp",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@receiverTop"]=_st(self._targetClassTop())._new();
+self["@receiverMiddle"]=_st(self._targetClassMiddle())._new();
+self["@receiverBottom"]=_st(self._targetClassBottom())._new();
+self["@method"]=nil;
+self["@performBlock"]=(function(){
+return smalltalk.withContext(function($ctx2) {
+return self._error_("performBlock not initialized");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+return self}, function($ctx1) {$ctx1.fill(self,"setUp",{},smalltalk.MethodInheritanceTest)})},
+messageSends: ["new", "targetClassTop", "targetClassMiddle", "targetClassBottom", "error:"]}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "shouldMNU",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self._shouldMNUTop();
+self._shouldMNUMiddle();
+self._shouldMNUBottom();
+return self}, function($ctx1) {$ctx1.fill(self,"shouldMNU",{},smalltalk.MethodInheritanceTest)})},
+messageSends: ["shouldMNUTop", "shouldMNUMiddle", "shouldMNUBottom"]}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "shouldMNUBottom",
+fn: function (){
+var self=this;
+function $MessageNotUnderstood(){return smalltalk.MessageNotUnderstood||(typeof MessageNotUnderstood=="undefined"?nil:MessageNotUnderstood)}
+return smalltalk.withContext(function($ctx1) { 
+self._should_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(self["@performBlock"])._value_(self["@receiverBottom"]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),$MessageNotUnderstood());
+return self}, function($ctx1) {$ctx1.fill(self,"shouldMNUBottom",{},smalltalk.MethodInheritanceTest)})},
+messageSends: ["should:raise:", "value:"]}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "shouldMNUMiddle",
+fn: function (){
+var self=this;
+function $MessageNotUnderstood(){return smalltalk.MessageNotUnderstood||(typeof MessageNotUnderstood=="undefined"?nil:MessageNotUnderstood)}
+return smalltalk.withContext(function($ctx1) { 
+self._should_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(self["@performBlock"])._value_(self["@receiverMiddle"]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),$MessageNotUnderstood());
+return self}, function($ctx1) {$ctx1.fill(self,"shouldMNUMiddle",{},smalltalk.MethodInheritanceTest)})},
+messageSends: ["should:raise:", "value:"]}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "shouldMNUTop",
+fn: function (){
+var self=this;
+function $MessageNotUnderstood(){return smalltalk.MessageNotUnderstood||(typeof MessageNotUnderstood=="undefined"?nil:MessageNotUnderstood)}
+return smalltalk.withContext(function($ctx1) { 
+self._should_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(self["@performBlock"])._value_(self["@receiverTop"]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),$MessageNotUnderstood());
+return self}, function($ctx1) {$ctx1.fill(self,"shouldMNUTop",{},smalltalk.MethodInheritanceTest)})},
+messageSends: ["should:raise:", "value:"]}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "shouldReturn:",
+fn: function (anObject){
+var self=this;
+var result;
+return smalltalk.withContext(function($ctx1) { 
+result=_st(self["@performBlock"])._value_(self["@receiverTop"]);
+self._assert_equals_(["top",anObject],["top",result]);
+result=_st(self["@performBlock"])._value_(self["@receiverMiddle"]);
+self._assert_equals_(["middle",anObject],["middle",result]);
+result=_st(self["@performBlock"])._value_(self["@receiverBottom"]);
+self._assert_equals_(["bottom",anObject],["bottom",result]);
+return self}, function($ctx1) {$ctx1.fill(self,"shouldReturn:",{anObject:anObject,result:result},smalltalk.MethodInheritanceTest)})},
+messageSends: ["value:", "assert:equals:"]}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "shouldReturn:and:and:",
+fn: function (anObject,anObject2,anObject3){
+var self=this;
+var result;
+return smalltalk.withContext(function($ctx1) { 
+result=_st(self["@performBlock"])._value_(self["@receiverTop"]);
+self._assert_equals_(["top",anObject],["top",result]);
+result=_st(self["@performBlock"])._value_(self["@receiverMiddle"]);
+self._assert_equals_(["middle",anObject2],["middle",result]);
+result=_st(self["@performBlock"])._value_(self["@receiverBottom"]);
+self._assert_equals_(["bottom",anObject3],["bottom",result]);
+return self}, function($ctx1) {$ctx1.fill(self,"shouldReturn:and:and:",{anObject:anObject,anObject2:anObject2,anObject3:anObject3,result:result},smalltalk.MethodInheritanceTest)})},
+messageSends: ["value:", "assert:equals:"]}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "targetClassBottom",
+fn: function (){
+var self=this;
+function $JavaScriptException(){return smalltalk.JavaScriptException||(typeof JavaScriptException=="undefined"?nil:JavaScriptException)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=$JavaScriptException();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"targetClassBottom",{},smalltalk.MethodInheritanceTest)})},
+messageSends: []}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "targetClassMiddle",
+fn: function (){
+var self=this;
+function $Error(){return smalltalk.Error||(typeof Error=="undefined"?nil:Error)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=$Error();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"targetClassMiddle",{},smalltalk.MethodInheritanceTest)})},
+messageSends: []}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "targetClassTop",
+fn: function (){
+var self=this;
+function $Object(){return smalltalk.Object||(typeof Object=="undefined"?nil:Object)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=$Object();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"targetClassTop",{},smalltalk.MethodInheritanceTest)})},
+messageSends: []}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "tearDown",
+fn: function (){
+var self=this;
+function $Error(){return smalltalk.Error||(typeof Error=="undefined"?nil:Error)}
+return smalltalk.withContext(function($ctx1) { 
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
+return self._deinstallTop();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_($Error(),(function(){
+return smalltalk.withContext(function($ctx2) {
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
+return self._deinstallMiddle();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_($Error(),(function(){
+return smalltalk.withContext(function($ctx2) {
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
+return self._deinstallBottom();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_($Error(),(function(){
+return smalltalk.withContext(function($ctx2) {
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"tearDown",{},smalltalk.MethodInheritanceTest)})},
+messageSends: ["on:do:", "deinstallTop", "deinstallMiddle", "deinstallBottom"]}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testMNU11",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@performBlock"]=(function(x){
+return smalltalk.withContext(function($ctx2) {
+return _st(x)._foo();
+}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1)})});
+self._shouldMNU();
+self._installTop_("foo ^ false");
+self._installTop_("foo ^ true");
+self._deinstallTop();
+self._shouldMNU();
+return self}, function($ctx1) {$ctx1.fill(self,"testMNU11",{},smalltalk.MethodInheritanceTest)})},
+messageSends: ["foo", "shouldMNU", "installTop:", "deinstallTop"]}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testMNU22",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@performBlock"]=(function(x){
+return smalltalk.withContext(function($ctx2) {
+return _st(x)._foo();
+}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1)})});
+self._shouldMNU();
+self._installMiddle_("foo ^ false");
+self._installMiddle_("foo ^ true");
+self._deinstallMiddle();
+self._shouldMNU();
+return self}, function($ctx1) {$ctx1.fill(self,"testMNU22",{},smalltalk.MethodInheritanceTest)})},
+messageSends: ["foo", "shouldMNU", "installMiddle:", "deinstallMiddle"]}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testReturns1",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@performBlock"]=(function(x){
+return smalltalk.withContext(function($ctx2) {
+return _st(x)._foo();
+}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1)})});
+self._installTop_("foo ^ false");
+self._shouldReturn_(false);
+self._installTop_("foo ^ true");
+self._shouldReturn_(true);
+return self}, function($ctx1) {$ctx1.fill(self,"testReturns1",{},smalltalk.MethodInheritanceTest)})},
+messageSends: ["foo", "installTop:", "shouldReturn:"]}),
+smalltalk.MethodInheritanceTest);
+
+
+
 smalltalk.addClass('NumberTest', smalltalk.TestCase, [], 'Kernel-Tests');
 smalltalk.addMethod(
 smalltalk.method({

+ 447 - 0
js/Kernel-Tests.js

@@ -3132,6 +3132,453 @@ smalltalk.MessageSendTest);
 
 
 
+smalltalk.addClass('MethodInheritanceTest', smalltalk.TestCase, ['receiverTop', 'receiverMiddle', 'receiverBottom', 'method', 'performBlock'], 'Kernel-Tests');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "codeGeneratorClass",
+category: 'accessing',
+fn: function (){
+var self=this;
+function $CodeGenerator(){return smalltalk.CodeGenerator||(typeof CodeGenerator=="undefined"?nil:CodeGenerator)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=$CodeGenerator();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"codeGeneratorClass",{},smalltalk.MethodInheritanceTest)})},
+args: [],
+source: "codeGeneratorClass\x0a\x09^ CodeGenerator",
+messageSends: [],
+referencedClasses: ["CodeGenerator"]
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "compiler",
+category: 'factory',
+fn: function (){
+var self=this;
+function $Compiler(){return smalltalk.Compiler||(typeof Compiler=="undefined"?nil:Compiler)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$1;
+$2=_st($Compiler())._new();
+_st($2)._codeGeneratorClass_(self._codeGeneratorClass());
+$3=_st($2)._yourself();
+$1=$3;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"compiler",{},smalltalk.MethodInheritanceTest)})},
+args: [],
+source: "compiler\x0a\x09^ Compiler new\x0a\x09\x09codeGeneratorClass: self codeGeneratorClass;\x0a\x09\x09yourself",
+messageSends: ["codeGeneratorClass:", "codeGeneratorClass", "new", "yourself"],
+referencedClasses: ["Compiler"]
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "deinstallBottom",
+category: 'testing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._targetClassBottom())._removeCompiledMethod_(self["@method"]);
+return self}, function($ctx1) {$ctx1.fill(self,"deinstallBottom",{},smalltalk.MethodInheritanceTest)})},
+args: [],
+source: "deinstallBottom\x0a\x09self targetClassBottom removeCompiledMethod: method",
+messageSends: ["removeCompiledMethod:", "targetClassBottom"],
+referencedClasses: []
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "deinstallMiddle",
+category: 'testing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._targetClassMiddle())._removeCompiledMethod_(self["@method"]);
+return self}, function($ctx1) {$ctx1.fill(self,"deinstallMiddle",{},smalltalk.MethodInheritanceTest)})},
+args: [],
+source: "deinstallMiddle\x0a\x09self targetClassMiddle removeCompiledMethod: method",
+messageSends: ["removeCompiledMethod:", "targetClassMiddle"],
+referencedClasses: []
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "deinstallTop",
+category: 'testing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self._targetClassTop())._removeCompiledMethod_(self["@method"]);
+return self}, function($ctx1) {$ctx1.fill(self,"deinstallTop",{},smalltalk.MethodInheritanceTest)})},
+args: [],
+source: "deinstallTop\x0a\x09self targetClassTop removeCompiledMethod: method",
+messageSends: ["removeCompiledMethod:", "targetClassTop"],
+referencedClasses: []
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "installBottom:",
+category: 'testing',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@method"]=_st(self._compiler())._install_forClass_category_(aString,self._targetClassBottom(),"tests");
+return self}, function($ctx1) {$ctx1.fill(self,"installBottom:",{aString:aString},smalltalk.MethodInheritanceTest)})},
+args: ["aString"],
+source: "installBottom: aString\x0a\x09method := self compiler install: aString forClass: self targetClassBottom category: 'tests'",
+messageSends: ["install:forClass:category:", "targetClassBottom", "compiler"],
+referencedClasses: []
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "installMiddle:",
+category: 'testing',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@method"]=_st(self._compiler())._install_forClass_category_(aString,self._targetClassMiddle(),"tests");
+return self}, function($ctx1) {$ctx1.fill(self,"installMiddle:",{aString:aString},smalltalk.MethodInheritanceTest)})},
+args: ["aString"],
+source: "installMiddle: aString\x0a\x09method := self compiler install: aString forClass: self targetClassMiddle category: 'tests'",
+messageSends: ["install:forClass:category:", "targetClassMiddle", "compiler"],
+referencedClasses: []
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "installTop:",
+category: 'testing',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@method"]=_st(self._compiler())._install_forClass_category_(aString,self._targetClassTop(),"tests");
+return self}, function($ctx1) {$ctx1.fill(self,"installTop:",{aString:aString},smalltalk.MethodInheritanceTest)})},
+args: ["aString"],
+source: "installTop: aString\x0a\x09method := self compiler install: aString forClass: self targetClassTop category: 'tests'",
+messageSends: ["install:forClass:category:", "targetClassTop", "compiler"],
+referencedClasses: []
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "setUp",
+category: 'initialization',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@receiverTop"]=_st(self._targetClassTop())._new();
+self["@receiverMiddle"]=_st(self._targetClassMiddle())._new();
+self["@receiverBottom"]=_st(self._targetClassBottom())._new();
+self["@method"]=nil;
+self["@performBlock"]=(function(){
+return smalltalk.withContext(function($ctx2) {
+return self._error_("performBlock not initialized");
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+return self}, function($ctx1) {$ctx1.fill(self,"setUp",{},smalltalk.MethodInheritanceTest)})},
+args: [],
+source: "setUp\x0a\x09receiverTop := self targetClassTop new.\x0a\x09receiverMiddle := self targetClassMiddle new.\x0a\x09receiverBottom := self targetClassBottom new.\x0a\x09method := nil.\x0a\x09performBlock := [ self error: 'performBlock not initialized' ]",
+messageSends: ["new", "targetClassTop", "targetClassMiddle", "targetClassBottom", "error:"],
+referencedClasses: []
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "shouldMNU",
+category: 'testing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self._shouldMNUTop();
+self._shouldMNUMiddle();
+self._shouldMNUBottom();
+return self}, function($ctx1) {$ctx1.fill(self,"shouldMNU",{},smalltalk.MethodInheritanceTest)})},
+args: [],
+source: "shouldMNU\x0a\x09self shouldMNUTop.\x0a\x09self shouldMNUMiddle.\x0a\x09self shouldMNUBottom",
+messageSends: ["shouldMNUTop", "shouldMNUMiddle", "shouldMNUBottom"],
+referencedClasses: []
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "shouldMNUBottom",
+category: 'testing',
+fn: function (){
+var self=this;
+function $MessageNotUnderstood(){return smalltalk.MessageNotUnderstood||(typeof MessageNotUnderstood=="undefined"?nil:MessageNotUnderstood)}
+return smalltalk.withContext(function($ctx1) { 
+self._should_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(self["@performBlock"])._value_(self["@receiverBottom"]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),$MessageNotUnderstood());
+return self}, function($ctx1) {$ctx1.fill(self,"shouldMNUBottom",{},smalltalk.MethodInheritanceTest)})},
+args: [],
+source: "shouldMNUBottom\x0a\x09self should: [ performBlock value: receiverBottom ] raise: MessageNotUnderstood",
+messageSends: ["should:raise:", "value:"],
+referencedClasses: ["MessageNotUnderstood"]
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "shouldMNUMiddle",
+category: 'testing',
+fn: function (){
+var self=this;
+function $MessageNotUnderstood(){return smalltalk.MessageNotUnderstood||(typeof MessageNotUnderstood=="undefined"?nil:MessageNotUnderstood)}
+return smalltalk.withContext(function($ctx1) { 
+self._should_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(self["@performBlock"])._value_(self["@receiverMiddle"]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),$MessageNotUnderstood());
+return self}, function($ctx1) {$ctx1.fill(self,"shouldMNUMiddle",{},smalltalk.MethodInheritanceTest)})},
+args: [],
+source: "shouldMNUMiddle\x0a\x09self should: [ performBlock value: receiverMiddle ] raise: MessageNotUnderstood",
+messageSends: ["should:raise:", "value:"],
+referencedClasses: ["MessageNotUnderstood"]
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "shouldMNUTop",
+category: 'testing',
+fn: function (){
+var self=this;
+function $MessageNotUnderstood(){return smalltalk.MessageNotUnderstood||(typeof MessageNotUnderstood=="undefined"?nil:MessageNotUnderstood)}
+return smalltalk.withContext(function($ctx1) { 
+self._should_raise_((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(self["@performBlock"])._value_(self["@receiverTop"]);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}),$MessageNotUnderstood());
+return self}, function($ctx1) {$ctx1.fill(self,"shouldMNUTop",{},smalltalk.MethodInheritanceTest)})},
+args: [],
+source: "shouldMNUTop\x0a\x09self should: [ performBlock value: receiverTop ] raise: MessageNotUnderstood",
+messageSends: ["should:raise:", "value:"],
+referencedClasses: ["MessageNotUnderstood"]
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "shouldReturn:",
+category: 'testing',
+fn: function (anObject){
+var self=this;
+var result;
+return smalltalk.withContext(function($ctx1) { 
+result=_st(self["@performBlock"])._value_(self["@receiverTop"]);
+self._assert_equals_(["top",anObject],["top",result]);
+result=_st(self["@performBlock"])._value_(self["@receiverMiddle"]);
+self._assert_equals_(["middle",anObject],["middle",result]);
+result=_st(self["@performBlock"])._value_(self["@receiverBottom"]);
+self._assert_equals_(["bottom",anObject],["bottom",result]);
+return self}, function($ctx1) {$ctx1.fill(self,"shouldReturn:",{anObject:anObject,result:result},smalltalk.MethodInheritanceTest)})},
+args: ["anObject"],
+source: "shouldReturn: anObject\x0a\x09| result |\x0a\x0a\x09result := performBlock value: receiverTop.\x0a\x09self assert: { 'top'. anObject } equals: { 'top'. result }.\x0a\x09result := performBlock value: receiverMiddle.\x0a\x09self assert: { 'middle'. anObject } equals: { 'middle'. result }.\x0a\x09result := performBlock value: receiverBottom.\x0a\x09self assert: { 'bottom'. anObject } equals: { 'bottom'. result }",
+messageSends: ["value:", "assert:equals:"],
+referencedClasses: []
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "shouldReturn:and:and:",
+category: 'testing',
+fn: function (anObject,anObject2,anObject3){
+var self=this;
+var result;
+return smalltalk.withContext(function($ctx1) { 
+result=_st(self["@performBlock"])._value_(self["@receiverTop"]);
+self._assert_equals_(["top",anObject],["top",result]);
+result=_st(self["@performBlock"])._value_(self["@receiverMiddle"]);
+self._assert_equals_(["middle",anObject2],["middle",result]);
+result=_st(self["@performBlock"])._value_(self["@receiverBottom"]);
+self._assert_equals_(["bottom",anObject3],["bottom",result]);
+return self}, function($ctx1) {$ctx1.fill(self,"shouldReturn:and:and:",{anObject:anObject,anObject2:anObject2,anObject3:anObject3,result:result},smalltalk.MethodInheritanceTest)})},
+args: ["anObject", "anObject2", "anObject3"],
+source: "shouldReturn: anObject and: anObject2 and: anObject3\x0a\x09| result |\x0a\x0a\x09result := performBlock value: receiverTop.\x0a\x09self assert: { 'top'. anObject } equals: { 'top'. result }.\x0a\x09result := performBlock value: receiverMiddle.\x0a\x09self assert: { 'middle'. anObject2 } equals: { 'middle'. result }.\x0a\x09result := performBlock value: receiverBottom.\x0a\x09self assert: { 'bottom'. anObject3 } equals: { 'bottom'. result }",
+messageSends: ["value:", "assert:equals:"],
+referencedClasses: []
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "targetClassBottom",
+category: 'accessing',
+fn: function (){
+var self=this;
+function $JavaScriptException(){return smalltalk.JavaScriptException||(typeof JavaScriptException=="undefined"?nil:JavaScriptException)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=$JavaScriptException();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"targetClassBottom",{},smalltalk.MethodInheritanceTest)})},
+args: [],
+source: "targetClassBottom\x0a\x09^ JavaScriptException",
+messageSends: [],
+referencedClasses: ["JavaScriptException"]
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "targetClassMiddle",
+category: 'accessing',
+fn: function (){
+var self=this;
+function $Error(){return smalltalk.Error||(typeof Error=="undefined"?nil:Error)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=$Error();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"targetClassMiddle",{},smalltalk.MethodInheritanceTest)})},
+args: [],
+source: "targetClassMiddle\x0a\x09^ Error",
+messageSends: [],
+referencedClasses: ["Error"]
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "targetClassTop",
+category: 'accessing',
+fn: function (){
+var self=this;
+function $Object(){return smalltalk.Object||(typeof Object=="undefined"?nil:Object)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=$Object();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"targetClassTop",{},smalltalk.MethodInheritanceTest)})},
+args: [],
+source: "targetClassTop\x0a\x09^ Object",
+messageSends: [],
+referencedClasses: ["Object"]
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "tearDown",
+category: 'initialization',
+fn: function (){
+var self=this;
+function $Error(){return smalltalk.Error||(typeof Error=="undefined"?nil:Error)}
+return smalltalk.withContext(function($ctx1) { 
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
+return self._deinstallTop();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_($Error(),(function(){
+return smalltalk.withContext(function($ctx2) {
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
+return self._deinstallMiddle();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_($Error(),(function(){
+return smalltalk.withContext(function($ctx2) {
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
+return self._deinstallBottom();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._on_do_($Error(),(function(){
+return smalltalk.withContext(function($ctx2) {
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"tearDown",{},smalltalk.MethodInheritanceTest)})},
+args: [],
+source: "tearDown\x0a\x09[ self deinstallTop ] on: Error do: [].\x0a\x09[ self deinstallMiddle ] on: Error do: [].\x0a\x09[ self deinstallBottom ] on: Error do: []",
+messageSends: ["on:do:", "deinstallTop", "deinstallMiddle", "deinstallBottom"],
+referencedClasses: ["Error"]
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testMNU11",
+category: 'tests',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@performBlock"]=(function(x){
+return smalltalk.withContext(function($ctx2) {
+return _st(x)._foo();
+}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1)})});
+self._shouldMNU();
+self._installTop_("foo ^ false");
+self._installTop_("foo ^ true");
+self._deinstallTop();
+self._shouldMNU();
+return self}, function($ctx1) {$ctx1.fill(self,"testMNU11",{},smalltalk.MethodInheritanceTest)})},
+args: [],
+source: "testMNU11\x0a\x09performBlock := [ :x | x foo ].\x0a\x09self shouldMNU.\x0a\x09self installTop: 'foo ^ false'.\x0a\x09self installTop: 'foo ^ true'.\x0a\x09self deinstallTop.\x0a\x09self shouldMNU",
+messageSends: ["foo", "shouldMNU", "installTop:", "deinstallTop"],
+referencedClasses: []
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testMNU22",
+category: 'tests',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@performBlock"]=(function(x){
+return smalltalk.withContext(function($ctx2) {
+return _st(x)._foo();
+}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1)})});
+self._shouldMNU();
+self._installMiddle_("foo ^ false");
+self._installMiddle_("foo ^ true");
+self._deinstallMiddle();
+self._shouldMNU();
+return self}, function($ctx1) {$ctx1.fill(self,"testMNU22",{},smalltalk.MethodInheritanceTest)})},
+args: [],
+source: "testMNU22\x0a\x09performBlock := [ :x | x foo ].\x0a\x09self shouldMNU.\x0a\x09self installMiddle: 'foo ^ false'.\x0a\x09self installMiddle: 'foo ^ true'.\x0a\x09self deinstallMiddle.\x0a\x09self shouldMNU",
+messageSends: ["foo", "shouldMNU", "installMiddle:", "deinstallMiddle"],
+referencedClasses: []
+}),
+smalltalk.MethodInheritanceTest);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testReturns1",
+category: 'tests',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@performBlock"]=(function(x){
+return smalltalk.withContext(function($ctx2) {
+return _st(x)._foo();
+}, function($ctx2) {$ctx2.fillBlock({x:x},$ctx1)})});
+self._installTop_("foo ^ false");
+self._shouldReturn_(false);
+self._installTop_("foo ^ true");
+self._shouldReturn_(true);
+return self}, function($ctx1) {$ctx1.fill(self,"testReturns1",{},smalltalk.MethodInheritanceTest)})},
+args: [],
+source: "testReturns1\x0a\x09performBlock := [ :x | x foo ].\x0a\x09self installTop: 'foo ^ false'.\x0a\x09self shouldReturn: false.\x0a\x09self installTop: 'foo ^ true'.\x0a\x09self shouldReturn: true",
+messageSends: ["foo", "installTop:", "shouldReturn:"],
+referencedClasses: []
+}),
+smalltalk.MethodInheritanceTest);
+
+
+
 smalltalk.addClass('NumberTest', smalltalk.TestCase, [], 'Kernel-Tests');
 smalltalk.addMethod(
 smalltalk.method({

+ 7 - 7
js/Spaces.deploy.js

@@ -21,11 +21,11 @@ selector: "create",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(window)._jQuery_("body"))._append_("<iframe style=\x22display: none;\x22></iframe>");
-self["@frame"]=_st(_st(_st(window)._jQuery_("iframe"))._get())._last();
+_st("body"._asJQuery())._append_("<iframe style=\x22display: none;\x22></iframe>");
+self["@frame"]=_st(_st("iframe"._asJQuery())._get())._last();
 _st(_st(self["@frame"])._contentWindow())._location_(_st(window)._location());
 return self}, function($ctx1) {$ctx1.fill(self,"create",{},smalltalk.ObjectSpace)})},
-messageSends: ["append:", "jQuery:", "last", "get", "location:", "location", "contentWindow"]}),
+messageSends: ["append:", "asJQuery", "last", "get", "location:", "location", "contentWindow"]}),
 smalltalk.ObjectSpace);
 
 smalltalk.addMethod(
@@ -42,10 +42,10 @@ return $2;
 } else {
 $1;
 };
-_st(_st(window)._jQuery_(self["@frame"]))._remove();
+_st(_st(self["@frame"])._asJQuery())._remove();
 self._release();
 return self}, function($ctx1) {$ctx1.fill(self,"destroy",{},smalltalk.ObjectSpace)})},
-messageSends: ["ifNil:", "remove", "jQuery:", "release"]}),
+messageSends: ["ifNil:", "remove", "asJQuery", "release"]}),
 smalltalk.ObjectSpace);
 
 smalltalk.addMethod(
@@ -122,9 +122,9 @@ selector: "whenReadyDo:",
 fn: function (aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(window)._jQuery_(self["@frame"]))._bind_do_("load",aBlock);
+_st(_st(self["@frame"])._asJQuery())._bind_do_("load",aBlock);
 return self}, function($ctx1) {$ctx1.fill(self,"whenReadyDo:",{aBlock:aBlock},smalltalk.ObjectSpace)})},
-messageSends: ["bind:do:", "jQuery:"]}),
+messageSends: ["bind:do:", "asJQuery"]}),
 smalltalk.ObjectSpace);
 
 

+ 10 - 10
js/Spaces.js

@@ -28,13 +28,13 @@ category: 'initialization',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(window)._jQuery_("body"))._append_("<iframe style=\x22display: none;\x22></iframe>");
-self["@frame"]=_st(_st(_st(window)._jQuery_("iframe"))._get())._last();
+_st("body"._asJQuery())._append_("<iframe style=\x22display: none;\x22></iframe>");
+self["@frame"]=_st(_st("iframe"._asJQuery())._get())._last();
 _st(_st(self["@frame"])._contentWindow())._location_(_st(window)._location());
 return self}, function($ctx1) {$ctx1.fill(self,"create",{},smalltalk.ObjectSpace)})},
 args: [],
-source: "create\x0a\x09(window jQuery: 'body') append: '<iframe style=\x22display: none;\x22></iframe>'.\x0a\x09frame := (window jQuery: 'iframe') get last.\x0a\x09frame contentWindow location: window location",
-messageSends: ["append:", "jQuery:", "last", "get", "location:", "location", "contentWindow"],
+source: "create\x0a\x09'body' asJQuery append: '<iframe style=\x22display: none;\x22></iframe>'.\x0a\x09frame := 'iframe' asJQuery get last.\x0a\x09frame contentWindow location: window location",
+messageSends: ["append:", "asJQuery", "last", "get", "location:", "location", "contentWindow"],
 referencedClasses: []
 }),
 smalltalk.ObjectSpace);
@@ -54,12 +54,12 @@ return $2;
 } else {
 $1;
 };
-_st(_st(window)._jQuery_(self["@frame"]))._remove();
+_st(_st(self["@frame"])._asJQuery())._remove();
 self._release();
 return self}, function($ctx1) {$ctx1.fill(self,"destroy",{},smalltalk.ObjectSpace)})},
 args: [],
-source: "destroy\x0a\x09frame ifNil: [ ^ self ].\x0a\x09(window jQuery: frame) remove.\x0a\x0a\x09self release",
-messageSends: ["ifNil:", "remove", "jQuery:", "release"],
+source: "destroy\x0a\x09frame ifNil: [ ^ self ].\x0a\x09frame asJQuery remove.\x0a\x0a\x09self release",
+messageSends: ["ifNil:", "remove", "asJQuery", "release"],
 referencedClasses: []
 }),
 smalltalk.ObjectSpace);
@@ -164,11 +164,11 @@ category: 'events',
 fn: function (aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(window)._jQuery_(self["@frame"]))._bind_do_("load",aBlock);
+_st(_st(self["@frame"])._asJQuery())._bind_do_("load",aBlock);
 return self}, function($ctx1) {$ctx1.fill(self,"whenReadyDo:",{aBlock:aBlock},smalltalk.ObjectSpace)})},
 args: ["aBlock"],
-source: "whenReadyDo: aBlock\x0a\x09(window jQuery: frame)\x0a\x09\x09bind: 'load'\x0a\x09\x09do: aBlock",
-messageSends: ["bind:do:", "jQuery:"],
+source: "whenReadyDo: aBlock\x0a\x09frame asJQuery\x0a\x09\x09bind: 'load'\x0a\x09\x09do: aBlock",
+messageSends: ["bind:do:", "asJQuery"],
 referencedClasses: []
 }),
 smalltalk.ObjectSpace);

+ 46 - 2
st/Canvas.st

@@ -1,4 +1,48 @@
 Smalltalk current createPackage: 'Canvas'!
+Object subclass: #BrowserInterface
+	instanceVariableNames: ''
+	package: 'Canvas'!
+!BrowserInterface commentStamp!
+I am platform interface class that tries to use window and jQuery; that is, one for browser environment.
+
+## API
+
+    self isAvailable. "true if window and jQuery exist".
+
+    self alert: 'Hey, there is a problem'.
+    self confirm: 'Affirmative?'.
+    self prompt: 'Your name:'.
+
+    self ajax: #{
+        'url' -> '/patch.js'. 'type' -> 'GET'. dataType->'script'
+    }.!
+
+!BrowserInterface methodsFor: 'actions'!
+
+ajax: anObject
+	^jQuery ajax: anObject
+!
+
+alert: aString
+	^window alert: aString
+!
+
+confirm: aString
+	^window confirm: aString
+!
+
+prompt: aString
+	^window prompt: aString
+! !
+
+!BrowserInterface methodsFor: 'testing'!
+
+isAvailable
+<return typeof window !!== "undefined" && typeof jQuery !!== "undefined">
+! !
+
+BrowserInterface class instanceVariableNames: 'uiWorker ajaxWorker'!
+
 Object subclass: #HTMLCanvas
 	instanceVariableNames: 'root'
 	package: 'Canvas'!
@@ -887,7 +931,7 @@ width: aString
 !TagBrush methodsFor: 'converting'!
 
 asJQuery
-	^window jQuery: self element
+	^self element asJQuery
 ! !
 
 !TagBrush methodsFor: 'events'!
@@ -1038,7 +1082,7 @@ canvas: aCanvas
 	yourself
 ! !
 
-Object subclass: #Widget
+InterfacingObject subclass: #Widget
 	instanceVariableNames: ''
 	package: 'Canvas'!
 !Widget commentStamp!

+ 13 - 17
st/Helios-Core.st

@@ -372,7 +372,7 @@ compilationProtocol
 withHelperLabelled: aString do: aBlock
 	"TODO: doesn't belong here"
 
-	(window jQuery: '#helper') remove.
+	'#helper' asJQuery remove.
 
 	[ :html |
 		html div 
@@ -381,7 +381,7 @@ withHelperLabelled: aString do: aBlock
 	
 	[
 		aBlock value.
-		(window jQuery: '#helper') remove
+		'#helper' asJQuery remove
 	] 
 		valueWithTimeout: 10
 ! !
@@ -580,10 +580,6 @@ wrapper
 
 !HLWidget methodsFor: 'actions'!
 
-alert: aString
-	window alert: aString
-!
-
 confirm: aString ifTrue: aBlock
 	self manager confirm: aString ifTrue: aBlock
 !
@@ -781,7 +777,7 @@ selectedItem: anObject
 !HLListWidget methodsFor: 'actions'!
 
 activateFirstListItem
-	self activateListItem: (window jQuery: ((wrapper asJQuery find: 'li.inactive') get: 0))
+	self activateListItem: ((wrapper asJQuery find: 'li.inactive') eq: 0)
 !
 
 activateItem: anObject
@@ -1247,7 +1243,7 @@ initialize
 !HLManager methodsFor: 'rendering'!
 
 refresh
-	(window jQuery: '.navbar') remove.
+	'.navbar' asJQuery remove.
 	self appendToJQuery: 'body' asJQuery
 !
 
@@ -1335,7 +1331,7 @@ clearKeydownEvent
 	"Prevent default keydown event with arrow key from scrolling the parent page
 	when helios is run inside a frame."
 	
-	(window jQuery: 'body') keydown: [ :e | 
+	'body' asJQuery keydown: [ :e | 
 		(e keyCode >= 37 and: [ e keyCode <= 40 ])
 			ifTrue: [ false ] ]
 ! !
@@ -1359,10 +1355,10 @@ cancel
 !
 
 remove
-	(window jQuery: '.dialog') removeClass: 'active'.
+	'.dialog' asJQuery removeClass: 'active'.
 	[ 
-		(window jQuery: '#overlay') remove.
-		(window jQuery: '.dialog') remove
+		'#overlay' asJQuery remove.
+		'.dialog' asJQuery remove
 	] valueWithTimeout: 300
 ! !
 
@@ -1382,7 +1378,7 @@ renderContentOn: html
 				renderMainOn: html;
 				renderButtonsOn: html ].
 
-	(window jQuery: '.dialog') addClass: 'active'.
+	'.dialog' asJQuery addClass: 'active'.
 	self setupKeyBindings
 !
 
@@ -1390,7 +1386,7 @@ renderMainOn: html
 !
 
 setupKeyBindings
-	(window jQuery: '.dialog') keyup: [ :e |
+	'.dialog' asJQuery keyup: [ :e |
 		e keyCode = 27 ifTrue: [ self cancel ] ]
 ! !
 
@@ -1441,10 +1437,10 @@ confirm
 !
 
 remove
-	(window jQuery: '.dialog') removeClass: 'active'.
+	'.dialog' asJQuery removeClass: 'active'.
 	[ 
-		(window jQuery: '#overlay') remove.
-		(window jQuery: '.dialog') remove
+		'#overlay' asJQuery remove.
+		'.dialog' asJQuery remove
 	] valueWithTimeout: 300
 ! !
 

+ 3 - 3
st/Helios-KeyBindings.st

@@ -462,7 +462,7 @@ handleKeyDown: event
 !
 
 setupEvents
-	(window jQuery: 'body') keydown: [ :event | self handleKeyDown: event ]
+	'body' asJQuery keydown: [ :event | self handleKeyDown: event ]
 ! !
 
 !HLKeyBinder methodsFor: 'initialization'!
@@ -578,14 +578,14 @@ renderSelectionOn: html
 !
 
 renderStart
-	(window jQuery: '#helper') remove.
+	'#helper' asJQuery remove.
 
 	[ :html |
 		html div 
 			id: 'helper';
 			with: 'Press ', self keyBinder activationKeyLabel, ' to start' ] appendToJQuery: 'body' asJQuery.
 	
-	[ (window jQuery: '#helper') fadeOut: 1000 ] 
+	[ '#helper' asJQuery fadeOut: 1000 ] 
 		valueWithTimeout: 2000
 ! !
 

+ 2 - 2
st/Helios-Workspace.st

@@ -215,8 +215,8 @@ messageHintFor: anEditor token: aToken
 variableHintFor: anEditor token: aToken
 	| variables classNames pseudoVariables |
 	
-	variables := ((window jQuery: anEditor display wrapper) find: 'span.cm-variable') get
-		collect: [ :each | (window jQuery: each) html ].
+	variables := (anEditor display wrapper asJQuery find: 'span.cm-variable') get
+		collect: [ :each | each asJQuery html ].
 	
 	classNames := Smalltalk current classes collect: [ :each | each name ].
 	pseudoVariables := Smalltalk current pseudoVariableNames.

+ 24 - 22
st/IDE.st

@@ -245,7 +245,7 @@ eval: aString
 	| compiler |
 	compiler := Compiler new.
 	[ compiler parseExpression: aString ] on: Error do: [:ex |
-		^window alert: ex messageText].
+		^self alert: ex messageText].
 	^compiler evaluateExpression: aString on: self receiver
 !
 
@@ -380,15 +380,15 @@ newBrowserTab
 !
 
 onResize: aBlock
-	<jQuery('#amber').resizable({
-	handles: 'n',
-	resize: aBlock,
-	minHeight: 230
-})>
+	'#amber' asJQuery resizable: #{
+		'handles' -> 'n'.
+		'resize' -> aBlock.
+		'minHeight' -> 230
+	}
 !
 
 onWindowResize: aBlock
-	<jQuery(window).resize(aBlock)>
+	window asJQuery resize: aBlock
 !
 
 open
@@ -432,7 +432,9 @@ updateBodyMargin
 !
 
 updatePosition
-	<jQuery('#amber').css('top', '').css('bottom', '0px')>
+	'#amber' asJQuery
+		css: 'top' put: '';
+		css: 'bottom' put: '0px'
 ! !
 
 !TabManager methodsFor: 'adding/Removing'!
@@ -535,10 +537,10 @@ TabManager class instanceVariableNames: 'current'!
 !TabManager class methodsFor: 'actions'!
 
 toggleAmberIDE
-	(window jQuery: '#amber') length = 0
+	'#amber' asJQuery length = 0
 		ifTrue: [ Browser open ]
 		ifFalse: [
-			((window jQuery: '#amber') is: ':visible')
+			('#amber' asJQuery is: ':visible')
 				ifTrue: [ TabManager current close ]
 				ifFalse: [ TabManager current open ] ]
 ! !
@@ -780,7 +782,7 @@ addInstanceVariableNamed: aString toClass: aClass
 
 addNewClass
 	| className |
-	className := window prompt: 'New class'.
+	className := self prompt: 'New class'.
 	(className notNil and: [className notEmpty]) ifTrue: [
 		Object subclass: className instanceVariableNames: '' package: self selectedPackage.
 			self
@@ -791,7 +793,7 @@ addNewClass
 
 addNewProtocol
 	| newProtocol |
-	newProtocol := window prompt: 'New method protocol'.
+	newProtocol := self prompt: 'New method protocol'.
 	(newProtocol notNil and: [newProtocol notEmpty]) ifTrue: [
 	selectedMethod category: newProtocol.
 	self setMethodProtocol: newProtocol]
@@ -799,7 +801,7 @@ addNewProtocol
 
 cancelChanges
 	^unsavedChanges
-	ifTrue: [window confirm: 'Cancel changes?']
+	ifTrue: [self confirm: 'Cancel changes?']
 	ifFalse: [true]
 !
 
@@ -851,13 +853,13 @@ compileMethodDefinitionFor: aClass
 	compiler source: source.
 	node := compiler parse: source.
 	node isParseFailure ifTrue: [
-	^window alert: 'PARSE ERROR: ', node reason, ', position: ', node position asString].
+	^self alert: 'PARSE ERROR: ', node reason, ', position: ', node position asString].
 	compiler currentClass: aClass.
 	method := compiler eval: (compiler compileNode: node).
 	compiler unknownVariables do: [:each |
 		"Do not try to redeclare javascript's objects"
-		(window at: each) ifNil: [
-		(window confirm: 'Declare ''', each, ''' as instance variable?') ifTrue: [
+		(PlatformInterface existsGlobal: each) ifFalse: [
+		(self confirm: 'Declare ''', each, ''' as instance variable?') ifTrue: [
 			self addInstanceVariableNamed: each toClass: aClass.
 			^self compileMethodDefinitionFor: aClass]]].
 	ClassBuilder new installMethod: method forClass: aClass category: selectedProtocol.
@@ -867,7 +869,7 @@ compileMethodDefinitionFor: aClass
 
 copyClass
 	| className |
-	className := window prompt: 'Copy class'.
+	className := self prompt: 'Copy class'.
 	(className notNil and: [className notEmpty]) ifTrue: [
 		ClassBuilder new copyClass: self selectedClass named: className.
 			self
@@ -902,7 +904,7 @@ hideMethodButtons
 !
 
 removeClass
-	(window confirm: 'Do you really want to remove ', selectedClass name, '?')
+	(self confirm: 'Do you really want to remove ', selectedClass name, '?')
 	ifTrue: [
 		Smalltalk current removeClass: selectedClass.
 		self resetClassesList.
@@ -911,7 +913,7 @@ removeClass
 
 removeMethod
 	self cancelChanges ifTrue: [
-	(window confirm: 'Do you really want to remove #', selectedMethod selector, '?')
+	(self confirm: 'Do you really want to remove #', selectedMethod selector, '?')
 		ifTrue: [
 		selectedTab = #instance
 			ifTrue: [selectedClass removeCompiledMethod: selectedMethod]
@@ -921,7 +923,7 @@ removeMethod
 
 removePackage
 
-	(window confirm: 'Do you really want to remove the whole package ', selectedPackage, ' with all its classes?')
+	(self confirm: 'Do you really want to remove the whole package ', selectedPackage, ' with all its classes?')
 	ifTrue: [
 		Smalltalk current removePackage: selectedPackage.
 		self updateCategoriesList]
@@ -929,7 +931,7 @@ removePackage
 
 renameClass
 	| newName |
-	newName := window prompt: 'Rename class ', selectedClass name.
+	newName := self prompt: 'Rename class ', selectedClass name.
 	(newName notNil and: [newName notEmpty]) ifTrue: [
 	selectedClass rename: newName.
 	self
@@ -940,7 +942,7 @@ renameClass
 renamePackage
 
 	| newName |
-	newName := window prompt: 'Rename package ', selectedPackage.
+	newName := self prompt: 'Rename package ', selectedPackage.
 	newName ifNotNil: [
 	newName notEmpty ifTrue: [
 	Smalltalk current renamePackage: selectedPackage to: newName.

+ 8 - 8
st/Importer-Exporter.st

@@ -467,7 +467,7 @@ import: aStream
 									result scanFrom: parser]]]
 ! !
 
-Object subclass: #PackageHandler
+InterfacingObject subclass: #PackageHandler
 	instanceVariableNames: ''
 	package: 'Importer-Exporter'!
 !PackageHandler commentStamp!
@@ -490,9 +490,9 @@ commit: aPackage
 !PackageHandler methodsFor: 'private'!
 
 ajaxPutAt: aURL data: aString
-	jQuery
-		ajax: aURL 
-		options: #{ 
+	self
+		ajax: #{
+			'url' -> aURL.
 			'type' -> 'PUT'.
 			'data' -> aString.
 			'contentType' -> 'text/plain;charset=UTF-8'.
@@ -627,15 +627,15 @@ commitPathStFor: aPackage
 loadPackage: packageName prefix: aString
 	| url |
 	url := '/', aString, '/js/', packageName, '.js'.
-	jQuery
-		ajax: url
-		options: #{
+	self
+		ajax: #{
+			'url' -> url.
 			'type' -> 'GET'.
 			'dataType' -> 'script'.
 			'complete' -> [ :jqXHR :textStatus |
 				jqXHR readyState = 4
 					ifTrue: [ self setupPackageNamed: packageName prefix: aString ] ].
-			'error' -> [ window alert: 'Could not load package at: ', url ]
+			'error' -> [ self alert: 'Could not load package at: ', url ]
 		}
 !
 

+ 1 - 4
st/Kernel-Classes.st

@@ -267,10 +267,7 @@ basicAddCompiledMethod: aMethod
 !
 
 basicRemoveCompiledMethod: aMethod
-	<
-		smalltalk.removeMethod(aMethod)
-		smalltalk.init(self);
-	>
+	<smalltalk.removeMethod(aMethod,self)>
 ! !
 
 !Behavior methodsFor: 'testing'!

+ 1 - 7
st/Kernel-Methods.st

@@ -680,12 +680,6 @@ constructor: aString value:anObject value: anObject2 value:anObject3
 !NativeFunction class methodsFor: 'testing'!
 
 exists: aString
-	<
-		if(aString in window) {
-			return true
-		} else {
-			return false
-		}
-	>
+	^PlatformInterface existsGlobal: aString
 ! !
 

+ 146 - 33
st/Kernel-Objects.st

@@ -708,7 +708,69 @@ today
 	^self new
 ! !
 
-Object subclass: #Environment
+Object subclass: #InspectorHandler
+	instanceVariableNames: ''
+	package: 'Kernel-Objects'!
+!InspectorHandler commentStamp!
+I am responsible for inspecting object.
+
+My class-side `inspector` inst var holds the current inspector I'm delegating object inspection to.
+
+The default inspector object is the transcript.!
+
+InspectorHandler class instanceVariableNames: 'inspector'!
+
+!InspectorHandler class methodsFor: 'accessing'!
+
+inspector
+	^ inspector ifNil: [ inspector := Transcript ]
+! !
+
+!InspectorHandler class methodsFor: 'registration'!
+
+inspect: anObject
+	^ self inspector inspect: anObject
+!
+
+register: anInspector
+	inspector := anInspector
+! !
+
+Object subclass: #InterfacingObject
+	instanceVariableNames: ''
+	package: 'Kernel-Objects'!
+!InterfacingObject commentStamp!
+I am superclass of all object that interface with user or environment. `Widget` and a few other classes are subclasses of me. I delegate all of the above APIs to `PlatformInterface`.
+
+## API
+
+    self alert: 'Hey, there is a problem'.
+    self confirm: 'Affirmative?'.
+    self prompt: 'Your name:'.
+
+    self ajax: #{
+        'url' -> '/patch.js'. 'type' -> 'GET'. dataType->'script'
+    }.!
+
+!InterfacingObject methodsFor: 'actions'!
+
+ajax: anObject
+	^PlatformInterface ajax: anObject
+!
+
+alert: aString
+	^PlatformInterface alert: aString
+!
+
+confirm: aString
+	^PlatformInterface confirm: aString
+!
+
+prompt: aString
+	^PlatformInterface prompt: aString
+! !
+
+InterfacingObject subclass: #Environment
 	instanceVariableNames: ''
 	package: 'Kernel-Objects'!
 !Environment commentStamp!
@@ -778,7 +840,7 @@ eval: aString on: aReceiver
 	| compiler |
 	compiler := Compiler new.
 	[ compiler parseExpression: aString ] on: Error do: [ :ex |
-		^ window alert: ex messageText ].
+		^ self alert: ex messageText ].
 	^ compiler evaluateExpression: aString on: aReceiver
 !
 
@@ -892,34 +954,6 @@ evaluate: aBlock on: anErrorClass do: exceptionBlock
  			ifFalse: [ exception signal ] ]
 ! !
 
-Object subclass: #InspectorHandler
-	instanceVariableNames: ''
-	package: 'Kernel-Objects'!
-!InspectorHandler commentStamp!
-I am responsible for inspecting object.
-
-My class-side `inspector` inst var holds the current inspector I'm delegating object inspection to.
-
-The default inspector object is the transcript.!
-
-InspectorHandler class instanceVariableNames: 'inspector'!
-
-!InspectorHandler class methodsFor: 'accessing'!
-
-inspector
-	^ inspector ifNil: [ inspector := Transcript ]
-! !
-
-!InspectorHandler class methodsFor: 'registration'!
-
-inspect: anObject
-	^ self inspector inspect: anObject
-!
-
-register: anInspector
-	inspector := anInspector
-! !
-
 Object subclass: #JSObjectProxy
 	instanceVariableNames: 'jsObject'
 	package: 'Kernel-Objects'!
@@ -1496,14 +1530,18 @@ named: aPackageName ifAbsent: aBlock
 !Package class methodsFor: 'loading-storing'!
 
 load: aPackageName
+	self deprecatedAPI.
 	self load: aPackageName prefix: self defaultCommitPathJs, '/'
 !
 
 load: aPackageName prefix: aPrefix
-	jQuery
-		getScript: (aPrefix , aPackageName , '.js')
-		onSuccess: [
+	self deprecatedAPI.
+	PlatformInterface ajax: #{
+		'url' -> (aPrefix , aPackageName , '.js').
+		'dataType' -> 'script'.
+		'success' -> [
 			(Package named: aPackageName) setupClasses ]
+	}
 ! !
 
 !Package class methodsFor: 'sorting'!
@@ -1527,6 +1565,81 @@ sortedClasses: classes
 	^expandedClasses
 ! !
 
+Object subclass: #PlatformInterface
+	instanceVariableNames: ''
+	package: 'Kernel-Objects'!
+!PlatformInterface commentStamp!
+I am single entry point to UI and environment interface.
+My `initialize` tries several options (for now, browser environment only) to set myself up.
+
+## API
+
+    PlatformInterface alert: 'Hey, there is a problem'.
+    PlatformInterface confirm: 'Affirmative?'.
+    PlatformInterface prompt: 'Your name:'.
+
+    PlatformInterface ajax: #{
+        'url' -> '/patch.js'. 'type' -> 'GET'. dataType->'script'
+    }.!
+
+PlatformInterface class instanceVariableNames: 'worker'!
+
+!PlatformInterface class methodsFor: 'accessing'!
+
+setWorker: anObject
+	worker := anObject
+! !
+
+!PlatformInterface class methodsFor: 'actions'!
+
+ajax: anObject
+	^worker
+		ifNotNil: [ worker ajax: anObject ]
+		ifNil: [ self error: 'ajax: not available' ]
+!
+
+alert: aString
+	^worker
+		ifNotNil: [ worker alert: aString ]
+		ifNil: [ self error: 'alert: not available' ]
+!
+
+confirm: aString
+	^worker
+		ifNotNil: [ worker confirm: aString ]
+		ifNil: [ self error: 'confirm: not available' ]
+!
+
+existsGlobal: aString
+<
+	var f = new Function('aString',
+	'if (/^[0-9]/.test(aString) || !!/^[\\w_]+$/.test(aString))\n'+
+	'	return false;\n'+
+	'try { eval(aString); return true; } catch (ex) {}\n'+
+	'return false;');
+	return f(aString);
+>
+!
+
+prompt: aString
+	^worker
+		ifNotNil: [ worker prompt: aString ]
+		ifNil: [ self error: 'prompt: not available' ]
+! !
+
+!PlatformInterface class methodsFor: 'initialization'!
+
+initialize
+	| candidate |
+	
+	super initialize.
+	
+	BrowserInterface ifNotNil: [
+		candidate := BrowserInterface new.
+		candidate isAvailable ifTrue: [ self setWorker: candidate. ^self ]
+	]
+! !
+
 Object subclass: #Point
 	instanceVariableNames: 'x y'
 	package: 'Kernel-Objects'!

+ 140 - 0
st/Kernel-Tests.st

@@ -1189,6 +1189,146 @@ testValueWithArguments
 	self assert: (messageSend valueWithPossibleArguments: #(4)) equals: 6
 ! !
 
+TestCase subclass: #MethodInheritanceTest
+	instanceVariableNames: 'receiverTop receiverMiddle receiverBottom method performBlock'
+	package: 'Kernel-Tests'!
+
+!MethodInheritanceTest methodsFor: 'accessing'!
+
+codeGeneratorClass
+	^ CodeGenerator
+!
+
+targetClassBottom
+	^ JavaScriptException
+!
+
+targetClassMiddle
+	^ Error
+!
+
+targetClassTop
+	^ Object
+! !
+
+!MethodInheritanceTest methodsFor: 'factory'!
+
+compiler
+	^ Compiler new
+		codeGeneratorClass: self codeGeneratorClass;
+		yourself
+! !
+
+!MethodInheritanceTest methodsFor: 'initialization'!
+
+setUp
+	receiverTop := self targetClassTop new.
+	receiverMiddle := self targetClassMiddle new.
+	receiverBottom := self targetClassBottom new.
+	method := nil.
+	performBlock := [ self error: 'performBlock not initialized' ]
+!
+
+tearDown
+	[ self deinstallTop ] on: Error do: [].
+	[ self deinstallMiddle ] on: Error do: [].
+	[ self deinstallBottom ] on: Error do: []
+! !
+
+!MethodInheritanceTest methodsFor: 'testing'!
+
+deinstallBottom
+	self targetClassBottom removeCompiledMethod: method
+!
+
+deinstallMiddle
+	self targetClassMiddle removeCompiledMethod: method
+!
+
+deinstallTop
+	self targetClassTop removeCompiledMethod: method
+!
+
+installBottom: aString
+	method := self compiler install: aString forClass: self targetClassBottom category: 'tests'
+!
+
+installMiddle: aString
+	method := self compiler install: aString forClass: self targetClassMiddle category: 'tests'
+!
+
+installTop: aString
+	method := self compiler install: aString forClass: self targetClassTop category: 'tests'
+!
+
+shouldMNU
+	self shouldMNUTop.
+	self shouldMNUMiddle.
+	self shouldMNUBottom
+!
+
+shouldMNUBottom
+	self should: [ performBlock value: receiverBottom ] raise: MessageNotUnderstood
+!
+
+shouldMNUMiddle
+	self should: [ performBlock value: receiverMiddle ] raise: MessageNotUnderstood
+!
+
+shouldMNUTop
+	self should: [ performBlock value: receiverTop ] raise: MessageNotUnderstood
+!
+
+shouldReturn: anObject
+	| result |
+
+	result := performBlock value: receiverTop.
+	self assert: { 'top'. anObject } equals: { 'top'. result }.
+	result := performBlock value: receiverMiddle.
+	self assert: { 'middle'. anObject } equals: { 'middle'. result }.
+	result := performBlock value: receiverBottom.
+	self assert: { 'bottom'. anObject } equals: { 'bottom'. result }
+!
+
+shouldReturn: anObject and: anObject2 and: anObject3
+	| result |
+
+	result := performBlock value: receiverTop.
+	self assert: { 'top'. anObject } equals: { 'top'. result }.
+	result := performBlock value: receiverMiddle.
+	self assert: { 'middle'. anObject2 } equals: { 'middle'. result }.
+	result := performBlock value: receiverBottom.
+	self assert: { 'bottom'. anObject3 } equals: { 'bottom'. result }
+! !
+
+!MethodInheritanceTest methodsFor: 'tests'!
+
+testMNU11
+	performBlock := [ :x | x foo ].
+	self shouldMNU.
+	self installTop: 'foo ^ false'.
+	self installTop: 'foo ^ true'.
+	self deinstallTop.
+	self shouldMNU
+!
+
+testMNU22
+	performBlock := [ :x | x foo ].
+	self shouldMNU.
+	self installMiddle: 'foo ^ false'.
+	self installMiddle: 'foo ^ true'.
+	self deinstallMiddle.
+	self shouldMNU
+!
+
+testReturns1
+	performBlock := [ :x | x foo ].
+	self installTop: 'foo ^ false'.
+	self shouldReturn: false.
+	self installTop: 'foo ^ true'.
+	self shouldReturn: true
+! !
+
 TestCase subclass: #NumberTest
 	instanceVariableNames: ''
 	package: 'Kernel-Tests'!

+ 4 - 4
st/Spaces.st

@@ -34,7 +34,7 @@ do: aBlock
 !ObjectSpace methodsFor: 'events'!
 
 whenReadyDo: aBlock
-	(window jQuery: frame)
+	frame asJQuery
 		bind: 'load'
 		do: aBlock
 ! !
@@ -47,8 +47,8 @@ connectTo: aFrame
 !
 
 create
-	(window jQuery: 'body') append: '<iframe style="display: none;"></iframe>'.
-	frame := (window jQuery: 'iframe') get last.
+	'body' asJQuery append: '<iframe style="display: none;"></iframe>'.
+	frame := 'iframe' asJQuery get last.
 	frame contentWindow location: window location
 !
 
@@ -65,7 +65,7 @@ isConnected
 
 destroy
 	frame ifNil: [ ^ self ].
-	(window jQuery: frame) remove.
+	frame asJQuery remove.
 
 	self release
 !

+ 60 - 39
support/boot.js

@@ -79,6 +79,7 @@ function inherits(child, parent) {
 		constructor: { value: child,
 			enumerable: false, configurable: true, writable: true }
 	});
+	return child;
 }
 
 inherits(SmalltalkBehavior, SmalltalkObject);
@@ -135,6 +136,7 @@ function Smalltalk() {
 	var dnu = {
 		methods: [],
 		selectors: [],
+		checker: Object.create(null),
 
 		get: function (string) {
 			var index = this.selectors.indexOf(string);
@@ -143,11 +145,16 @@ function Smalltalk() {
 			}
 			this.selectors.push(string);
 			var selector = st.selector(string);
+			this.checker[selector] = true;
 			var method = {jsSelector: selector, fn: this.createHandler(selector)};
 			this.methods.push(method);
 			return method;
 		},
 
+		isSelector: function (selector) {
+			return this.checker[selector];
+		},
+
 		/* Dnu handler method */
 
 		createHandler: function (selector) {
@@ -197,7 +204,7 @@ function Smalltalk() {
 		spec = spec || {};
 		var meta = metaclass(spec);
 		var that = meta.instanceClass;
-		that.fn = spec.fn || function() {};
+		that.fn = spec.fn || inherits(function () {}, spec.superclass.fn);
 		setupClass(that, spec);
 
 		that.className = spec.className;
@@ -213,10 +220,7 @@ function Smalltalk() {
 	function metaclass(spec) {
 		spec = spec || {};
 		var that = new SmalltalkMetaclass();
-		inherits(
-			that.fn = function() {},
-			spec.superclass ? spec.superclass.klass.fn : SmalltalkClass
-		);
+		that.fn = inherits(function () {}, spec.superclass ? spec.superclass.klass.fn : SmalltalkClass);
 		that.instanceClass = new that.fn();
 		setupClass(that);
 		return that;
@@ -270,10 +274,7 @@ function Smalltalk() {
 
 	st.initClass = function(klass) {
 		if(klass.wrapped) {
-			klass.inheritedMethods = {};
 			copySuperclass(klass);
-		} else {
-			installSuperclass(klass);
 		}
 
 		if(klass === st.Object || klass.wrapped) {
@@ -288,25 +289,31 @@ function Smalltalk() {
 		});
 	}
 
-	function installSuperclass(klass) {
-		// only if the klass has not been initialized yet.
-		if(klass.fn.prototype._yourself) { return; }
-
-		if(klass.superclass && klass.superclass !== nil) {
-			inherits(klass.fn, klass.superclass.fn);
-			wireKlass(klass);
-			reinstallMethods(klass);
-		}
-	}
-
 	function copySuperclass(klass, superclass) {
+		var inheritedMethods = {};
+		deinstallAllMethods(klass);
 		for (superclass = superclass || klass.superclass;
 			superclass && superclass !== nil;
 			superclass = superclass.superclass) {
 			for (var keys = Object.keys(superclass.methods), i = 0; i < keys.length; i++) {
-				inheritMethodIfAbsent(superclass.methods[keys[i]], klass);
+				inheritMethodIfAbsent(superclass.methods[keys[i]]);
 			}
 		}
+		reinstallMethods(klass);
+
+		function inheritMethodIfAbsent(method) {
+			var selector = method.selector;
+
+			//TODO: prepare klass methods into inheritedMethods to only test once
+			//TODO: Object.create(null) to ditch hasOwnProperty call (very slow)
+			if(klass.methods.hasOwnProperty(selector) || inheritedMethods.hasOwnProperty(selector)) {
+				return;
+			}
+
+			installMethod(method, klass);
+			inheritedMethods[method.selector] = true;
+		}
+
 	}
 
 	function installMethod(method, klass) {
@@ -316,15 +323,14 @@ function Smalltalk() {
 		});
 	}
 
-	function inheritMethodIfAbsent(method, klass) {
-		var selector = method.selector;
-
-		if(klass.methods.hasOwnProperty(selector) || klass.inheritedMethods.hasOwnProperty(selector)) {
-			return;
+	function deinstallAllMethods(klass) {
+		var proto = klass.fn.prototype;
+		for(var keys = Object.getOwnPropertyNames(proto), i=0; i<keys.length; i++) {
+			var key = keys[i];
+			if (dnu.isSelector(key)) {
+				proto[key] = null;
+			}
 		}
-
-		installMethod(method, klass);
-		klass.inheritedMethods[method.selector] = true;
 	}
 
 	function reinstallMethods(klass) {
@@ -354,6 +360,20 @@ function Smalltalk() {
 		}
 	}
 
+	function propagateMethodChange(klass) {
+		// If already initialized (else it will be done later anyway),
+		// re-initialize all subclasses to ensure the method change
+		// propagation (for wrapped classes, not using the prototype
+		// chain).
+
+		//TODO: optimize, only one method need to be updated, not all of them
+		if (initialized) {
+			st.allSubclasses(klass).forEach(function (subclass) {
+				st.initClass(subclass);
+			});
+		}
+	}
+
 	/* Answer all registered Packages as Array */
 	// TODO: Remove this hack
 
@@ -520,15 +540,7 @@ function Smalltalk() {
 		// Therefore we populate the organizer here too
 		klass.organization.elements.addElement(method.category);
 
-		// If already initialized (else it will be done later anyway),
-		// re-initialize all subclasses to ensure the new method
-		// propagation (for wrapped classes, not using the prototype
-		// chain.
-		if(initialized) {
-			st.allSubclasses(klass).forEach(function(subclass) {
-				st.initClass(subclass);
-			});
-		}
+		propagateMethodChange(klass);
 
 		for(var i=0; i<method.messageSends.length; i++) {
 			var dnuHandler = dnu.get(method.messageSends[i]);
@@ -538,12 +550,21 @@ function Smalltalk() {
 		}
 	}
 
-	st.removeMethod = function(method) {
-		var klass = method.methodClass;
+	st.removeMethod = function(method, klass) {
+		if (klass !== method.methodClass) {
+			throw new Error(
+				"Refusing to remove method "
+					+ method.methodClass.className+">>"+method.selector
+					+ " from different class "
+					+ klass.className);
+		}
 
 		delete klass.fn.prototype[st.selector(method.selector)];
 		delete klass.methods[method.selector];
 
+		st.initClass(klass);
+		propagateMethodChange(klass);
+
 		// Do *not* delete protocols from here.
 		// This is handled by #removeCompiledMethod
 	};

+ 4 - 2
test/Test.js

@@ -52,10 +52,12 @@ if(smalltalk.assert($1)){
 _st(console)._log_(_st(_st(_st(_st(_st(_st(_st(result)._runs())._asString()).__comma(" tests run, ")).__comma(_st(_st(_st(result)._failures())._size())._asString())).__comma(" failures, ")).__comma(_st(_st(_st(result)._errors())._size())._asString())).__comma(" errors."));
 $2=_st(_st(result)._failures())._isEmpty();
 if(! smalltalk.assert($2)){
+_st(_st(_st(result)._failures())._first())._runCase();
 self._throw_(_st(_st(_st(_st(_st(_st(_st(result)._failures())._first())._class())._name()).__comma(" >> ")).__comma(_st(_st(_st(result)._failures())._first())._selector())).__comma(" is failing!"));
 };
 $3=_st(_st(result)._errors())._isEmpty();
 if(! smalltalk.assert($3)){
+_st(_st(_st(result)._errors())._first())._runCase();
 return self._throw_(_st(_st(_st(_st(_st(_st(_st(result)._errors())._first())._class())._name()).__comma(" >> ")).__comma(_st(_st(_st(result)._errors())._first())._selector())).__comma(" has errors!"));
 };
 };
@@ -63,8 +65,8 @@ return self._throw_(_st(_st(_st(_st(_st(_st(_st(result)._errors())._first())._cl
 _st(worker)._run();
 return self}, function($ctx1) {$ctx1.fill(self,"runTestSuite",{suite:suite,worker:worker},smalltalk.NodeTestRunner.klass)})},
 args: [],
-source: "runTestSuite\x0a\x09| suite worker |\x0a\x0a\x09suite := OrderedCollection new.\x0a    (TestCase allSubclasses select: [ :each | each isAbstract not ])\x0a\x09do: [ :each | suite addAll: each buildSuite ].\x0a\x0a\x09worker := TestSuiteRunner on: suite.\x0a\x09worker announcer on: ResultAnnouncement do:\x0a\x09[ :ann | | result |\x0a    \x09result := ann result.\x0a        result runs = result total ifTrue: [\x0a\x09        console log: result runs asString, ' tests run, ', result failures size asString, ' failures, ', result errors size asString, ' errors.'.\x0a\x0a            result failures isEmpty ifFalse: [\x0a                self throw: result failures first class name, ' >> ', result failures first selector, ' is failing!' ].\x0a            result errors isEmpty ifFalse: [\x0a                self throw: result errors first class name, ' >> ', result errors first selector, ' has errors!' ].\x0a    ]].\x0a    worker run",
-messageSends: ["new", "do:", "addAll:", "buildSuite", "select:", "not", "isAbstract", "allSubclasses", "on:", "on:do:", "result", "ifTrue:", "log:", ",", "asString", "size", "errors", "failures", "runs", "ifFalse:", "throw:", "selector", "first", "name", "class", "isEmpty", "=", "total", "announcer", "run"],
+source: "runTestSuite\x0a\x09| suite worker |\x0a\x0a\x09suite := OrderedCollection new.\x0a    (TestCase allSubclasses select: [ :each | each isAbstract not ])\x0a\x09do: [ :each | suite addAll: each buildSuite ].\x0a\x0a\x09worker := TestSuiteRunner on: suite.\x0a\x09worker announcer on: ResultAnnouncement do:\x0a\x09[ :ann | | result |\x0a    \x09result := ann result.\x0a        result runs = result total ifTrue: [\x0a\x09        console log: result runs asString, ' tests run, ', result failures size asString, ' failures, ', result errors size asString, ' errors.'.\x0a\x0a            result failures isEmpty ifFalse: [\x0a                result failures first runCase.\x0a                \x22the line above should throw, normally, but just in case I leave the line below\x22\x0a                self throw: result failures first class name, ' >> ', result failures first selector, ' is failing!' ].\x0a            result errors isEmpty ifFalse: [\x0a                result errors first runCase.\x0a                \x22the line above should throw, normally, but just in case I leave the line below\x22\x0a                self throw: result errors first class name, ' >> ', result errors first selector, ' has errors!' ].\x0a    ]].\x0a    worker run",
+messageSends: ["new", "do:", "addAll:", "buildSuite", "select:", "not", "isAbstract", "allSubclasses", "on:", "on:do:", "result", "ifTrue:", "log:", ",", "asString", "size", "errors", "failures", "runs", "ifFalse:", "runCase", "first", "throw:", "selector", "name", "class", "isEmpty", "=", "total", "announcer", "run"],
 referencedClasses: ["OrderedCollection", "TestCase", "TestSuiteRunner", "ResultAnnouncement"]
 }),
 smalltalk.NodeTestRunner.klass);

+ 4 - 0
test/Test.st

@@ -24,8 +24,12 @@ runTestSuite
 	        console log: result runs asString, ' tests run, ', result failures size asString, ' failures, ', result errors size asString, ' errors.'.
 
             result failures isEmpty ifFalse: [
+                result failures first runCase.
+                "the line above should throw, normally, but just in case I leave the line below"
                 self throw: result failures first class name, ' >> ', result failures first selector, ' is failing!!' ].
             result errors isEmpty ifFalse: [
+                result errors first runCase.
+                "the line above should throw, normally, but just in case I leave the line below"
                 self throw: result errors first class name, ' >> ', result errors first selector, ' has errors!!' ].
     ]].
     worker run