Kaynağa Gözat

Merge branch 'master' into debugger

Conflicts:
	js/boot.js
Nicolas Petton 11 yıl önce
ebeveyn
işleme
164f23a04b

+ 2 - 3
Gruntfile.js

@@ -28,7 +28,7 @@ module.exports = function(grunt) {
     },
 
     amberc: {
-      _config: {
+      options: {
         amber_dir: process.cwd(),
         closure_jar: ''
       },
@@ -59,8 +59,7 @@ module.exports = function(grunt) {
       amber_canvas: {
         output_dir : 'js',
         src: ['st/Canvas.st', 'st/SUnit.st'],
-        deploy: true,
-        verbose: true
+        deploy: true
       },
       amber_IDE: {
         output_dir : 'js',

+ 16 - 11
cli/js/AmberCli.deploy.js

@@ -62,20 +62,27 @@ smalltalk.method({
 selector: "main",
 fn: function (){
 var self=this;
-var args;
+var args,nodeMinorVersion;
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
+var $1,$2,$3;
+nodeMinorVersion=_st(_st(_st(_st(process)._version())._tokenize_("."))._second())._asNumber();
+$1=_st(nodeMinorVersion).__lt((8));
+if(smalltalk.assert($1)){
+_st(console)._log_(_st("You are currently using Node.js ").__comma(_st(process)._version()));
+_st(console)._log_("Required is at least Node.js v0.8.x or greater.");
+return (-1);
+};
 args=_st(process)._argv();
 _st(args)._removeFrom_to_((1),(3));
-$1=_st(args)._isEmpty();
-if(smalltalk.assert($1)){
+$2=_st(args)._isEmpty();
+if(smalltalk.assert($2)){
 _st(self)._help_(nil);
 } else {
-$2=_st(self)._handleArguments_(args);
-return $2;
+$3=_st(self)._handleArguments_(args);
+return $3;
 };
-return self}, function($ctx1) {$ctx1.fill(self,"main",{args:args},smalltalk.AmberCli.klass)})},
-messageSends: ["argv", "removeFrom:to:", "ifTrue:ifFalse:", "help:", "handleArguments:", "isEmpty"]}),
+return self}, function($ctx1) {$ctx1.fill(self,"main",{args:args,nodeMinorVersion:nodeMinorVersion},smalltalk.AmberCli.klass);});},
+messageSends: ["asNumber", "second", "tokenize:", "version", "ifTrue:", "log:", ",", "<", "argv", "removeFrom:to:", "ifTrue:ifFalse:", "help:", "handleArguments:", "isEmpty"]}),
 smalltalk.AmberCli.klass);
 
 smalltalk.addMethod(
@@ -772,9 +779,7 @@ selector: "defaultPort",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=(4000);
-return $1;
+return (4000);
 }, function($ctx1) {$ctx1.fill(self,"defaultPort",{},smalltalk.FileServer.klass)})},
 messageSends: []}),
 smalltalk.FileServer.klass);

Dosya farkı çok büyük olduğundan ihmal edildi
+ 72 - 65
cli/js/AmberCli.js


Dosya farkı çok büyük olduğundan ihmal edildi
+ 139 - 125
cli/js/amber-cli.js


+ 9 - 1
cli/st/AmberCli.st

@@ -73,7 +73,15 @@ serve: args
 main
 	"Main entry point for Amber applications.
 	Parses commandline arguments and starts the according subprogram."
-	| args |
+	| args nodeMinorVersion |
+
+	nodeMinorVersion := ((process version) tokenize: '.') second asNumber.
+	nodeMinorVersion < 8 ifTrue: [
+		console log: 'You are currently using Node.js ', (process version).
+		console log: 'Required is at least Node.js v0.8.x or greater.'.
+		^ -1.
+	].
+
 	args := process argv.
 	"Remove the first args which contain the path to the node executable and the script file."
 	args removeFrom: 1 to: 3.

+ 16 - 11
grunt/tasks/grunt-amberc.js

@@ -9,7 +9,8 @@ module.exports = function(grunt) {
      amberc: {
        _config: {
          amber_dir: process.cwd(),     // REQUIRED
-         closure_jar: ''               // optional
+         closure_jar: '',              // optional
+         verbose: true                 // optional
        },
        helloWorld: {
          src: ['projects/HelloWorld/st/HelloWorld.st'], // REQUIRED
@@ -21,25 +22,31 @@ module.exports = function(grunt) {
          main_file: 'myMain.js',               // optional
          deploy: true,                         // optional
          output_suffix: 'mySuffix',            // optional
-         library_suffix: '-0.9',               // optional
-         verbose: true                         // optional
+         library_suffix: '-0.9'               // optional
        },
      },
 
    */
   grunt.registerMultiTask('amberc', 'Compile Smalltalk files with the amberc compiler', function() {
     // mark required properties
-    this.requiresConfig('amberc._config.amber_dir');
+    this.requiresConfig('amberc.options.amber_dir');
     this.requiresConfig(['amberc', this.target, 'src']);
 
+    var options = this.options({
+      amber_dir: undefined,
+      closure_jar: '',
+      verbose: false
+    });
+    this.data.verbose = options.verbose;
+
     // mark task as async task
     var done = this.async();
 
     // create and initialize amberc
-    var compiler = new amberc.Compiler(grunt.config('amberc._config.amber_dir'), grunt.config('amberc._config.closure_jar'));
+    var compiler = new amberc.Compiler(grunt.config('amberc.options.amber_dir'), grunt.config('amberc.options.closure_jar'));
 
     // generate the amberc configuration out of the given target properties
-    var configuration = generateCompilerConfiguration(this.data, grunt.config('amberc._config.amber_dir'));
+    var configuration = generateCompilerConfiguration(this.data, grunt.config('amberc.options.amber_dir'));
 
     // run the compiler
     // change back to the old working directory and call the async callback once finished
@@ -68,7 +75,7 @@ module.exports = function(grunt) {
       configuration.main = mainClass;
     }
     var mainFile = data.main_file;
-    if (undefined !== initFile) {
+    if (undefined !== mainFile) {
       configuration.mainfile = mainFile;
     }
     if (true === data.deploy) {
@@ -103,11 +110,9 @@ module.exports = function(grunt) {
       configuration.program = outputName;
     }
     if (undefined !== data.output_dir) {
-    	configuration.output_dir = data.output_dir;
-    }
-    if (true === data.verbose) {
-    	configuration.verbose = true;
+      configuration.output_dir = data.output_dir;
     }
+    configuration.verbose = data.verbose;
     return configuration;
   }
 };

+ 1 - 1
js/Canvas.deploy.js

@@ -1680,7 +1680,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=self["@snippets"];
 if(($receiver = $2) == nil || $receiver == undefined){
-self["@snippets"]=smalltalk.HashedCollection._fromPairs_([]);
+self["@snippets"]=smalltalk.HashedCollection._from_([]);
 $1=self["@snippets"];
 } else {
 $1=$2;

+ 1 - 1
js/Canvas.js

@@ -2308,7 +2308,7 @@ return smalltalk.withContext(function($ctx1) {
 var $2,$1;
 $2=self["@snippets"];
 if(($receiver = $2) == nil || $receiver == undefined){
-self["@snippets"]=smalltalk.HashedCollection._fromPairs_([]);
+self["@snippets"]=smalltalk.HashedCollection._from_([]);
 $1=self["@snippets"];
 } else {
 $1=$2;

+ 1 - 1
js/Compiler-IR.deploy.js

@@ -2062,7 +2062,7 @@ selector: "visitIRDynamicDictionary:",
 fn: function (anIRDynamicDictionary){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(self._stream())._nextPutAll_("smalltalk.HashedCollection._fromPairs_([");
+_st(self._stream())._nextPutAll_("smalltalk.HashedCollection._from_([");
 _st(_st(anIRDynamicDictionary)._instructions())._do_separatedBy_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return self._visit_(each);

+ 2 - 2
js/Compiler-IR.js

@@ -2772,7 +2772,7 @@ category: 'visiting',
 fn: function (anIRDynamicDictionary){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(self._stream())._nextPutAll_("smalltalk.HashedCollection._fromPairs_([");
+_st(self._stream())._nextPutAll_("smalltalk.HashedCollection._from_([");
 _st(_st(anIRDynamicDictionary)._instructions())._do_separatedBy_((function(each){
 return smalltalk.withContext(function($ctx2) {
 return self._visit_(each);
@@ -2783,7 +2783,7 @@ return _st(self._stream())._nextPutAll_(",");
 _st(self._stream())._nextPutAll_("])");
 return self}, function($ctx1) {$ctx1.fill(self,"visitIRDynamicDictionary:",{anIRDynamicDictionary:anIRDynamicDictionary},smalltalk.IRJSTranslator)})},
 args: ["anIRDynamicDictionary"],
-source: "visitIRDynamicDictionary: anIRDynamicDictionary\x0a\x09self stream nextPutAll: 'smalltalk.HashedCollection._fromPairs_(['.\x0a\x09\x09anIRDynamicDictionary instructions\x0a\x09\x09\x09do: [ :each | self visit: each ]\x0a\x09\x09\x09separatedBy: [self stream nextPutAll: ',' ].\x0a\x09self stream nextPutAll: '])'",
+source: "visitIRDynamicDictionary: anIRDynamicDictionary\x0a\x09self stream nextPutAll: 'smalltalk.HashedCollection._from_(['.\x0a\x09\x09anIRDynamicDictionary instructions\x0a\x09\x09\x09do: [ :each | self visit: each ]\x0a\x09\x09\x09separatedBy: [self stream nextPutAll: ',' ].\x0a\x09self stream nextPutAll: '])'",
 messageSends: ["nextPutAll:", "stream", "do:separatedBy:", "visit:", "instructions"],
 referencedClasses: []
 }),

+ 8 - 8
js/Compiler-Tests.deploy.js

@@ -314,7 +314,7 @@ selector: "testDynamicDictionary",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self._assert_equals_(self._interpret_("foo ^ #{1->1. 2->3}"),smalltalk.HashedCollection._fromPairs_([(1).__minus_gt((1)),(2).__minus_gt((3))]));
+self._assert_equals_(self._interpret_("foo ^ #{1->1. 2->3}"),smalltalk.HashedCollection._from_([(1).__minus_gt((1)),(2).__minus_gt((3))]));
 return self}, function($ctx1) {$ctx1.fill(self,"testDynamicDictionary",{},smalltalk.ASTInterpreterTest)})},
 messageSends: ["assert:equals:", "interpret:", "->"]}),
 smalltalk.ASTInterpreterTest);
@@ -326,7 +326,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._assert_equals_(self._interpret_("foo <return 2+3>"),(5));
-self._assert_equals_(self._interpret_withArguments_("foo: anInteger <return 2 + anInteger>",smalltalk.HashedCollection._fromPairs_(["anInteger".__minus_gt((3))])),(5));
+self._assert_equals_(self._interpret_withArguments_("foo: anInteger <return 2 + anInteger>",smalltalk.HashedCollection._from_(["anInteger".__minus_gt((3))])),(5));
 return self}, function($ctx1) {$ctx1.fill(self,"testInlinedJSStatement",{},smalltalk.ASTInterpreterTest)})},
 messageSends: ["assert:equals:", "interpret:", "interpret:withArguments:", "->"]}),
 smalltalk.ASTInterpreterTest);
@@ -337,7 +337,7 @@ selector: "testInstVarAccess",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self._assert_equals_(self._interpret_receiver_withArguments_("foo ^ x",(2).__at((3)),smalltalk.HashedCollection._fromPairs_([])),(2));
+self._assert_equals_(self._interpret_receiver_withArguments_("foo ^ x",(2).__at((3)),smalltalk.HashedCollection._from_([])),(2));
 return self}, function($ctx1) {$ctx1.fill(self,"testInstVarAccess",{},smalltalk.ASTInterpreterTest)})},
 messageSends: ["assert:equals:", "interpret:receiver:withArguments:", "@"]}),
 smalltalk.ASTInterpreterTest);
@@ -349,7 +349,7 @@ fn: function (){
 var self=this;
 function $Point(){return smalltalk.Point||(typeof Point=="undefined"?nil:Point)}
 return smalltalk.withContext(function($ctx1) { 
-self._assert_equals_(self._interpret_receiver_withArguments_("foo: anInteger x := anInteger. ^ x",_st($Point())._new(),smalltalk.HashedCollection._fromPairs_(["anInteger".__minus_gt((2))])),(2));
+self._assert_equals_(self._interpret_receiver_withArguments_("foo: anInteger x := anInteger. ^ x",_st($Point())._new(),smalltalk.HashedCollection._from_(["anInteger".__minus_gt((2))])),(2));
 return self}, function($ctx1) {$ctx1.fill(self,"testInstVarAssignment",{},smalltalk.ASTInterpreterTest)})},
 messageSends: ["assert:equals:", "interpret:receiver:withArguments:", "new", "->"]}),
 smalltalk.ASTInterpreterTest);
@@ -371,7 +371,7 @@ selector: "testReceiver",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self._assert_equals_(self._interpret_receiver_withArguments_("foo ^ self",(2).__at((3)),smalltalk.HashedCollection._fromPairs_([])),(2).__at((3)));
+self._assert_equals_(self._interpret_receiver_withArguments_("foo ^ self",(2).__at((3)),smalltalk.HashedCollection._from_([])),(2).__at((3)));
 return self}, function($ctx1) {$ctx1.fill(self,"testReceiver",{},smalltalk.ASTInterpreterTest)})},
 messageSends: ["assert:equals:", "interpret:receiver:withArguments:", "@"]}),
 smalltalk.ASTInterpreterTest);
@@ -889,7 +889,7 @@ selector: "testDynamicDictionaryElementsOrdered",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self._should_return_("foo\x0a\x09| x |\x0a\x09x := 'foo'->1.\x0a\x09^ #{ x. (true ifTrue: [ x := 'bar'->2 ]) }\x0a",smalltalk.HashedCollection._fromPairs_(["foo".__minus_gt((1)),"bar".__minus_gt((2))]));
+self._should_return_("foo\x0a\x09| x |\x0a\x09x := 'foo'->1.\x0a\x09^ #{ x. (true ifTrue: [ x := 'bar'->2 ]) }\x0a",smalltalk.HashedCollection._from_(["foo".__minus_gt((1)),"bar".__minus_gt((2))]));
 return self}, function($ctx1) {$ctx1.fill(self,"testDynamicDictionaryElementsOrdered",{},smalltalk.CodeGeneratorTest)})},
 messageSends: ["should:return:", "->"]}),
 smalltalk.CodeGeneratorTest);
@@ -904,7 +904,7 @@ return smalltalk.withContext(function($ctx1) {
 self._should_return_("foo\x0a\x09| x |\x0a\x09x := Array.\x0a\x09^ x with: 'foo'->x with: 'bar'->(true ifTrue: [ x := 2 ])\x0a",["foo".__minus_gt($Array()),"bar".__minus_gt((2))]);
 self._should_return_("foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ Array with: 'foo'->x with: 'bar'->(true ifTrue: [ x := 2 ])\x0a",["foo".__minus_gt((1)),"bar".__minus_gt((2))]);
 self._should_return_("foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ { 'foo'->x. 'bar'->(true ifTrue: [ x := 2 ]) }\x0a",["foo".__minus_gt((1)),"bar".__minus_gt((2))]);
-self._should_return_("foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ #{ 'foo'->x. 'bar'->(true ifTrue: [ x := 2 ]) }\x0a",smalltalk.HashedCollection._fromPairs_(["foo".__minus_gt((1)),"bar".__minus_gt((2))]));
+self._should_return_("foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ #{ 'foo'->x. 'bar'->(true ifTrue: [ x := 2 ]) }\x0a",smalltalk.HashedCollection._from_(["foo".__minus_gt((1)),"bar".__minus_gt((2))]));
 return self}, function($ctx1) {$ctx1.fill(self,"testInnerTemporalDependentElementsOrdered",{},smalltalk.CodeGeneratorTest)})},
 messageSends: ["should:return:", "->"]}),
 smalltalk.CodeGeneratorTest);
@@ -921,7 +921,7 @@ self._should_return_("foo ^ #(1 2 3 4)",[(1), (2), (3), (4)]);
 self._should_return_("foo ^ {1. [:x | x ] value: 2. 3. [4] value}",[(1), (2), (3), (4)]);
 self._should_return_("foo ^ true",true);
 self._should_return_("foo ^ false",false);
-self._should_return_("foo ^ #{1->2. 3->4}",smalltalk.HashedCollection._fromPairs_([(1).__minus_gt((2)),(3).__minus_gt((4))]));
+self._should_return_("foo ^ #{1->2. 3->4}",smalltalk.HashedCollection._from_([(1).__minus_gt((2)),(3).__minus_gt((4))]));
 self._should_return_("foo ^ #hello","hello");
 self._should_return_("foo ^ -123.456",(-123.456));
 return self}, function($ctx1) {$ctx1.fill(self,"testLiterals",{},smalltalk.CodeGeneratorTest)})},

+ 8 - 8
js/Compiler-Tests.js

@@ -410,7 +410,7 @@ category: 'tests',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self._assert_equals_(self._interpret_("foo ^ #{1->1. 2->3}"),smalltalk.HashedCollection._fromPairs_([(1).__minus_gt((1)),(2).__minus_gt((3))]));
+self._assert_equals_(self._interpret_("foo ^ #{1->1. 2->3}"),smalltalk.HashedCollection._from_([(1).__minus_gt((1)),(2).__minus_gt((3))]));
 return self}, function($ctx1) {$ctx1.fill(self,"testDynamicDictionary",{},smalltalk.ASTInterpreterTest)})},
 args: [],
 source: "testDynamicDictionary\x0a\x09self assert: (self interpret: 'foo ^ #{1->1. 2->3}') equals: #{1->1. 2->3}",
@@ -427,7 +427,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 self._assert_equals_(self._interpret_("foo <return 2+3>"),(5));
-self._assert_equals_(self._interpret_withArguments_("foo: anInteger <return 2 + anInteger>",smalltalk.HashedCollection._fromPairs_(["anInteger".__minus_gt((3))])),(5));
+self._assert_equals_(self._interpret_withArguments_("foo: anInteger <return 2 + anInteger>",smalltalk.HashedCollection._from_(["anInteger".__minus_gt((3))])),(5));
 return self}, function($ctx1) {$ctx1.fill(self,"testInlinedJSStatement",{},smalltalk.ASTInterpreterTest)})},
 args: [],
 source: "testInlinedJSStatement\x0a\x09self assert: (self interpret: 'foo <return 2+3>') equals: 5.\x0a\x09\x0a\x09self\x0a\x09\x09assert: (self\x0a\x09\x09\x09interpret: 'foo: anInteger <return 2 + anInteger>'\x0a\x09\x09\x09withArguments: #{ 'anInteger' -> 3})\x0a\x09\x09equals: 5",
@@ -443,7 +443,7 @@ category: 'tests',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self._assert_equals_(self._interpret_receiver_withArguments_("foo ^ x",(2).__at((3)),smalltalk.HashedCollection._fromPairs_([])),(2));
+self._assert_equals_(self._interpret_receiver_withArguments_("foo ^ x",(2).__at((3)),smalltalk.HashedCollection._from_([])),(2));
 return self}, function($ctx1) {$ctx1.fill(self,"testInstVarAccess",{},smalltalk.ASTInterpreterTest)})},
 args: [],
 source: "testInstVarAccess\x0a\x09self\x0a\x09\x09assert: (self\x0a\x09\x09\x09interpret: 'foo ^ x'\x0a\x09\x09\x09receiver: 2@3\x0a\x09\x09\x09withArguments: #{})\x0a\x09\x09equals: 2",
@@ -460,7 +460,7 @@ fn: function (){
 var self=this;
 function $Point(){return smalltalk.Point||(typeof Point=="undefined"?nil:Point)}
 return smalltalk.withContext(function($ctx1) { 
-self._assert_equals_(self._interpret_receiver_withArguments_("foo: anInteger x := anInteger. ^ x",_st($Point())._new(),smalltalk.HashedCollection._fromPairs_(["anInteger".__minus_gt((2))])),(2));
+self._assert_equals_(self._interpret_receiver_withArguments_("foo: anInteger x := anInteger. ^ x",_st($Point())._new(),smalltalk.HashedCollection._from_(["anInteger".__minus_gt((2))])),(2));
 return self}, function($ctx1) {$ctx1.fill(self,"testInstVarAssignment",{},smalltalk.ASTInterpreterTest)})},
 args: [],
 source: "testInstVarAssignment\x0a\x09self\x0a\x09\x09assert: (self\x0a\x09\x09\x09interpret: 'foo: anInteger x := anInteger. ^ x'\x0a\x09\x09\x09receiver: Point new\x0a\x09\x09\x09withArguments: #{'anInteger' -> 2})\x0a\x09\x09equals: 2",
@@ -492,7 +492,7 @@ category: 'tests',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self._assert_equals_(self._interpret_receiver_withArguments_("foo ^ self",(2).__at((3)),smalltalk.HashedCollection._fromPairs_([])),(2).__at((3)));
+self._assert_equals_(self._interpret_receiver_withArguments_("foo ^ self",(2).__at((3)),smalltalk.HashedCollection._from_([])),(2).__at((3)));
 return self}, function($ctx1) {$ctx1.fill(self,"testReceiver",{},smalltalk.ASTInterpreterTest)})},
 args: [],
 source: "testReceiver\x0a\x09self\x0a\x09\x09assert: (self\x0a\x09\x09\x09interpret: 'foo ^ self'\x0a\x09\x09\x09receiver: 2@3\x0a\x09\x09\x09withArguments: #{})\x0a\x09\x09equals: 2@3",
@@ -1205,7 +1205,7 @@ category: 'tests',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self._should_return_("foo\x0a\x09| x |\x0a\x09x := 'foo'->1.\x0a\x09^ #{ x. (true ifTrue: [ x := 'bar'->2 ]) }\x0a",smalltalk.HashedCollection._fromPairs_(["foo".__minus_gt((1)),"bar".__minus_gt((2))]));
+self._should_return_("foo\x0a\x09| x |\x0a\x09x := 'foo'->1.\x0a\x09^ #{ x. (true ifTrue: [ x := 'bar'->2 ]) }\x0a",smalltalk.HashedCollection._from_(["foo".__minus_gt((1)),"bar".__minus_gt((2))]));
 return self}, function($ctx1) {$ctx1.fill(self,"testDynamicDictionaryElementsOrdered",{},smalltalk.CodeGeneratorTest)})},
 args: [],
 source: "testDynamicDictionaryElementsOrdered\x0a\x09self should: 'foo\x0a\x09| x |\x0a\x09x := ''foo''->1.\x0a\x09^ #{ x. (true ifTrue: [ x := ''bar''->2 ]) }\x0a' return: #{'foo'->1. 'bar'->2}.",
@@ -1225,7 +1225,7 @@ return smalltalk.withContext(function($ctx1) {
 self._should_return_("foo\x0a\x09| x |\x0a\x09x := Array.\x0a\x09^ x with: 'foo'->x with: 'bar'->(true ifTrue: [ x := 2 ])\x0a",["foo".__minus_gt($Array()),"bar".__minus_gt((2))]);
 self._should_return_("foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ Array with: 'foo'->x with: 'bar'->(true ifTrue: [ x := 2 ])\x0a",["foo".__minus_gt((1)),"bar".__minus_gt((2))]);
 self._should_return_("foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ { 'foo'->x. 'bar'->(true ifTrue: [ x := 2 ]) }\x0a",["foo".__minus_gt((1)),"bar".__minus_gt((2))]);
-self._should_return_("foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ #{ 'foo'->x. 'bar'->(true ifTrue: [ x := 2 ]) }\x0a",smalltalk.HashedCollection._fromPairs_(["foo".__minus_gt((1)),"bar".__minus_gt((2))]));
+self._should_return_("foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ #{ 'foo'->x. 'bar'->(true ifTrue: [ x := 2 ]) }\x0a",smalltalk.HashedCollection._from_(["foo".__minus_gt((1)),"bar".__minus_gt((2))]));
 return self}, function($ctx1) {$ctx1.fill(self,"testInnerTemporalDependentElementsOrdered",{},smalltalk.CodeGeneratorTest)})},
 args: [],
 source: "testInnerTemporalDependentElementsOrdered\x0a\x09self should: 'foo\x0a\x09| x |\x0a\x09x := Array.\x0a\x09^ x with: ''foo''->x with: ''bar''->(true ifTrue: [ x := 2 ])\x0a' return: {'foo'->Array. 'bar'->2}.\x0a\x09self should: 'foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ Array with: ''foo''->x with: ''bar''->(true ifTrue: [ x := 2 ])\x0a' return: {'foo'->1. 'bar'->2}.\x0a\x09self should: 'foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ { ''foo''->x. ''bar''->(true ifTrue: [ x := 2 ]) }\x0a' return: {'foo'->1. 'bar'->2}.\x0a\x09self should: 'foo\x0a\x09| x |\x0a\x09x := 1.\x0a\x09^ #{ ''foo''->x. ''bar''->(true ifTrue: [ x := 2 ]) }\x0a' return: #{'foo'->1. 'bar'->2}.",
@@ -1247,7 +1247,7 @@ self._should_return_("foo ^ #(1 2 3 4)",[(1), (2), (3), (4)]);
 self._should_return_("foo ^ {1. [:x | x ] value: 2. 3. [4] value}",[(1), (2), (3), (4)]);
 self._should_return_("foo ^ true",true);
 self._should_return_("foo ^ false",false);
-self._should_return_("foo ^ #{1->2. 3->4}",smalltalk.HashedCollection._fromPairs_([(1).__minus_gt((2)),(3).__minus_gt((4))]));
+self._should_return_("foo ^ #{1->2. 3->4}",smalltalk.HashedCollection._from_([(1).__minus_gt((2)),(3).__minus_gt((4))]));
 self._should_return_("foo ^ #hello","hello");
 self._should_return_("foo ^ -123.456",(-123.456));
 return self}, function($ctx1) {$ctx1.fill(self,"testLiterals",{},smalltalk.CodeGeneratorTest)})},

+ 41 - 101
js/Helios-Core.deploy.js

@@ -1153,6 +1153,20 @@ return self}, function($ctx1) {$ctx1.fill(self,"alert:",{aString:aString},smallt
 messageSends: ["alert:"]}),
 smalltalk.HLWidget);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "bindKeyDown:up:",
+fn: function (keyDownBlock,keyUpBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st(self._wrapper())._asJQuery();
+_st($1)._keydown_(keyDownBlock);
+$2=_st($1)._keyup_(keyUpBlock);
+return self}, function($ctx1) {$ctx1.fill(self,"bindKeyDown:up:",{keyDownBlock:keyDownBlock,keyUpBlock:keyUpBlock},smalltalk.HLWidget)})},
+messageSends: ["keydown:", "asJQuery", "wrapper", "keyup:"]}),
+smalltalk.HLWidget);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "canHaveFocus",
@@ -1321,6 +1335,20 @@ return $1;
 messageSends: ["tabClass", "class"]}),
 smalltalk.HLWidget);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "unbindKeyDownUp",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st(self._wrapper())._asJQuery();
+_st($1)._unbind_("keydown");
+$2=_st($1)._unbind_("keyup");
+return self}, function($ctx1) {$ctx1.fill(self,"unbindKeyDownUp",{},smalltalk.HLWidget)})},
+messageSends: ["unbind:", "asJQuery", "wrapper"]}),
+smalltalk.HLWidget);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "unregister",
@@ -1457,11 +1485,11 @@ return smalltalk.withContext(function($ctx1) {
 var $1;
 $1=_st(_st(self._wrapper())._notNil())._and_((function(){
 return smalltalk.withContext(function($ctx2) {
-return _st(_st(self._wrapper())._asJQuery())._is_(":focus");
+return _st(_st(self._wrapper())._asJQuery())._hasClass_(self._focusClass());
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"hasFocus",{},smalltalk.HLFocusableWidget)})},
-messageSends: ["and:", "is:", "asJQuery", "wrapper", "notNil"]}),
+messageSends: ["and:", "hasClass:", "focusClass", "asJQuery", "wrapper", "notNil"]}),
 smalltalk.HLFocusableWidget);
 
 smalltalk.addMethod(
@@ -1895,109 +1923,21 @@ smalltalk.method({
 selector: "setupKeyBindings",
 fn: function (){
 var self=this;
-var active,interval,delay,repeatInterval;
+function $HLRepeatingKeyBindingHandler(){return smalltalk.HLRepeatingKeyBindingHandler||(typeof HLRepeatingKeyBindingHandler=="undefined"?nil:HLRepeatingKeyBindingHandler)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11;
-active=false;
-repeatInterval=(70);
-_st(_st(self._wrapper())._asJQuery())._unbind_("keydown");
-_st(_st(self._wrapper())._asJQuery())._keydown_((function(e){
+var $1,$2;
+$1=_st($HLRepeatingKeyBindingHandler())._forWidget_(self);
+_st($1)._whileKeyPressed_do_((38),(function(){
 return smalltalk.withContext(function($ctx2) {
-$1=_st(_st(_st(e)._which()).__eq((38)))._and_((function(){
-return smalltalk.withContext(function($ctx3) {
-return _st(active).__eq(false);
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}));
-if(smalltalk.assert($1)){
-active=true;
-active;
-self._activatePreviousListItem();
-delay=_st((function(){
-return smalltalk.withContext(function($ctx3) {
-interval=_st((function(){
-return smalltalk.withContext(function($ctx4) {
-$2=_st(_st(self._wrapper())._asJQuery())._hasClass_(self._focusClass());
-if(smalltalk.assert($2)){
 return self._activatePreviousListItem();
-} else {
-active=false;
-active;
-$3=interval;
-if(($receiver = $3) == nil || $receiver == undefined){
-$3;
-} else {
-_st(interval)._clearInterval();
-};
-$4=delay;
-if(($receiver = $4) == nil || $receiver == undefined){
-return $4;
-} else {
-return _st(delay)._clearTimeout();
-};
-};
-}, function($ctx4) {$ctx4.fillBlock({},$ctx3)})}))._valueWithInterval_(repeatInterval);
-return interval;
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}))._valueWithTimeout_((300));
-delay;
-};
-$5=_st(_st(_st(e)._which()).__eq((40)))._and_((function(){
-return smalltalk.withContext(function($ctx3) {
-return _st(active).__eq(false);
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}));
-if(smalltalk.assert($5)){
-active=true;
-active;
-self._activateNextListItem();
-delay=_st((function(){
-return smalltalk.withContext(function($ctx3) {
-interval=_st((function(){
-return smalltalk.withContext(function($ctx4) {
-$6=_st(_st(self._wrapper())._asJQuery())._hasClass_(self._focusClass());
-if(smalltalk.assert($6)){
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st($1)._whileKeyPressed_do_((40),(function(){
+return smalltalk.withContext(function($ctx2) {
 return self._activateNextListItem();
-} else {
-active=false;
-active;
-$7=interval;
-if(($receiver = $7) == nil || $receiver == undefined){
-$7;
-} else {
-_st(interval)._clearInterval();
-};
-$8=delay;
-if(($receiver = $8) == nil || $receiver == undefined){
-return $8;
-} else {
-return _st(delay)._clearTimeout();
-};
-};
-}, function($ctx4) {$ctx4.fillBlock({},$ctx3)})}))._valueWithInterval_(repeatInterval);
-return interval;
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}))._valueWithTimeout_((300));
-return delay;
-};
-}, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}));
-_st(_st(self._wrapper())._asJQuery())._keyup_((function(e){
-return smalltalk.withContext(function($ctx2) {
-$9=active;
-if(smalltalk.assert($9)){
-active=false;
-active;
-$10=interval;
-if(($receiver = $10) == nil || $receiver == undefined){
-$10;
-} else {
-_st(interval)._clearInterval();
-};
-$11=delay;
-if(($receiver = $11) == nil || $receiver == undefined){
-return $11;
-} else {
-return _st(delay)._clearTimeout();
-};
-};
-}, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"setupKeyBindings",{active:active,interval:interval,delay:delay,repeatInterval:repeatInterval},smalltalk.HLListWidget)})},
-messageSends: ["unbind:", "asJQuery", "wrapper", "keydown:", "ifTrue:", "activatePreviousListItem", "valueWithTimeout:", "valueWithInterval:", "ifTrue:ifFalse:", "ifNotNil:", "clearInterval", "clearTimeout", "hasClass:", "focusClass", "and:", "=", "which", "activateNextListItem", "keyup:"]}),
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$2=_st($1)._rebindKeys();
+return self}, function($ctx1) {$ctx1.fill(self,"setupKeyBindings",{},smalltalk.HLListWidget)})},
+messageSends: ["whileKeyPressed:do:", "activatePreviousListItem", "forWidget:", "activateNextListItem", "rebindKeys"]}),
 smalltalk.HLListWidget);
 
 

+ 55 - 105
js/Helios-Core.js

@@ -1513,6 +1513,25 @@ referencedClasses: []
 }),
 smalltalk.HLWidget);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "bindKeyDown:up:",
+category: 'keybindings',
+fn: function (keyDownBlock,keyUpBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st(self._wrapper())._asJQuery();
+_st($1)._keydown_(keyDownBlock);
+$2=_st($1)._keyup_(keyUpBlock);
+return self}, function($ctx1) {$ctx1.fill(self,"bindKeyDown:up:",{keyDownBlock:keyDownBlock,keyUpBlock:keyUpBlock},smalltalk.HLWidget)})},
+args: ["keyDownBlock", "keyUpBlock"],
+source: "bindKeyDown: keyDownBlock up: keyUpBlock\x0a\x09self wrapper asJQuery\x0a\x09\x09keydown: keyDownBlock;\x0a\x09\x09keyup: keyUpBlock ",
+messageSends: ["keydown:", "asJQuery", "wrapper", "keyup:"],
+referencedClasses: []
+}),
+smalltalk.HLWidget);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "canHaveFocus",
@@ -1746,6 +1765,25 @@ referencedClasses: []
 }),
 smalltalk.HLWidget);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "unbindKeyDownUp",
+category: 'keybindings',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st(self._wrapper())._asJQuery();
+_st($1)._unbind_("keydown");
+$2=_st($1)._unbind_("keyup");
+return self}, function($ctx1) {$ctx1.fill(self,"unbindKeyDownUp",{},smalltalk.HLWidget)})},
+args: [],
+source: "unbindKeyDownUp\x0a\x09self wrapper asJQuery\x0a\x09\x09unbind: 'keydown';\x0a\x09\x09unbind: 'keyup'",
+messageSends: ["unbind:", "asJQuery", "wrapper"],
+referencedClasses: []
+}),
+smalltalk.HLWidget);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "unregister",
@@ -1932,20 +1970,20 @@ smalltalk.HLFocusableWidget);
 smalltalk.addMethod(
 smalltalk.method({
 selector: "hasFocus",
-category: 'events',
+category: 'testing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
 $1=_st(_st(self._wrapper())._notNil())._and_((function(){
 return smalltalk.withContext(function($ctx2) {
-return _st(_st(self._wrapper())._asJQuery())._is_(":focus");
+return _st(_st(self._wrapper())._asJQuery())._hasClass_(self._focusClass());
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"hasFocus",{},smalltalk.HLFocusableWidget)})},
 args: [],
-source: "hasFocus\x0a\x09^ self wrapper notNil and: [ self wrapper asJQuery is: ':focus' ]",
-messageSends: ["and:", "is:", "asJQuery", "wrapper", "notNil"],
+source: "hasFocus\x0a\x09^ self wrapper notNil and: [ self wrapper asJQuery hasClass: self focusClass ]",
+messageSends: ["and:", "hasClass:", "focusClass", "asJQuery", "wrapper", "notNil"],
 referencedClasses: []
 }),
 smalltalk.HLFocusableWidget);
@@ -2512,112 +2550,24 @@ selector: "setupKeyBindings",
 category: 'events',
 fn: function (){
 var self=this;
-var active,interval,delay,repeatInterval;
+function $HLRepeatingKeyBindingHandler(){return smalltalk.HLRepeatingKeyBindingHandler||(typeof HLRepeatingKeyBindingHandler=="undefined"?nil:HLRepeatingKeyBindingHandler)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11;
-active=false;
-repeatInterval=(70);
-_st(_st(self._wrapper())._asJQuery())._unbind_("keydown");
-_st(_st(self._wrapper())._asJQuery())._keydown_((function(e){
+var $1,$2;
+$1=_st($HLRepeatingKeyBindingHandler())._forWidget_(self);
+_st($1)._whileKeyPressed_do_((38),(function(){
 return smalltalk.withContext(function($ctx2) {
-$1=_st(_st(_st(e)._which()).__eq((38)))._and_((function(){
-return smalltalk.withContext(function($ctx3) {
-return _st(active).__eq(false);
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}));
-if(smalltalk.assert($1)){
-active=true;
-active;
-self._activatePreviousListItem();
-delay=_st((function(){
-return smalltalk.withContext(function($ctx3) {
-interval=_st((function(){
-return smalltalk.withContext(function($ctx4) {
-$2=_st(_st(self._wrapper())._asJQuery())._hasClass_(self._focusClass());
-if(smalltalk.assert($2)){
 return self._activatePreviousListItem();
-} else {
-active=false;
-active;
-$3=interval;
-if(($receiver = $3) == nil || $receiver == undefined){
-$3;
-} else {
-_st(interval)._clearInterval();
-};
-$4=delay;
-if(($receiver = $4) == nil || $receiver == undefined){
-return $4;
-} else {
-return _st(delay)._clearTimeout();
-};
-};
-}, function($ctx4) {$ctx4.fillBlock({},$ctx3)})}))._valueWithInterval_(repeatInterval);
-return interval;
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}))._valueWithTimeout_((300));
-delay;
-};
-$5=_st(_st(_st(e)._which()).__eq((40)))._and_((function(){
-return smalltalk.withContext(function($ctx3) {
-return _st(active).__eq(false);
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}));
-if(smalltalk.assert($5)){
-active=true;
-active;
-self._activateNextListItem();
-delay=_st((function(){
-return smalltalk.withContext(function($ctx3) {
-interval=_st((function(){
-return smalltalk.withContext(function($ctx4) {
-$6=_st(_st(self._wrapper())._asJQuery())._hasClass_(self._focusClass());
-if(smalltalk.assert($6)){
-return self._activateNextListItem();
-} else {
-active=false;
-active;
-$7=interval;
-if(($receiver = $7) == nil || $receiver == undefined){
-$7;
-} else {
-_st(interval)._clearInterval();
-};
-$8=delay;
-if(($receiver = $8) == nil || $receiver == undefined){
-return $8;
-} else {
-return _st(delay)._clearTimeout();
-};
-};
-}, function($ctx4) {$ctx4.fillBlock({},$ctx3)})}))._valueWithInterval_(repeatInterval);
-return interval;
-}, function($ctx3) {$ctx3.fillBlock({},$ctx2)})}))._valueWithTimeout_((300));
-return delay;
-};
-}, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}));
-_st(_st(self._wrapper())._asJQuery())._keyup_((function(e){
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st($1)._whileKeyPressed_do_((40),(function(){
 return smalltalk.withContext(function($ctx2) {
-$9=active;
-if(smalltalk.assert($9)){
-active=false;
-active;
-$10=interval;
-if(($receiver = $10) == nil || $receiver == undefined){
-$10;
-} else {
-_st(interval)._clearInterval();
-};
-$11=delay;
-if(($receiver = $11) == nil || $receiver == undefined){
-return $11;
-} else {
-return _st(delay)._clearTimeout();
-};
-};
-}, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"setupKeyBindings",{active:active,interval:interval,delay:delay,repeatInterval:repeatInterval},smalltalk.HLListWidget)})},
+return self._activateNextListItem();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$2=_st($1)._rebindKeys();
+return self}, function($ctx1) {$ctx1.fill(self,"setupKeyBindings",{},smalltalk.HLListWidget)})},
 args: [],
-source: "setupKeyBindings\x0a\x09\x22TODO: refactor this!\x22\x0a\x09\x0a\x09| active interval delay repeatInterval |\x0a\x09\x0a\x09active := false.\x0a\x09repeatInterval := 70.\x0a\x09self wrapper asJQuery unbind: 'keydown'.\x0a\x0a\x09self wrapper asJQuery keydown: [ :e |\x0a\x09\x09\x0a        (e which = 38 and: [ active = false ]) ifTrue: [ \x0a\x09\x09\x09active := true.\x0a\x09\x09\x09self activatePreviousListItem.\x0a        \x09delay := [\x0a\x09\x09\x09\x09interval := [\x0a\x09\x09\x09\x09\x09(self wrapper asJQuery hasClass: self focusClass)\x0a\x09\x09\x09\x09\x09\x09ifTrue: [\x0a\x09\x09\x09\x09\x09\x09\x09self activatePreviousListItem ]\x0a\x09\x09\x09\x09\x09\x09ifFalse: [\x0a\x09\x09\x09\x09\x09\x09\x09active := false.\x0a\x09\x09\x09\x09\x09\x09\x09interval ifNotNil: [ interval clearInterval ].\x0a\x09\x09\x09\x09\x09\x09\x09delay ifNotNil: [ delay clearTimeout] ] ]\x0a\x09\x09\x09\x09\x09valueWithInterval: repeatInterval ]\x0a\x09\x09\x09\x09\x09\x09valueWithTimeout: 300 ].\x0a\x09\x09\x09\x0a      \x09(e which = 40 and: [ active = false ]) ifTrue: [\x0a            active := true.\x0a\x09\x09\x09self activateNextListItem.\x0a        \x09delay := [\x0a\x09\x09\x09\x09interval := [ \x0a\x09\x09\x09\x09\x09(self wrapper asJQuery hasClass: self focusClass)\x0a\x09\x09\x09\x09\x09\x09ifTrue: [\x0a\x09\x09\x09\x09\x09\x09\x09self activateNextListItem ]\x0a\x09\x09\x09\x09\x09\x09ifFalse: [\x0a\x09\x09\x09\x09\x09\x09\x09active := false.\x0a\x09\x09\x09\x09\x09\x09\x09interval ifNotNil: [ interval clearInterval ].\x0a\x09\x09\x09\x09\x09\x09\x09delay ifNotNil: [ delay clearTimeout] ] ]\x0a\x09\x09\x09\x09\x09valueWithInterval: repeatInterval ]\x0a\x09\x09\x09\x09\x09\x09valueWithTimeout: 300 ] ].\x0a\x09\x0a\x09self wrapper asJQuery keyup: [ :e |\x0a\x09\x09active ifTrue: [\x0a\x09\x09\x09active := false.\x0a\x09\x09\x09interval ifNotNil: [ interval clearInterval ].\x0a\x09\x09\x09delay ifNotNil: [ delay clearTimeout] ] ]",
-messageSends: ["unbind:", "asJQuery", "wrapper", "keydown:", "ifTrue:", "activatePreviousListItem", "valueWithTimeout:", "valueWithInterval:", "ifTrue:ifFalse:", "ifNotNil:", "clearInterval", "clearTimeout", "hasClass:", "focusClass", "and:", "=", "which", "activateNextListItem", "keyup:"],
-referencedClasses: []
+source: "setupKeyBindings \x0a\x09(HLRepeatingKeyBindingHandler forWidget: self)\x0a\x09\x09whileKeyPressed: 38 do: [ self activatePreviousListItem ];\x0a\x09\x09whileKeyPressed: 40 do: [ self activateNextListItem ];\x0a\x09\x09rebindKeys",
+messageSends: ["whileKeyPressed:do:", "activatePreviousListItem", "forWidget:", "activateNextListItem", "rebindKeys"],
+referencedClasses: ["HLRepeatingKeyBindingHandler"]
 }),
 smalltalk.HLListWidget);
 

+ 2 - 2
js/Helios-Debugger.deploy.js

@@ -360,8 +360,8 @@ fn: function (){
 var self=this;
 var anchor,head,selection;
 return smalltalk.withContext(function($ctx1) { 
-head=smalltalk.HashedCollection._fromPairs_(["line".__minus_gt(_st(_st(_st(self._highlightedNode())._position())._x()).__minus((1))),"ch".__minus_gt(_st(_st(_st(self._highlightedNode())._position())._y()).__minus((1)))]);
-anchor=smalltalk.HashedCollection._fromPairs_(["line".__minus_gt(_st(_st(_st(self._highlightedNode())._extent())._x()).__minus((1))),"ch".__minus_gt(_st(_st(_st(self._highlightedNode())._extent())._y()).__minus((1)))]);
+head=smalltalk.HashedCollection._from_(["line".__minus_gt(_st(_st(_st(self._highlightedNode())._position())._x()).__minus((1))),"ch".__minus_gt(_st(_st(_st(self._highlightedNode())._position())._y()).__minus((1)))]);
+anchor=smalltalk.HashedCollection._from_(["line".__minus_gt(_st(_st(_st(self._highlightedNode())._extent())._x()).__minus((1))),"ch".__minus_gt(_st(_st(_st(self._highlightedNode())._extent())._y()).__minus((1)))]);
 _st(self["@editor"])._setSelection_to_(head,anchor);
 return self}, function($ctx1) {$ctx1.fill(self,"highlight",{anchor:anchor,head:head,selection:selection},smalltalk.HLDebuggerCodeWidget)})},
 messageSends: ["->", "-", "x", "position", "highlightedNode", "y", "extent", "setSelection:to:"]}),

+ 2 - 2
js/Helios-Debugger.js

@@ -472,8 +472,8 @@ fn: function (){
 var self=this;
 var anchor,head,selection;
 return smalltalk.withContext(function($ctx1) { 
-head=smalltalk.HashedCollection._fromPairs_(["line".__minus_gt(_st(_st(_st(self._highlightedNode())._position())._x()).__minus((1))),"ch".__minus_gt(_st(_st(_st(self._highlightedNode())._position())._y()).__minus((1)))]);
-anchor=smalltalk.HashedCollection._fromPairs_(["line".__minus_gt(_st(_st(_st(self._highlightedNode())._extent())._x()).__minus((1))),"ch".__minus_gt(_st(_st(_st(self._highlightedNode())._extent())._y()).__minus((1)))]);
+head=smalltalk.HashedCollection._from_(["line".__minus_gt(_st(_st(_st(self._highlightedNode())._position())._x()).__minus((1))),"ch".__minus_gt(_st(_st(_st(self._highlightedNode())._position())._y()).__minus((1)))]);
+anchor=smalltalk.HashedCollection._from_(["line".__minus_gt(_st(_st(_st(self._highlightedNode())._extent())._x()).__minus((1))),"ch".__minus_gt(_st(_st(_st(self._highlightedNode())._extent())._y()).__minus((1)))]);
 _st(self["@editor"])._setSelection_to_(head,anchor);
 return self}, function($ctx1) {$ctx1.fill(self,"highlight",{anchor:anchor,head:head,selection:selection},smalltalk.HLDebuggerCodeWidget)})},
 args: [],

+ 232 - 1
js/Helios-KeyBindings.deploy.js

@@ -811,7 +811,7 @@ _st($4)._value_(self._defaultValue());
 $5=_st($4)._yourself();
 self["@input"]=$5;
 self["@input"];
-_st(_st(self["@input"])._asJQuery())._typeahead_(smalltalk.HashedCollection._fromPairs_(["source".__minus_gt(self._inputCompletion())]));
+_st(_st(self["@input"])._asJQuery())._typeahead_(smalltalk.HashedCollection._from_(["source".__minus_gt(self._inputCompletion())]));
 $6=_st(html)._span();
 _st($6)._class_("help-inline");
 _st($6)._with_(self._message());
@@ -1457,3 +1457,234 @@ messageSends: ["keyBinder:", "new", "yourself"]}),
 smalltalk.HLKeyBinderHelper.klass);
 
 
+smalltalk.addClass('HLRepeatingKeyBindingHandler', smalltalk.Object, ['repeatInterval', 'delay', 'interval', 'keyBindings', 'widget', 'isKeyCurrentlyPressed'], 'Helios-KeyBindings');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "bindKeys",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@widget"])._bindKeyDown_up_((function(e){
+return smalltalk.withContext(function($ctx2) {
+return self._handleKeyDown_(e);
+}, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}),(function(e){
+return smalltalk.withContext(function($ctx2) {
+return self._handleKeyUp_(e);
+}, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"bindKeys",{},smalltalk.HLRepeatingKeyBindingHandler)})},
+messageSends: ["bindKeyDown:up:", "handleKeyDown:", "handleKeyUp:"]}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "delayBeforeStartingRepeatWithAction:",
+fn: function (action){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st((function(){
+return smalltalk.withContext(function($ctx2) {
+self["@interval"]=self._startRepeatingAction_(action);
+return self["@interval"];
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._valueWithTimeout_((300));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"delayBeforeStartingRepeatWithAction:",{action:action},smalltalk.HLRepeatingKeyBindingHandler)})},
+messageSends: ["valueWithTimeout:", "startRepeatingAction:"]}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "handleKeyDown:",
+fn: function (e){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@keyBindings"])._keysAndValuesDo_((function(key,action){
+return smalltalk.withContext(function($ctx2) {
+return self._ifKey_wasPressedIn_thenDo_(key,e,action);
+}, function($ctx2) {$ctx2.fillBlock({key:key,action:action},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"handleKeyDown:",{e:e},smalltalk.HLRepeatingKeyBindingHandler)})},
+messageSends: ["keysAndValuesDo:", "ifKey:wasPressedIn:thenDo:"]}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "handleKeyUp",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+self["@isKeyCurrentlyPressed"]=false;
+$1=self["@interval"];
+if(($receiver = $1) == nil || $receiver == undefined){
+$1;
+} else {
+_st(self["@interval"])._clearInterval();
+};
+$2=self["@delay"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$2;
+} else {
+_st(self["@delay"])._clearTimeout();
+};
+return self}, function($ctx1) {$ctx1.fill(self,"handleKeyUp",{},smalltalk.HLRepeatingKeyBindingHandler)})},
+messageSends: ["ifNotNil:", "clearInterval", "clearTimeout"]}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "handleKeyUp:",
+fn: function (e){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@isKeyCurrentlyPressed"];
+if(smalltalk.assert($1)){
+self._handleKeyUp();
+};
+return self}, function($ctx1) {$ctx1.fill(self,"handleKeyUp:",{e:e},smalltalk.HLRepeatingKeyBindingHandler)})},
+messageSends: ["ifTrue:", "handleKeyUp"]}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "ifKey:wasPressedIn:thenDo:",
+fn: function (key,e,action){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(_st(_st(e)._which()).__eq(key))._and_((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(self["@isKeyCurrentlyPressed"]).__eq(false);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+if(smalltalk.assert($1)){
+self._whileTheKeyIsPressedDo_(action);
+};
+return self}, function($ctx1) {$ctx1.fill(self,"ifKey:wasPressedIn:thenDo:",{key:key,e:e,action:action},smalltalk.HLRepeatingKeyBindingHandler)})},
+messageSends: ["ifTrue:", "whileTheKeyIsPressedDo:", "and:", "=", "which"]}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initialize",
+fn: function (){
+var self=this;
+function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
+return smalltalk.withContext(function($ctx1) { 
+smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+self["@keyBindings"]=_st($Dictionary())._new();
+self["@isKeyCurrentlyPressed"]=false;
+self["@repeatInterval"]=(70);
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLRepeatingKeyBindingHandler)})},
+messageSends: ["initialize", "new"]}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "rebindKeys",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=self;
+_st($1)._unbindKeys();
+$2=_st($1)._bindKeys();
+return self}, function($ctx1) {$ctx1.fill(self,"rebindKeys",{},smalltalk.HLRepeatingKeyBindingHandler)})},
+messageSends: ["unbindKeys", "bindKeys"]}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "repeatInterval:",
+fn: function (aMillisecondIntegerValue){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@repeatInterval"]=aMillisecondIntegerValue;
+return self}, function($ctx1) {$ctx1.fill(self,"repeatInterval:",{aMillisecondIntegerValue:aMillisecondIntegerValue},smalltalk.HLRepeatingKeyBindingHandler)})},
+messageSends: []}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "startRepeatingAction:",
+fn: function (action){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$1=_st((function(){
+return smalltalk.withContext(function($ctx2) {
+$2=_st(self["@widget"])._hasFocus();
+if(smalltalk.assert($2)){
+return _st(action)._value();
+} else {
+return self._handleKeyUp();
+};
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._valueWithInterval_(self["@repeatInterval"]);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"startRepeatingAction:",{action:action},smalltalk.HLRepeatingKeyBindingHandler)})},
+messageSends: ["valueWithInterval:", "ifTrue:ifFalse:", "value", "handleKeyUp", "hasFocus"]}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "unbindKeys",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@widget"])._unbindKeyDownUp();
+return self}, function($ctx1) {$ctx1.fill(self,"unbindKeys",{},smalltalk.HLRepeatingKeyBindingHandler)})},
+messageSends: ["unbindKeyDownUp"]}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "whileKeyPressed:do:",
+fn: function (aKey,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@keyBindings"])._at_put_(aKey,aBlock);
+return self}, function($ctx1) {$ctx1.fill(self,"whileKeyPressed:do:",{aKey:aKey,aBlock:aBlock},smalltalk.HLRepeatingKeyBindingHandler)})},
+messageSends: ["at:put:"]}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "whileTheKeyIsPressedDo:",
+fn: function (action){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@isKeyCurrentlyPressed"]=true;
+_st(action)._value();
+self["@delay"]=self._delayBeforeStartingRepeatWithAction_(action);
+return self}, function($ctx1) {$ctx1.fill(self,"whileTheKeyIsPressedDo:",{action:action},smalltalk.HLRepeatingKeyBindingHandler)})},
+messageSends: ["value", "delayBeforeStartingRepeatWithAction:"]}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "widget:",
+fn: function (aWidget){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@widget"]=aWidget;
+return self}, function($ctx1) {$ctx1.fill(self,"widget:",{aWidget:aWidget},smalltalk.HLRepeatingKeyBindingHandler)})},
+messageSends: []}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "forWidget:",
+fn: function (aWidget){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$1;
+$2=self._new();
+_st($2)._widget_(aWidget);
+$3=_st($2)._yourself();
+$1=$3;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"forWidget:",{aWidget:aWidget},smalltalk.HLRepeatingKeyBindingHandler.klass)})},
+messageSends: ["widget:", "new", "yourself"]}),
+smalltalk.HLRepeatingKeyBindingHandler.klass);
+
+

+ 308 - 1
js/Helios-KeyBindings.js

@@ -1077,7 +1077,7 @@ _st($4)._value_(self._defaultValue());
 $5=_st($4)._yourself();
 self["@input"]=$5;
 self["@input"];
-_st(_st(self["@input"])._asJQuery())._typeahead_(smalltalk.HashedCollection._fromPairs_(["source".__minus_gt(self._inputCompletion())]));
+_st(_st(self["@input"])._asJQuery())._typeahead_(smalltalk.HashedCollection._from_(["source".__minus_gt(self._inputCompletion())]));
 $6=_st(html)._span();
 _st($6)._class_("help-inline");
 _st($6)._with_(self._message());
@@ -1922,3 +1922,310 @@ referencedClasses: []
 smalltalk.HLKeyBinderHelper.klass);
 
 
+smalltalk.addClass('HLRepeatingKeyBindingHandler', smalltalk.Object, ['repeatInterval', 'delay', 'interval', 'keyBindings', 'widget', 'isKeyCurrentlyPressed'], 'Helios-KeyBindings');
+smalltalk.HLRepeatingKeyBindingHandler.comment="##Usage\x0a\x0a    (HLRepeatingKeyBindingHandler forWidget: aWidget)\x0a        whileKeyPressed: keyCode do: [xxxx];\x0a        whileKeyPressed: anotherKey do: [yyy];\x0a        rebind\x0a\x0aPerforms an action on a key press, waits for 300 ms and then preforms the action every repeatInterval ms until the button is released";
+smalltalk.addMethod(
+smalltalk.method({
+selector: "bindKeys",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@widget"])._bindKeyDown_up_((function(e){
+return smalltalk.withContext(function($ctx2) {
+return self._handleKeyDown_(e);
+}, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}),(function(e){
+return smalltalk.withContext(function($ctx2) {
+return self._handleKeyUp_(e);
+}, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"bindKeys",{},smalltalk.HLRepeatingKeyBindingHandler)})},
+args: [],
+source: "bindKeys\x0a\x09widget bindKeyDown: [ :e | self handleKeyDown: e ] up: [ :e | self handleKeyUp: e ]",
+messageSends: ["bindKeyDown:up:", "handleKeyDown:", "handleKeyUp:"],
+referencedClasses: []
+}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "delayBeforeStartingRepeatWithAction:",
+category: 'actions',
+fn: function (action){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st((function(){
+return smalltalk.withContext(function($ctx2) {
+self["@interval"]=self._startRepeatingAction_(action);
+return self["@interval"];
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._valueWithTimeout_((300));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"delayBeforeStartingRepeatWithAction:",{action:action},smalltalk.HLRepeatingKeyBindingHandler)})},
+args: ["action"],
+source: "delayBeforeStartingRepeatWithAction: action\x0a\x09^ [ interval := self startRepeatingAction: action ] valueWithTimeout: 300",
+messageSends: ["valueWithTimeout:", "startRepeatingAction:"],
+referencedClasses: []
+}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "handleKeyDown:",
+category: 'events-processing',
+fn: function (e){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@keyBindings"])._keysAndValuesDo_((function(key,action){
+return smalltalk.withContext(function($ctx2) {
+return self._ifKey_wasPressedIn_thenDo_(key,e,action);
+}, function($ctx2) {$ctx2.fillBlock({key:key,action:action},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"handleKeyDown:",{e:e},smalltalk.HLRepeatingKeyBindingHandler)})},
+args: ["e"],
+source: "handleKeyDown: e\x0a\x09 keyBindings keysAndValuesDo: [ :key :action | \x0a\x09\x09self ifKey: key wasPressedIn: e thenDo: action ]",
+messageSends: ["keysAndValuesDo:", "ifKey:wasPressedIn:thenDo:"],
+referencedClasses: []
+}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "handleKeyUp",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+self["@isKeyCurrentlyPressed"]=false;
+$1=self["@interval"];
+if(($receiver = $1) == nil || $receiver == undefined){
+$1;
+} else {
+_st(self["@interval"])._clearInterval();
+};
+$2=self["@delay"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$2;
+} else {
+_st(self["@delay"])._clearTimeout();
+};
+return self}, function($ctx1) {$ctx1.fill(self,"handleKeyUp",{},smalltalk.HLRepeatingKeyBindingHandler)})},
+args: [],
+source: "handleKeyUp\x0a\x09isKeyCurrentlyPressed := false.\x0a\x09interval ifNotNil: [ interval clearInterval ].\x0a\x09delay ifNotNil: [ delay clearTimeout ]",
+messageSends: ["ifNotNil:", "clearInterval", "clearTimeout"],
+referencedClasses: []
+}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "handleKeyUp:",
+category: 'events-processing',
+fn: function (e){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@isKeyCurrentlyPressed"];
+if(smalltalk.assert($1)){
+self._handleKeyUp();
+};
+return self}, function($ctx1) {$ctx1.fill(self,"handleKeyUp:",{e:e},smalltalk.HLRepeatingKeyBindingHandler)})},
+args: ["e"],
+source: "handleKeyUp: e\x0a\x09isKeyCurrentlyPressed\x0a\x09\x09ifTrue: [ self handleKeyUp ] ",
+messageSends: ["ifTrue:", "handleKeyUp"],
+referencedClasses: []
+}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "ifKey:wasPressedIn:thenDo:",
+category: 'events-processing',
+fn: function (key,e,action){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(_st(_st(e)._which()).__eq(key))._and_((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(self["@isKeyCurrentlyPressed"]).__eq(false);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+if(smalltalk.assert($1)){
+self._whileTheKeyIsPressedDo_(action);
+};
+return self}, function($ctx1) {$ctx1.fill(self,"ifKey:wasPressedIn:thenDo:",{key:key,e:e,action:action},smalltalk.HLRepeatingKeyBindingHandler)})},
+args: ["key", "e", "action"],
+source: "ifKey: key wasPressedIn: e thenDo: action\x0a\x09(e which = key and: [ isKeyCurrentlyPressed = false ])\x0a\x09\x09ifTrue: [  self whileTheKeyIsPressedDo: action ]",
+messageSends: ["ifTrue:", "whileTheKeyIsPressedDo:", "and:", "=", "which"],
+referencedClasses: []
+}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "initialize",
+category: 'initialization',
+fn: function (){
+var self=this;
+function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
+return smalltalk.withContext(function($ctx1) { 
+smalltalk.Object.fn.prototype._initialize.apply(_st(self), []);
+self["@keyBindings"]=_st($Dictionary())._new();
+self["@isKeyCurrentlyPressed"]=false;
+self["@repeatInterval"]=(70);
+return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLRepeatingKeyBindingHandler)})},
+args: [],
+source: "initialize \x0a\x09super initialize.\x0a\x09keyBindings := Dictionary new.\x0a\x09isKeyCurrentlyPressed := false.\x0a\x09repeatInterval := 70.",
+messageSends: ["initialize", "new"],
+referencedClasses: ["Dictionary"]
+}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "rebindKeys",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=self;
+_st($1)._unbindKeys();
+$2=_st($1)._bindKeys();
+return self}, function($ctx1) {$ctx1.fill(self,"rebindKeys",{},smalltalk.HLRepeatingKeyBindingHandler)})},
+args: [],
+source: "rebindKeys\x0a\x09self unbindKeys;\x0a\x09\x09bindKeys",
+messageSends: ["unbindKeys", "bindKeys"],
+referencedClasses: []
+}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "repeatInterval:",
+category: 'accessing',
+fn: function (aMillisecondIntegerValue){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@repeatInterval"]=aMillisecondIntegerValue;
+return self}, function($ctx1) {$ctx1.fill(self,"repeatInterval:",{aMillisecondIntegerValue:aMillisecondIntegerValue},smalltalk.HLRepeatingKeyBindingHandler)})},
+args: ["aMillisecondIntegerValue"],
+source: "repeatInterval: aMillisecondIntegerValue \x0a\x09repeatInterval := aMillisecondIntegerValue",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "startRepeatingAction:",
+category: 'actions',
+fn: function (action){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$1=_st((function(){
+return smalltalk.withContext(function($ctx2) {
+$2=_st(self["@widget"])._hasFocus();
+if(smalltalk.assert($2)){
+return _st(action)._value();
+} else {
+return self._handleKeyUp();
+};
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._valueWithInterval_(self["@repeatInterval"]);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"startRepeatingAction:",{action:action},smalltalk.HLRepeatingKeyBindingHandler)})},
+args: ["action"],
+source: "startRepeatingAction: action\x0a\x09^ [ (widget hasFocus)\x0a\x09\x09ifTrue: [ action value ]\x0a\x09\x09ifFalse: [ self handleKeyUp ] ] valueWithInterval: repeatInterval",
+messageSends: ["valueWithInterval:", "ifTrue:ifFalse:", "value", "handleKeyUp", "hasFocus"],
+referencedClasses: []
+}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "unbindKeys",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@widget"])._unbindKeyDownUp();
+return self}, function($ctx1) {$ctx1.fill(self,"unbindKeys",{},smalltalk.HLRepeatingKeyBindingHandler)})},
+args: [],
+source: "unbindKeys\x0a\x09widget unbindKeyDownUp",
+messageSends: ["unbindKeyDownUp"],
+referencedClasses: []
+}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "whileKeyPressed:do:",
+category: 'accessing',
+fn: function (aKey,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self["@keyBindings"])._at_put_(aKey,aBlock);
+return self}, function($ctx1) {$ctx1.fill(self,"whileKeyPressed:do:",{aKey:aKey,aBlock:aBlock},smalltalk.HLRepeatingKeyBindingHandler)})},
+args: ["aKey", "aBlock"],
+source: "whileKeyPressed: aKey do: aBlock\x0a\x09keyBindings at: aKey put: aBlock",
+messageSends: ["at:put:"],
+referencedClasses: []
+}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "whileTheKeyIsPressedDo:",
+category: 'events-processing',
+fn: function (action){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@isKeyCurrentlyPressed"]=true;
+_st(action)._value();
+self["@delay"]=self._delayBeforeStartingRepeatWithAction_(action);
+return self}, function($ctx1) {$ctx1.fill(self,"whileTheKeyIsPressedDo:",{action:action},smalltalk.HLRepeatingKeyBindingHandler)})},
+args: ["action"],
+source: "whileTheKeyIsPressedDo: action\x0a\x09isKeyCurrentlyPressed := true.\x0a\x09action value.\x0a\x09delay := self delayBeforeStartingRepeatWithAction: action",
+messageSends: ["value", "delayBeforeStartingRepeatWithAction:"],
+referencedClasses: []
+}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "widget:",
+category: 'accessing',
+fn: function (aWidget){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@widget"]=aWidget;
+return self}, function($ctx1) {$ctx1.fill(self,"widget:",{aWidget:aWidget},smalltalk.HLRepeatingKeyBindingHandler)})},
+args: ["aWidget"],
+source: "widget: aWidget\x0a\x09widget := aWidget",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLRepeatingKeyBindingHandler);
+
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "forWidget:",
+category: 'instance-creation',
+fn: function (aWidget){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$1;
+$2=self._new();
+_st($2)._widget_(aWidget);
+$3=_st($2)._yourself();
+$1=$3;
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"forWidget:",{aWidget:aWidget},smalltalk.HLRepeatingKeyBindingHandler.klass)})},
+args: ["aWidget"],
+source: "forWidget: aWidget\x0a\x09^self new\x0a\x09\x09widget: aWidget;\x0a\x09\x09yourself",
+messageSends: ["widget:", "new", "yourself"],
+referencedClasses: []
+}),
+smalltalk.HLRepeatingKeyBindingHandler.klass);
+
+

+ 2 - 2
js/Helios-Layout.deploy.js

@@ -269,7 +269,7 @@ selector: "setupSplitter",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(self["@splitter"])._asJQuery())._draggable_(smalltalk.HashedCollection._fromPairs_(["axis".__minus_gt("y"),"containment".__minus_gt(_st(_st(self["@splitter"])._asJQuery())._parent()),"helper".__minus_gt("clone"),"start".__minus_gt((function(e,ui){
+_st(_st(self["@splitter"])._asJQuery())._draggable_(smalltalk.HashedCollection._from_(["axis".__minus_gt("y"),"containment".__minus_gt(_st(_st(self["@splitter"])._asJQuery())._parent()),"helper".__minus_gt("clone"),"start".__minus_gt((function(e,ui){
 return smalltalk.withContext(function($ctx2) {
 return self._startResizing_(_st(ui)._helper());
 }, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1)})})),"drag".__minus_gt((function(e,ui){
@@ -356,7 +356,7 @@ selector: "setupSplitter",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(self["@splitter"])._asJQuery())._draggable_(smalltalk.HashedCollection._fromPairs_(["axis".__minus_gt("x"),"containment".__minus_gt(_st(_st(self["@splitter"])._asJQuery())._parent()),"helper".__minus_gt("clone"),"start".__minus_gt((function(e,ui){
+_st(_st(self["@splitter"])._asJQuery())._draggable_(smalltalk.HashedCollection._from_(["axis".__minus_gt("x"),"containment".__minus_gt(_st(_st(self["@splitter"])._asJQuery())._parent()),"helper".__minus_gt("clone"),"start".__minus_gt((function(e,ui){
 return smalltalk.withContext(function($ctx2) {
 return self._startResizing_(_st(ui)._helper());
 }, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1)})})),"drag".__minus_gt((function(e,ui){

+ 2 - 2
js/Helios-Layout.js

@@ -365,7 +365,7 @@ category: 'rendering',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(self["@splitter"])._asJQuery())._draggable_(smalltalk.HashedCollection._fromPairs_(["axis".__minus_gt("y"),"containment".__minus_gt(_st(_st(self["@splitter"])._asJQuery())._parent()),"helper".__minus_gt("clone"),"start".__minus_gt((function(e,ui){
+_st(_st(self["@splitter"])._asJQuery())._draggable_(smalltalk.HashedCollection._from_(["axis".__minus_gt("y"),"containment".__minus_gt(_st(_st(self["@splitter"])._asJQuery())._parent()),"helper".__minus_gt("clone"),"start".__minus_gt((function(e,ui){
 return smalltalk.withContext(function($ctx2) {
 return self._startResizing_(_st(ui)._helper());
 }, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1)})})),"drag".__minus_gt((function(e,ui){
@@ -482,7 +482,7 @@ category: 'rendering',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(_st(self["@splitter"])._asJQuery())._draggable_(smalltalk.HashedCollection._fromPairs_(["axis".__minus_gt("x"),"containment".__minus_gt(_st(_st(self["@splitter"])._asJQuery())._parent()),"helper".__minus_gt("clone"),"start".__minus_gt((function(e,ui){
+_st(_st(self["@splitter"])._asJQuery())._draggable_(smalltalk.HashedCollection._from_(["axis".__minus_gt("x"),"containment".__minus_gt(_st(_st(self["@splitter"])._asJQuery())._parent()),"helper".__minus_gt("clone"),"start".__minus_gt((function(e,ui){
 return smalltalk.withContext(function($ctx2) {
 return self._startResizing_(_st(ui)._helper());
 }, function($ctx2) {$ctx2.fillBlock({e:e,ui:ui},$ctx1)})})),"drag".__minus_gt((function(e,ui){

+ 2 - 2
js/Helios-Workspace-Tests.deploy.js

@@ -8,8 +8,8 @@ var self=this;
 function $HashedCollection(){return smalltalk.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
 function $HLCodeWidget(){return smalltalk.HLCodeWidget||(typeof HLCodeWidget=="undefined"?nil:HLCodeWidget)}
 return smalltalk.withContext(function($ctx1) { 
-_st(self)._assert_(_st(_st($HLCodeWidget())._pcKeyMap())._isKindOf_($HashedCollection()));
-_st(self)._assert_(_st(_st($HLCodeWidget())._macKeyMap())._isKindOf_($HashedCollection()));
+self._assert_(_st(_st($HLCodeWidget())._pcKeyMap())._isKindOf_($HashedCollection()));
+self._assert_(_st(_st($HLCodeWidget())._macKeyMap())._isKindOf_($HashedCollection()));
 return self}, function($ctx1) {$ctx1.fill(self,"testKeyMap",{},smalltalk.HLCodeWidgetTest)})},
 messageSends: ["assert:", "isKindOf:", "pcKeyMap", "macKeyMap"]}),
 smalltalk.HLCodeWidgetTest);

+ 2 - 2
js/Helios-Workspace-Tests.js

@@ -9,8 +9,8 @@ var self=this;
 function $HashedCollection(){return smalltalk.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
 function $HLCodeWidget(){return smalltalk.HLCodeWidget||(typeof HLCodeWidget=="undefined"?nil:HLCodeWidget)}
 return smalltalk.withContext(function($ctx1) { 
-_st(self)._assert_(_st(_st($HLCodeWidget())._pcKeyMap())._isKindOf_($HashedCollection()));
-_st(self)._assert_(_st(_st($HLCodeWidget())._macKeyMap())._isKindOf_($HashedCollection()));
+self._assert_(_st(_st($HLCodeWidget())._pcKeyMap())._isKindOf_($HashedCollection()));
+self._assert_(_st(_st($HLCodeWidget())._macKeyMap())._isKindOf_($HashedCollection()));
 return self}, function($ctx1) {$ctx1.fill(self,"testKeyMap",{},smalltalk.HLCodeWidgetTest)})},
 args: [],
 source: "testKeyMap\x0a\x22Key maps are a collection of associations.\x22\x0aself assert: ( HLCodeWidget pcKeyMap isKindOf: HashedCollection ).\x0aself assert: ( HLCodeWidget macKeyMap isKindOf: HashedCollection ).",

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

@@ -288,7 +288,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=smalltalk.HashedCollection._fromPairs_(["theme".__minus_gt("amber"),"lineNumbers".__minus_gt(true),"enterMode".__minus_gt("flat"),"indentWithTabs".__minus_gt(true),"indentUnit".__minus_gt((4)),"matchBrackets".__minus_gt(true),"electricChars".__minus_gt(false),"keyMap".__minus_gt("Amber"),"extraKeys".__minus_gt(smalltalk.HashedCollection._fromPairs_(["Shift-Space".__minus_gt("autocomplete")]))]);
+$1=smalltalk.HashedCollection._from_(["theme".__minus_gt("amber"),"lineNumbers".__minus_gt(true),"enterMode".__minus_gt("flat"),"indentWithTabs".__minus_gt(true),"indentUnit".__minus_gt((4)),"matchBrackets".__minus_gt(true),"electricChars".__minus_gt(false),"keyMap".__minus_gt("Amber"),"extraKeys".__minus_gt(smalltalk.HashedCollection._from_(["Shift-Space".__minus_gt("autocomplete")]))]);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"editorOptions",{},smalltalk.HLCodeWidget)})},
 messageSends: ["->"]}),
@@ -463,7 +463,7 @@ _st(start)._at_put_("ch",_st(_st(self["@editor"])._getCursor_(false))._ch());
 _st(_st(self["@editor"])._getSelection())._ifEmpty_((function(){
 return smalltalk.withContext(function($ctx2) {
 _st(start)._at_put_("ch",_st(_st(self["@editor"])._getLine_(currentLine))._size());
-return _st(self["@editor"])._setSelection_end_(smalltalk.HashedCollection._fromPairs_(["line".__minus_gt(currentLine),"ch".__minus_gt((0))]),start);
+return _st(self["@editor"])._setSelection_end_(smalltalk.HashedCollection._from_(["line".__minus_gt(currentLine),"ch".__minus_gt((0))]),start);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 stop=_st($HashedCollection())._new();
 _st(stop)._at_put_("line",currentLine);
@@ -725,7 +725,7 @@ completions=_st($HLCodeWidget())._variableHintFor_token_(anEditor,token);
 } else {
 completions=_st($HLCodeWidget())._messageHintFor_token_(anEditor,token);
 };
-$2=smalltalk.HashedCollection._fromPairs_(["list".__minus_gt(completions),"from".__minus_gt(_st(_st($CodeMirror())._basicAt_("Pos"))._value_value_(_st(cursor)._line(),_st(token)._end())),"to".__minus_gt(_st(_st($CodeMirror())._basicAt_("Pos"))._value_value_(_st(cursor)._line(),_st(token)._start()))]);
+$2=smalltalk.HashedCollection._from_(["list".__minus_gt(completions),"from".__minus_gt(_st(_st($CodeMirror())._basicAt_("Pos"))._value_value_(_st(cursor)._line(),_st(token)._end())),"to".__minus_gt(_st(_st($CodeMirror())._basicAt_("Pos"))._value_value_(_st(cursor)._line(),_st(token)._start()))]);
 return $2;
 }, function($ctx1) {$ctx1.fill(self,"hintFor:options:",{anEditor:anEditor,options:options,cursor:cursor,token:token,completions:completions},smalltalk.HLCodeWidget.klass)})},
 messageSends: ["getCursor", "getTokenAt:", "at:put:", "state", "value:value:", "getMode", "at:", "basicAt:", "ifTrue:ifFalse:", "variableHintFor:token:", "messageHintFor:token:", "=", "type", "->", "line", "end", "start"]}),
@@ -773,7 +773,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=smalltalk.HashedCollection._fromPairs_(["Alt-Backspace".__minus_gt("delWordBefore"),"Alt-Delete".__minus_gt("delWordAfter"),"Alt-Left".__minus_gt("goWordBoundaryLeft"),"Alt-Right".__minus_gt("goWordBoundaryRight"),"Cmd-A".__minus_gt("selectAll"),"Cmd-Alt-F".__minus_gt("replace"),"Cmd-D".__minus_gt("doIt"),"Cmd-Down".__minus_gt("goDocEnd"),"Cmd-End".__minus_gt("goDocEnd"),"Cmd-F".__minus_gt("find"),"Cmd-G".__minus_gt("findNext"),"Cmd-I".__minus_gt("inspectIt"),"Cmd-Left".__minus_gt("goLineStart"),"Cmd-P".__minus_gt("printIt"),"Cmd-Right".__minus_gt("goLineEnd"),"Cmd-S".__minus_gt("saveIt"),"Cmd-Up".__minus_gt("goDocStart"),"Cmd-Y".__minus_gt("redo"),"Cmd-Z".__minus_gt("undo"),"Cmd-[".__minus_gt("indentLess"),"Cmd-]".__minus_gt("indentMore"),"Ctrl-Alt-Backspace".__minus_gt("delWordAfter"),"Shift-Cmd-Alt-F".__minus_gt("replaceAll"),"Shift-Cmd-G".__minus_gt("findPrev"),"Shift-Cmd-Z".__minus_gt("redo"),"fallthrough".__minus_gt(["basic","emacsy"])]);
+$1=smalltalk.HashedCollection._from_(["Alt-Backspace".__minus_gt("delWordBefore"),"Alt-Delete".__minus_gt("delWordAfter"),"Alt-Left".__minus_gt("goWordBoundaryLeft"),"Alt-Right".__minus_gt("goWordBoundaryRight"),"Cmd-A".__minus_gt("selectAll"),"Cmd-Alt-F".__minus_gt("replace"),"Cmd-D".__minus_gt("doIt"),"Cmd-Down".__minus_gt("goDocEnd"),"Cmd-End".__minus_gt("goDocEnd"),"Cmd-F".__minus_gt("find"),"Cmd-G".__minus_gt("findNext"),"Cmd-I".__minus_gt("inspectIt"),"Cmd-Left".__minus_gt("goLineStart"),"Cmd-P".__minus_gt("printIt"),"Cmd-Right".__minus_gt("goLineEnd"),"Cmd-S".__minus_gt("saveIt"),"Cmd-Up".__minus_gt("goDocStart"),"Cmd-Y".__minus_gt("redo"),"Cmd-Z".__minus_gt("undo"),"Cmd-[".__minus_gt("indentLess"),"Cmd-]".__minus_gt("indentMore"),"Ctrl-Alt-Backspace".__minus_gt("delWordAfter"),"Shift-Cmd-Alt-F".__minus_gt("replaceAll"),"Shift-Cmd-G".__minus_gt("findPrev"),"Shift-Cmd-Z".__minus_gt("redo"),"fallthrough".__minus_gt(["basic","emacsy"])]);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"macKeyMap",{},smalltalk.HLCodeWidget.klass)})},
 messageSends: ["->"]}),
@@ -799,7 +799,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=smalltalk.HashedCollection._fromPairs_([_st("Alt-Left").__minus_gt("goLineStart"),_st("Alt-Right").__minus_gt("goLineEnd"),_st("Alt-Up").__minus_gt("goDocStart"),_st("Ctrl-A").__minus_gt("selectAll"),_st("Ctrl-Backspace").__minus_gt("delWordBefore"),_st("Ctrl-D").__minus_gt("doIt"),_st("Ctrl-Delete").__minus_gt("delWordAfter"),_st("Ctrl-Down").__minus_gt("goDocEnd"),_st("Ctrl-End").__minus_gt("goDocEnd"),_st("Ctrl-F").__minus_gt("find"),_st("Ctrl-G").__minus_gt("findNext"),_st("Ctrl-I").__minus_gt("inspectIt"),_st("Ctrl-Home").__minus_gt("goDocStart"),_st("Ctrl-Left").__minus_gt("goWordBoundaryLeft"),_st("Ctrl-P").__minus_gt("printIt"),_st("Ctrl-Right").__minus_gt("goWordBoundaryRight"),_st("Ctrl-S").__minus_gt("saveIt"),_st("Ctrl-Y").__minus_gt("redo"),_st("Ctrl-Z").__minus_gt("undo"),_st("Ctrl-[").__minus_gt("indentLess"),_st("Ctrl-]").__minus_gt("indentMore"),_st("Shift-Ctrl-F").__minus_gt("replace"),_st("Shift-Ctrl-G").__minus_gt("findPrev"),_st("Shift-Ctrl-R").__minus_gt("replaceAll"),_st("Shift-Ctrl-Z").__minus_gt("redo"),_st("fallthrough").__minus_gt(["basic"])]);
+$1=smalltalk.HashedCollection._from_(["Alt-Left".__minus_gt("goLineStart"),"Alt-Right".__minus_gt("goLineEnd"),"Alt-Up".__minus_gt("goDocStart"),"Ctrl-A".__minus_gt("selectAll"),"Ctrl-Backspace".__minus_gt("delWordBefore"),"Ctrl-D".__minus_gt("doIt"),"Ctrl-Delete".__minus_gt("delWordAfter"),"Ctrl-Down".__minus_gt("goDocEnd"),"Ctrl-End".__minus_gt("goDocEnd"),"Ctrl-F".__minus_gt("find"),"Ctrl-G".__minus_gt("findNext"),"Ctrl-I".__minus_gt("inspectIt"),"Ctrl-Home".__minus_gt("goDocStart"),"Ctrl-Left".__minus_gt("goWordBoundaryLeft"),"Ctrl-P".__minus_gt("printIt"),"Ctrl-Right".__minus_gt("goWordBoundaryRight"),"Ctrl-S".__minus_gt("saveIt"),"Ctrl-Y".__minus_gt("redo"),"Ctrl-Z".__minus_gt("undo"),"Ctrl-[".__minus_gt("indentLess"),"Ctrl-]".__minus_gt("indentMore"),"Shift-Ctrl-F".__minus_gt("replace"),"Shift-Ctrl-G".__minus_gt("findPrev"),"Shift-Ctrl-R".__minus_gt("replaceAll"),"Shift-Ctrl-Z".__minus_gt("redo"),"fallthrough".__minus_gt(["basic"])]);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"pcKeyMap",{},smalltalk.HLCodeWidget.klass)})},
 messageSends: ["->"]}),

+ 5 - 5
js/Helios-Workspace.js

@@ -384,7 +384,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=smalltalk.HashedCollection._fromPairs_(["theme".__minus_gt("amber"),"lineNumbers".__minus_gt(true),"enterMode".__minus_gt("flat"),"indentWithTabs".__minus_gt(true),"indentUnit".__minus_gt((4)),"matchBrackets".__minus_gt(true),"electricChars".__minus_gt(false),"keyMap".__minus_gt("Amber"),"extraKeys".__minus_gt(smalltalk.HashedCollection._fromPairs_(["Shift-Space".__minus_gt("autocomplete")]))]);
+$1=smalltalk.HashedCollection._from_(["theme".__minus_gt("amber"),"lineNumbers".__minus_gt(true),"enterMode".__minus_gt("flat"),"indentWithTabs".__minus_gt(true),"indentUnit".__minus_gt((4)),"matchBrackets".__minus_gt(true),"electricChars".__minus_gt(false),"keyMap".__minus_gt("Amber"),"extraKeys".__minus_gt(smalltalk.HashedCollection._from_(["Shift-Space".__minus_gt("autocomplete")]))]);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"editorOptions",{},smalltalk.HLCodeWidget)})},
 args: [],
@@ -624,7 +624,7 @@ _st(start)._at_put_("ch",_st(_st(self["@editor"])._getCursor_(false))._ch());
 _st(_st(self["@editor"])._getSelection())._ifEmpty_((function(){
 return smalltalk.withContext(function($ctx2) {
 _st(start)._at_put_("ch",_st(_st(self["@editor"])._getLine_(currentLine))._size());
-return _st(self["@editor"])._setSelection_end_(smalltalk.HashedCollection._fromPairs_(["line".__minus_gt(currentLine),"ch".__minus_gt((0))]),start);
+return _st(self["@editor"])._setSelection_end_(smalltalk.HashedCollection._from_(["line".__minus_gt(currentLine),"ch".__minus_gt((0))]),start);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 stop=_st($HashedCollection())._new();
 _st(stop)._at_put_("line",currentLine);
@@ -961,7 +961,7 @@ completions=_st($HLCodeWidget())._variableHintFor_token_(anEditor,token);
 } else {
 completions=_st($HLCodeWidget())._messageHintFor_token_(anEditor,token);
 };
-$2=smalltalk.HashedCollection._fromPairs_(["list".__minus_gt(completions),"from".__minus_gt(_st(_st($CodeMirror())._basicAt_("Pos"))._value_value_(_st(cursor)._line(),_st(token)._end())),"to".__minus_gt(_st(_st($CodeMirror())._basicAt_("Pos"))._value_value_(_st(cursor)._line(),_st(token)._start()))]);
+$2=smalltalk.HashedCollection._from_(["list".__minus_gt(completions),"from".__minus_gt(_st(_st($CodeMirror())._basicAt_("Pos"))._value_value_(_st(cursor)._line(),_st(token)._end())),"to".__minus_gt(_st(_st($CodeMirror())._basicAt_("Pos"))._value_value_(_st(cursor)._line(),_st(token)._start()))]);
 return $2;
 }, function($ctx1) {$ctx1.fill(self,"hintFor:options:",{anEditor:anEditor,options:options,cursor:cursor,token:token,completions:completions},smalltalk.HLCodeWidget.klass)})},
 args: ["anEditor", "options"],
@@ -1024,7 +1024,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=smalltalk.HashedCollection._fromPairs_(["Alt-Backspace".__minus_gt("delWordBefore"),"Alt-Delete".__minus_gt("delWordAfter"),"Alt-Left".__minus_gt("goWordBoundaryLeft"),"Alt-Right".__minus_gt("goWordBoundaryRight"),"Cmd-A".__minus_gt("selectAll"),"Cmd-Alt-F".__minus_gt("replace"),"Cmd-D".__minus_gt("doIt"),"Cmd-Down".__minus_gt("goDocEnd"),"Cmd-End".__minus_gt("goDocEnd"),"Cmd-F".__minus_gt("find"),"Cmd-G".__minus_gt("findNext"),"Cmd-I".__minus_gt("inspectIt"),"Cmd-Left".__minus_gt("goLineStart"),"Cmd-P".__minus_gt("printIt"),"Cmd-Right".__minus_gt("goLineEnd"),"Cmd-S".__minus_gt("saveIt"),"Cmd-Up".__minus_gt("goDocStart"),"Cmd-Y".__minus_gt("redo"),"Cmd-Z".__minus_gt("undo"),"Cmd-[".__minus_gt("indentLess"),"Cmd-]".__minus_gt("indentMore"),"Ctrl-Alt-Backspace".__minus_gt("delWordAfter"),"Shift-Cmd-Alt-F".__minus_gt("replaceAll"),"Shift-Cmd-G".__minus_gt("findPrev"),"Shift-Cmd-Z".__minus_gt("redo"),"fallthrough".__minus_gt(["basic","emacsy"])]);
+$1=smalltalk.HashedCollection._from_(["Alt-Backspace".__minus_gt("delWordBefore"),"Alt-Delete".__minus_gt("delWordAfter"),"Alt-Left".__minus_gt("goWordBoundaryLeft"),"Alt-Right".__minus_gt("goWordBoundaryRight"),"Cmd-A".__minus_gt("selectAll"),"Cmd-Alt-F".__minus_gt("replace"),"Cmd-D".__minus_gt("doIt"),"Cmd-Down".__minus_gt("goDocEnd"),"Cmd-End".__minus_gt("goDocEnd"),"Cmd-F".__minus_gt("find"),"Cmd-G".__minus_gt("findNext"),"Cmd-I".__minus_gt("inspectIt"),"Cmd-Left".__minus_gt("goLineStart"),"Cmd-P".__minus_gt("printIt"),"Cmd-Right".__minus_gt("goLineEnd"),"Cmd-S".__minus_gt("saveIt"),"Cmd-Up".__minus_gt("goDocStart"),"Cmd-Y".__minus_gt("redo"),"Cmd-Z".__minus_gt("undo"),"Cmd-[".__minus_gt("indentLess"),"Cmd-]".__minus_gt("indentMore"),"Ctrl-Alt-Backspace".__minus_gt("delWordAfter"),"Shift-Cmd-Alt-F".__minus_gt("replaceAll"),"Shift-Cmd-G".__minus_gt("findPrev"),"Shift-Cmd-Z".__minus_gt("redo"),"fallthrough".__minus_gt(["basic","emacsy"])]);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"macKeyMap",{},smalltalk.HLCodeWidget.klass)})},
 args: [],
@@ -1060,7 +1060,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=smalltalk.HashedCollection._fromPairs_([_st("Alt-Left").__minus_gt("goLineStart"),_st("Alt-Right").__minus_gt("goLineEnd"),_st("Alt-Up").__minus_gt("goDocStart"),_st("Ctrl-A").__minus_gt("selectAll"),_st("Ctrl-Backspace").__minus_gt("delWordBefore"),_st("Ctrl-D").__minus_gt("doIt"),_st("Ctrl-Delete").__minus_gt("delWordAfter"),_st("Ctrl-Down").__minus_gt("goDocEnd"),_st("Ctrl-End").__minus_gt("goDocEnd"),_st("Ctrl-F").__minus_gt("find"),_st("Ctrl-G").__minus_gt("findNext"),_st("Ctrl-I").__minus_gt("inspectIt"),_st("Ctrl-Home").__minus_gt("goDocStart"),_st("Ctrl-Left").__minus_gt("goWordBoundaryLeft"),_st("Ctrl-P").__minus_gt("printIt"),_st("Ctrl-Right").__minus_gt("goWordBoundaryRight"),_st("Ctrl-S").__minus_gt("saveIt"),_st("Ctrl-Y").__minus_gt("redo"),_st("Ctrl-Z").__minus_gt("undo"),_st("Ctrl-[").__minus_gt("indentLess"),_st("Ctrl-]").__minus_gt("indentMore"),_st("Shift-Ctrl-F").__minus_gt("replace"),_st("Shift-Ctrl-G").__minus_gt("findPrev"),_st("Shift-Ctrl-R").__minus_gt("replaceAll"),_st("Shift-Ctrl-Z").__minus_gt("redo"),_st("fallthrough").__minus_gt(["basic"])]);
+$1=smalltalk.HashedCollection._from_(["Alt-Left".__minus_gt("goLineStart"),"Alt-Right".__minus_gt("goLineEnd"),"Alt-Up".__minus_gt("goDocStart"),"Ctrl-A".__minus_gt("selectAll"),"Ctrl-Backspace".__minus_gt("delWordBefore"),"Ctrl-D".__minus_gt("doIt"),"Ctrl-Delete".__minus_gt("delWordAfter"),"Ctrl-Down".__minus_gt("goDocEnd"),"Ctrl-End".__minus_gt("goDocEnd"),"Ctrl-F".__minus_gt("find"),"Ctrl-G".__minus_gt("findNext"),"Ctrl-I".__minus_gt("inspectIt"),"Ctrl-Home".__minus_gt("goDocStart"),"Ctrl-Left".__minus_gt("goWordBoundaryLeft"),"Ctrl-P".__minus_gt("printIt"),"Ctrl-Right".__minus_gt("goWordBoundaryRight"),"Ctrl-S".__minus_gt("saveIt"),"Ctrl-Y".__minus_gt("redo"),"Ctrl-Z".__minus_gt("undo"),"Ctrl-[".__minus_gt("indentLess"),"Ctrl-]".__minus_gt("indentMore"),"Shift-Ctrl-F".__minus_gt("replace"),"Shift-Ctrl-G".__minus_gt("findPrev"),"Shift-Ctrl-R".__minus_gt("replaceAll"),"Shift-Ctrl-Z".__minus_gt("redo"),"fallthrough".__minus_gt(["basic"])]);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"pcKeyMap",{},smalltalk.HLCodeWidget.klass)})},
 args: [],

+ 1 - 1
js/IDE.deploy.js

@@ -604,7 +604,7 @@ _st(start)._at_put_("ch",_st(_st(self["@editor"])._getCursor_(false))._ch());
 _st(_st(self["@editor"])._getSelection())._ifEmpty_((function(){
 return smalltalk.withContext(function($ctx2) {
 _st(start)._at_put_("ch",_st(_st(self["@editor"])._getLine_(currentLine))._size());
-return _st(self["@editor"])._setSelection_end_(smalltalk.HashedCollection._fromPairs_(["line".__minus_gt(currentLine),"ch".__minus_gt((0))]),start);
+return _st(self["@editor"])._setSelection_end_(smalltalk.HashedCollection._from_(["line".__minus_gt(currentLine),"ch".__minus_gt((0))]),start);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 stop=_st($HashedCollection())._new();
 _st(stop)._at_put_("line",currentLine);

+ 1 - 1
js/IDE.js

@@ -785,7 +785,7 @@ _st(start)._at_put_("ch",_st(_st(self["@editor"])._getCursor_(false))._ch());
 _st(_st(self["@editor"])._getSelection())._ifEmpty_((function(){
 return smalltalk.withContext(function($ctx2) {
 _st(start)._at_put_("ch",_st(_st(self["@editor"])._getLine_(currentLine))._size());
-return _st(self["@editor"])._setSelection_end_(smalltalk.HashedCollection._fromPairs_(["line".__minus_gt(currentLine),"ch".__minus_gt((0))]),start);
+return _st(self["@editor"])._setSelection_end_(smalltalk.HashedCollection._from_(["line".__minus_gt(currentLine),"ch".__minus_gt((0))]),start);
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 stop=_st($HashedCollection())._new();
 _st(stop)._at_put_("line",currentLine);

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

@@ -670,7 +670,7 @@ selector: "ajaxPutAt:data:",
 fn: function (aURL,aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(jQuery)._ajax_options_(aURL,smalltalk.HashedCollection._fromPairs_(["type".__minus_gt("PUT"),"data".__minus_gt(aString),"contentType".__minus_gt("text/plain;charset=UTF-8"),"error".__minus_gt((function(xhr){
+_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){
 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)})}))]));
@@ -707,7 +707,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._fromPairs_(["type".__minus_gt("GET"),"dataType".__minus_gt("script"),"complete".__minus_gt((function(jqXHR,textStatus){
+_st(jQuery)._ajax_options_(url,smalltalk.HashedCollection._from_(["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)){

+ 2 - 2
js/Importer-Exporter.js

@@ -802,7 +802,7 @@ category: 'private',
 fn: function (aURL,aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(jQuery)._ajax_options_(aURL,smalltalk.HashedCollection._fromPairs_(["type".__minus_gt("PUT"),"data".__minus_gt(aString),"contentType".__minus_gt("text/plain;charset=UTF-8"),"error".__minus_gt((function(xhr){
+_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){
 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)})}))]));
@@ -849,7 +849,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._fromPairs_(["type".__minus_gt("GET"),"dataType".__minus_gt("script"),"complete".__minus_gt((function(jqXHR,textStatus){
+_st(jQuery)._ajax_options_(url,smalltalk.HashedCollection._from_(["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)){

+ 46 - 10
js/Kernel-Collections.deploy.js

@@ -879,10 +879,10 @@ var self=this;
 function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st($Dictionary())._fromPairs_(self._associations());
+$1=_st($Dictionary())._from_(self._associations());
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"asDictionary",{},smalltalk.HashedCollection)})},
-messageSends: ["fromPairs:", "associations"]}),
+messageSends: ["from:", "associations"]}),
 smalltalk.HashedCollection);
 
 smalltalk.addMethod(
@@ -1313,23 +1313,59 @@ smalltalk.HashedCollection);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "fromPairs:",
+selector: "from:",
 fn: function (aCollection){
 var self=this;
-var dict;
+var newCollection;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-dict=self._new();
+newCollection=self._new();
 _st(aCollection)._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
-return _st(dict)._add_(each);
+return _st(newCollection)._add_(each);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
-$1=dict;
+$1=newCollection;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"fromPairs:",{aCollection:aCollection,dict:dict},smalltalk.HashedCollection.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"from:",{aCollection:aCollection,newCollection:newCollection},smalltalk.HashedCollection.klass)})},
 messageSends: ["new", "do:", "add:"]}),
 smalltalk.HashedCollection.klass);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "fromPairs:",
+fn: function (aCollection){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self._from_(aCollection);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"fromPairs:",{aCollection:aCollection},smalltalk.HashedCollection.klass)})},
+messageSends: ["from:"]}),
+smalltalk.HashedCollection.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "newFromPairs:",
+fn: function (aCollection){
+var self=this;
+var newCollection;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st(_st(aCollection)._size())._even();
+if(! smalltalk.assert($1)){
+self._error_("#newFromPairs only accepts arrays of an even length");
+};
+newCollection=self._new();
+_st((1)._to_by_(_st(aCollection)._size(),(2)))._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(newCollection)._at_put_(_st(aCollection)._at_(each),_st(aCollection)._at_(_st(each).__plus((1))));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+$2=newCollection;
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"newFromPairs:",{aCollection:aCollection,newCollection:newCollection},smalltalk.HashedCollection.klass)})},
+messageSends: ["ifFalse:", "error:", "even", "size", "new", "do:", "at:put:", "at:", "+", "to:by:"]}),
+smalltalk.HashedCollection.klass);
+
 
 smalltalk.addClass('Dictionary', smalltalk.HashedCollection, ['keys', 'values'], 'Kernel-Collections');
 smalltalk.addMethod(
@@ -1340,10 +1376,10 @@ var self=this;
 function $HashedCollection(){return smalltalk.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st($HashedCollection())._fromPairs_(self._associations());
+$1=_st($HashedCollection())._from_(self._associations());
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"asHashedCollection",{},smalltalk.Dictionary)})},
-messageSends: ["fromPairs:", "associations"]}),
+messageSends: ["from:", "associations"]}),
 smalltalk.Dictionary);
 
 smalltalk.addMethod(

+ 59 - 13
js/Kernel-Collections.js

@@ -1169,12 +1169,12 @@ var self=this;
 function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st($Dictionary())._fromPairs_(self._associations());
+$1=_st($Dictionary())._from_(self._associations());
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"asDictionary",{},smalltalk.HashedCollection)})},
 args: [],
-source: "asDictionary\x0a\x09^Dictionary fromPairs: self associations",
-messageSends: ["fromPairs:", "associations"],
+source: "asDictionary\x0a\x09^Dictionary from: self associations",
+messageSends: ["from:", "associations"],
 referencedClasses: ["Dictionary"]
 }),
 smalltalk.HashedCollection);
@@ -1742,28 +1742,74 @@ smalltalk.HashedCollection);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "fromPairs:",
+selector: "from:",
 category: 'instance creation',
 fn: function (aCollection){
 var self=this;
-var dict;
+var newCollection;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-dict=self._new();
+newCollection=self._new();
 _st(aCollection)._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
-return _st(dict)._add_(each);
+return _st(newCollection)._add_(each);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
-$1=dict;
+$1=newCollection;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"fromPairs:",{aCollection:aCollection,dict:dict},smalltalk.HashedCollection.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"from:",{aCollection:aCollection,newCollection:newCollection},smalltalk.HashedCollection.klass)})},
 args: ["aCollection"],
-source: "fromPairs: aCollection\x0a\x09| dict |\x0a\x09dict := self new.\x0a\x09aCollection do: [:each | dict add: each].\x0a\x09^dict",
+source: "from: aCollection\x0a\x09| newCollection |\x0a\x09newCollection := self new.\x0a\x09aCollection do: [ :each | newCollection add: each ].\x0a\x09^ newCollection",
 messageSends: ["new", "do:", "add:"],
 referencedClasses: []
 }),
 smalltalk.HashedCollection.klass);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "fromPairs:",
+category: 'instance creation',
+fn: function (aCollection){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self._from_(aCollection);
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"fromPairs:",{aCollection:aCollection},smalltalk.HashedCollection.klass)})},
+args: ["aCollection"],
+source: "fromPairs: aCollection\x0a\x09\x22This message is poorly named and has been replaced by #from:\x22\x0a\x09^ self from: aCollection",
+messageSends: ["from:"],
+referencedClasses: []
+}),
+smalltalk.HashedCollection.klass);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "newFromPairs:",
+category: 'instance creation',
+fn: function (aCollection){
+var self=this;
+var newCollection;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st(_st(aCollection)._size())._even();
+if(! smalltalk.assert($1)){
+self._error_("#newFromPairs only accepts arrays of an even length");
+};
+newCollection=self._new();
+_st((1)._to_by_(_st(aCollection)._size(),(2)))._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
+return _st(newCollection)._at_put_(_st(aCollection)._at_(each),_st(aCollection)._at_(_st(each).__plus((1))));
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+$2=newCollection;
+return $2;
+}, function($ctx1) {$ctx1.fill(self,"newFromPairs:",{aCollection:aCollection,newCollection:newCollection},smalltalk.HashedCollection.klass)})},
+args: ["aCollection"],
+source: "newFromPairs: aCollection\x0a\x09\x22Accept an array of elements where every two elements form an \x0a\x09association - the odd element being the key, and the even element the value.\x22\x0a\x09\x0a\x09| newCollection |\x0a\x09\x0a\x09aCollection size even ifFalse: [ \x0a\x09\x09self error: '#newFromPairs only accepts arrays of an even length' ].\x0a\x09\x09\x0a\x09newCollection := self new.\x0a\x09( 1 to: aCollection size by: 2 ) do: [ :each | \x0a\x09\x09newCollection at: (aCollection at: each) put: (aCollection at: each + 1) ].\x0a\x09\x09\x0a\x09^ newCollection",
+messageSends: ["ifFalse:", "error:", "even", "size", "new", "do:", "at:put:", "at:", "+", "to:by:"],
+referencedClasses: []
+}),
+smalltalk.HashedCollection.klass);
+
 
 smalltalk.addClass('Dictionary', smalltalk.HashedCollection, ['keys', 'values'], 'Kernel-Collections');
 smalltalk.Dictionary.comment="I represent a set of elements that can be viewed from one of two perspectives: a set of associations,\x0aor a container of values that are externally named where the name can be any object that responds to `=`.\x0a\x0aThe external name is referred to as the key.";
@@ -1776,12 +1822,12 @@ var self=this;
 function $HashedCollection(){return smalltalk.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=_st($HashedCollection())._fromPairs_(self._associations());
+$1=_st($HashedCollection())._from_(self._associations());
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"asHashedCollection",{},smalltalk.Dictionary)})},
 args: [],
-source: "asHashedCollection\x0a\x09^HashedCollection fromPairs: self associations",
-messageSends: ["fromPairs:", "associations"],
+source: "asHashedCollection\x0a\x09^HashedCollection from: self associations",
+messageSends: ["from:", "associations"],
 referencedClasses: ["HashedCollection"]
 }),
 smalltalk.Dictionary);

+ 3 - 3
js/Kernel-Methods.deploy.js

@@ -56,7 +56,7 @@ selector: "ensure:",
 fn: function (aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-try{return self()}finally{aBlock._value()};
+try{return self._value()}finally{aBlock._value()};
 return self}, function($ctx1) {$ctx1.fill(self,"ensure:",{aBlock:aBlock},smalltalk.BlockClosure)})},
 messageSends: []}),
 smalltalk.BlockClosure);
@@ -302,7 +302,7 @@ selector: "whileFalse:",
 fn: function (aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-while(!self()) {aBlock._value()};
+while(!smalltalk.assert(self._value())) {aBlock._value()};
 return self}, function($ctx1) {$ctx1.fill(self,"whileFalse:",{aBlock:aBlock},smalltalk.BlockClosure)})},
 messageSends: []}),
 smalltalk.BlockClosure);
@@ -326,7 +326,7 @@ selector: "whileTrue:",
 fn: function (aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-while(self()) {aBlock._value()};
+while(smalltalk.assert(self._value())) {aBlock._value()};
 return self}, function($ctx1) {$ctx1.fill(self,"whileTrue:",{aBlock:aBlock},smalltalk.BlockClosure)})},
 messageSends: []}),
 smalltalk.BlockClosure);

+ 6 - 6
js/Kernel-Methods.js

@@ -78,10 +78,10 @@ category: 'evaluating',
 fn: function (aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-try{return self()}finally{aBlock._value()};
+try{return self._value()}finally{aBlock._value()};
 return self}, function($ctx1) {$ctx1.fill(self,"ensure:",{aBlock:aBlock},smalltalk.BlockClosure)})},
 args: ["aBlock"],
-source: "ensure: aBlock\x0a\x09<try{return self()}finally{aBlock._value()}>",
+source: "ensure: aBlock\x0a\x09<try{return self._value()}finally{aBlock._value()}>",
 messageSends: [],
 referencedClasses: []
 }),
@@ -419,10 +419,10 @@ category: 'controlling',
 fn: function (aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-while(!self()) {aBlock._value()};
+while(!smalltalk.assert(self._value())) {aBlock._value()};
 return self}, function($ctx1) {$ctx1.fill(self,"whileFalse:",{aBlock:aBlock},smalltalk.BlockClosure)})},
 args: ["aBlock"],
-source: "whileFalse: aBlock\x0a\x09\x22inlined in the Compiler\x22\x0a\x09<while(!self()) {aBlock._value()}>",
+source: "whileFalse: aBlock\x0a\x09\x22inlined in the Compiler\x22\x0a\x09<while(!smalltalk.assert(self._value())) {aBlock._value()}>",
 messageSends: [],
 referencedClasses: []
 }),
@@ -453,10 +453,10 @@ category: 'controlling',
 fn: function (aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-while(self()) {aBlock._value()};
+while(smalltalk.assert(self._value())) {aBlock._value()};
 return self}, function($ctx1) {$ctx1.fill(self,"whileTrue:",{aBlock:aBlock},smalltalk.BlockClosure)})},
 args: ["aBlock"],
-source: "whileTrue: aBlock\x0a\x09\x22inlined in the Compiler\x22\x0a\x09<while(self()) {aBlock._value()}>",
+source: "whileTrue: aBlock\x0a\x09\x22inlined in the Compiler\x22\x0a\x09<while(smalltalk.assert(self._value())) {aBlock._value()}>",
 messageSends: [],
 referencedClasses: []
 }),

+ 53 - 3
js/Kernel-Tests.deploy.js

@@ -1061,7 +1061,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=smalltalk.HashedCollection._fromPairs_(["b".__minus_gt((1)),"a".__minus_gt((2)),"c".__minus_gt((3)),"d".__minus_gt((-4))]);
+$1=smalltalk.HashedCollection._from_(["b".__minus_gt((1)),"a".__minus_gt((2)),"c".__minus_gt((3)),"d".__minus_gt((-4))]);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"collection",{},smalltalk.HashedCollectionTest)})},
 messageSends: ["->"]}),
@@ -1074,12 +1074,24 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=smalltalk.HashedCollection._fromPairs_(["b".__minus_gt((1)),"a".__minus_gt((2)),"c".__minus_gt((3)),"d".__minus_gt((-4)),"e".__minus_gt((1)),"f".__minus_gt((2)),"g".__minus_gt((10))]);
+$1=smalltalk.HashedCollection._from_(["b".__minus_gt((1)),"a".__minus_gt((2)),"c".__minus_gt((3)),"d".__minus_gt((-4)),"e".__minus_gt((1)),"f".__minus_gt((2)),"g".__minus_gt((10))]);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"collectionWithDuplicates",{},smalltalk.HashedCollectionTest)})},
 messageSends: ["->"]}),
 smalltalk.HashedCollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testAsDictionary",
+fn: function (){
+var self=this;
+function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
+return smalltalk.withContext(function($ctx1) { 
+self._assert_(_st(_st(_st(self._collectionClass())._new())._asDictionary())._isMemberOf_($Dictionary()));
+return self}, function($ctx1) {$ctx1.fill(self,"testAsDictionary",{},smalltalk.HashedCollectionTest)})},
+messageSends: ["assert:", "isMemberOf:", "asDictionary", "new", "collectionClass"]}),
+smalltalk.HashedCollectionTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testAt",
@@ -1117,6 +1129,19 @@ return self}, function($ctx1) {$ctx1.fill(self,"testContains",{collection:collec
 messageSends: ["collection", "assert:", "contains:", "=", "first", "values", "deny:", "new"]}),
 smalltalk.HashedCollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testFrom",
+fn: function (){
+var self=this;
+var associations;
+return smalltalk.withContext(function($ctx1) { 
+associations=["a".__minus_gt((1)),"b".__minus_gt((2))];
+self._assertSameContents_as_(_st(_st(self._class())._collectionClass())._from_(associations),smalltalk.HashedCollection._from_(["a".__minus_gt((1)),"b".__minus_gt((2))]));
+return self}, function($ctx1) {$ctx1.fill(self,"testFrom",{associations:associations},smalltalk.HashedCollectionTest)})},
+messageSends: ["->", "assertSameContents:as:", "from:", "collectionClass", "class"]}),
+smalltalk.HashedCollectionTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testIndexOf",
@@ -1137,6 +1162,19 @@ return self}, function($ctx1) {$ctx1.fill(self,"testIndexOf",{},smalltalk.Hashed
 messageSends: ["assert:equals:", "indexOf:", "collection", "should:raise:", "indexOf:ifAbsent:"]}),
 smalltalk.HashedCollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testNewFromPairs",
+fn: function (){
+var self=this;
+var flattenedAssociations;
+return smalltalk.withContext(function($ctx1) { 
+flattenedAssociations=["a",(1),"b",(2)];
+self._assertSameContents_as_(_st(_st(self._class())._collectionClass())._newFromPairs_(flattenedAssociations),smalltalk.HashedCollection._from_(["a".__minus_gt((1)),"b".__minus_gt((2))]));
+return self}, function($ctx1) {$ctx1.fill(self,"testNewFromPairs",{flattenedAssociations:flattenedAssociations},smalltalk.HashedCollectionTest)})},
+messageSends: ["assertSameContents:as:", "newFromPairs:", "collectionClass", "class", "->"]}),
+smalltalk.HashedCollectionTest);
+
 
 smalltalk.addMethod(
 smalltalk.method({
@@ -1228,6 +1266,18 @@ return self}, function($ctx1) {$ctx1.fill(self,"testAccessing",{d:d},smalltalk.D
 messageSends: ["new", "at:put:", "assert:equals:", "at:", "at:ifAbsent:", "deny:", "=", "assert:", "includesKey:", "@"]}),
 smalltalk.DictionaryTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testAsHashedCollection",
+fn: function (){
+var self=this;
+function $HashedCollection(){return smalltalk.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
+return smalltalk.withContext(function($ctx1) { 
+self._assert_(_st(_st(_st(self._collectionClass())._new())._asHashedCollection())._isMemberOf_($HashedCollection()));
+return self}, function($ctx1) {$ctx1.fill(self,"testAsHashedCollection",{},smalltalk.DictionaryTest)})},
+messageSends: ["assert:", "isMemberOf:", "asHashedCollection", "new", "collectionClass"]}),
+smalltalk.DictionaryTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testDynamicDictionaries",
@@ -1235,7 +1285,7 @@ fn: function (){
 var self=this;
 function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
 return smalltalk.withContext(function($ctx1) { 
-self._assert_equals_(_st(smalltalk.HashedCollection._fromPairs_(["hello".__minus_gt((1))]))._asDictionary(),_st($Dictionary())._with_("hello".__minus_gt((1))));
+self._assert_equals_(_st(smalltalk.HashedCollection._from_(["hello".__minus_gt((1))]))._asDictionary(),_st($Dictionary())._with_("hello".__minus_gt((1))));
 return self}, function($ctx1) {$ctx1.fill(self,"testDynamicDictionaries",{},smalltalk.DictionaryTest)})},
 messageSends: ["assert:equals:", "asDictionary", "->", "with:"]}),
 smalltalk.DictionaryTest);

+ 73 - 3
js/Kernel-Tests.js

@@ -1312,7 +1312,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=smalltalk.HashedCollection._fromPairs_(["b".__minus_gt((1)),"a".__minus_gt((2)),"c".__minus_gt((3)),"d".__minus_gt((-4))]);
+$1=smalltalk.HashedCollection._from_(["b".__minus_gt((1)),"a".__minus_gt((2)),"c".__minus_gt((3)),"d".__minus_gt((-4))]);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"collection",{},smalltalk.HashedCollectionTest)})},
 args: [],
@@ -1330,7 +1330,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $1;
-$1=smalltalk.HashedCollection._fromPairs_(["b".__minus_gt((1)),"a".__minus_gt((2)),"c".__minus_gt((3)),"d".__minus_gt((-4)),"e".__minus_gt((1)),"f".__minus_gt((2)),"g".__minus_gt((10))]);
+$1=smalltalk.HashedCollection._from_(["b".__minus_gt((1)),"a".__minus_gt((2)),"c".__minus_gt((3)),"d".__minus_gt((-4)),"e".__minus_gt((1)),"f".__minus_gt((2)),"g".__minus_gt((10))]);
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"collectionWithDuplicates",{},smalltalk.HashedCollectionTest)})},
 args: [],
@@ -1340,6 +1340,23 @@ referencedClasses: []
 }),
 smalltalk.HashedCollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testAsDictionary",
+category: 'tests',
+fn: function (){
+var self=this;
+function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
+return smalltalk.withContext(function($ctx1) { 
+self._assert_(_st(_st(_st(self._collectionClass())._new())._asDictionary())._isMemberOf_($Dictionary()));
+return self}, function($ctx1) {$ctx1.fill(self,"testAsDictionary",{},smalltalk.HashedCollectionTest)})},
+args: [],
+source: "testAsDictionary\x0aself assert: ( self collectionClass new asDictionary isMemberOf: Dictionary ).",
+messageSends: ["assert:", "isMemberOf:", "asDictionary", "new", "collectionClass"],
+referencedClasses: ["Dictionary"]
+}),
+smalltalk.HashedCollectionTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testAt",
@@ -1387,6 +1404,24 @@ referencedClasses: ["Object"]
 }),
 smalltalk.HashedCollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testFrom",
+category: 'tests',
+fn: function (){
+var self=this;
+var associations;
+return smalltalk.withContext(function($ctx1) { 
+associations=["a".__minus_gt((1)),"b".__minus_gt((2))];
+self._assertSameContents_as_(_st(_st(self._class())._collectionClass())._from_(associations),smalltalk.HashedCollection._from_(["a".__minus_gt((1)),"b".__minus_gt((2))]));
+return self}, function($ctx1) {$ctx1.fill(self,"testFrom",{associations:associations},smalltalk.HashedCollectionTest)})},
+args: [],
+source: "testFrom\x0a\x22Accept a collection of associations.\x22\x0a| associations |\x0aassociations := { 'a' -> 1. 'b' -> 2 }.\x0aself assertSameContents: ( self class collectionClass from: associations ) as: #{ 'a' -> 1. 'b' -> 2 }.",
+messageSends: ["->", "assertSameContents:as:", "from:", "collectionClass", "class"],
+referencedClasses: []
+}),
+smalltalk.HashedCollectionTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testIndexOf",
@@ -1412,6 +1447,24 @@ referencedClasses: ["Error"]
 }),
 smalltalk.HashedCollectionTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testNewFromPairs",
+category: 'tests',
+fn: function (){
+var self=this;
+var flattenedAssociations;
+return smalltalk.withContext(function($ctx1) { 
+flattenedAssociations=["a",(1),"b",(2)];
+self._assertSameContents_as_(_st(_st(self._class())._collectionClass())._newFromPairs_(flattenedAssociations),smalltalk.HashedCollection._from_(["a".__minus_gt((1)),"b".__minus_gt((2))]));
+return self}, function($ctx1) {$ctx1.fill(self,"testNewFromPairs",{flattenedAssociations:flattenedAssociations},smalltalk.HashedCollectionTest)})},
+args: [],
+source: "testNewFromPairs\x0a\x22Accept an array in which all odd indexes are keys and evens are values.\x22\x0a| flattenedAssociations |\x0aflattenedAssociations := { 'a'. 1. 'b'. 2 }.\x0aself assertSameContents: ( self class collectionClass newFromPairs: flattenedAssociations ) as: #{ 'a' -> 1. 'b' -> 2 }.",
+messageSends: ["assertSameContents:as:", "newFromPairs:", "collectionClass", "class", "->"],
+referencedClasses: []
+}),
+smalltalk.HashedCollectionTest);
+
 
 smalltalk.addMethod(
 smalltalk.method({
@@ -1523,6 +1576,23 @@ referencedClasses: ["Dictionary"]
 }),
 smalltalk.DictionaryTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testAsHashedCollection",
+category: 'tests',
+fn: function (){
+var self=this;
+function $HashedCollection(){return smalltalk.HashedCollection||(typeof HashedCollection=="undefined"?nil:HashedCollection)}
+return smalltalk.withContext(function($ctx1) { 
+self._assert_(_st(_st(_st(self._collectionClass())._new())._asHashedCollection())._isMemberOf_($HashedCollection()));
+return self}, function($ctx1) {$ctx1.fill(self,"testAsHashedCollection",{},smalltalk.DictionaryTest)})},
+args: [],
+source: "testAsHashedCollection\x0aself assert: ( self collectionClass new asHashedCollection isMemberOf: HashedCollection ).",
+messageSends: ["assert:", "isMemberOf:", "asHashedCollection", "new", "collectionClass"],
+referencedClasses: ["HashedCollection"]
+}),
+smalltalk.DictionaryTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testDynamicDictionaries",
@@ -1531,7 +1601,7 @@ fn: function (){
 var self=this;
 function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
 return smalltalk.withContext(function($ctx1) { 
-self._assert_equals_(_st(smalltalk.HashedCollection._fromPairs_(["hello".__minus_gt((1))]))._asDictionary(),_st($Dictionary())._with_("hello".__minus_gt((1))));
+self._assert_equals_(_st(smalltalk.HashedCollection._from_(["hello".__minus_gt((1))]))._asDictionary(),_st($Dictionary())._with_("hello".__minus_gt((1))));
 return self}, function($ctx1) {$ctx1.fill(self,"testDynamicDictionaries",{},smalltalk.DictionaryTest)})},
 args: [],
 source: "testDynamicDictionaries\x0a\x09self assert: #{'hello' -> 1} asDictionary equals: (Dictionary with: 'hello' -> 1)",

+ 43 - 44
js/amber.js

@@ -21,12 +21,12 @@ amber = (function() {
 	var loadJS;
 	var nocache = '';
 
-    function resolveViaDOM(url) {
-        var a = document.createElement("a");
-        a.href = url;
-        return a.href;
-    }
-
+	function resolveViaDOM(url) {
+		var a = document.createElement("a");
+		a.href = url;
+		return a.href;
+	}
+	
 	that.load = function(obj) {
 		spec = obj || {};
 
@@ -38,7 +38,7 @@ amber = (function() {
 		// When debug is turned on, logs are written to the console,
 		// and the user will be prompted before they leave the page.
 		if (debug) {
-			window.onbeforeunload = function(){ return 'You will loose all code that you have not committed'; }
+			window.onbeforeunload = function(){ return 'You will loose all code that you have not committed'; };
 		}
 
 		// Allow loading default Amber files from a different location
@@ -207,13 +207,13 @@ amber = (function() {
 	// This will be called after JS files have been loaded
 	function initializeSmalltalk() {
 		that.smalltalkReady = function() {
-            if (spec.ready) {
-                spec.ready();
-            }
-            evaluateSmalltalkScripts();
-        };
+			if (spec.ready) {
+				spec.ready();
+			}
+			evaluateSmalltalkScripts();
+		};
 
-        loadAllJS();
+		loadAllJS();
 	}
 
 	/*
@@ -268,7 +268,7 @@ amber = (function() {
 			jQuery('script[type="text/smalltalk"]').each(function(i, elt) {
 				smalltalk.Compiler._new()._evaluateExpression_(jQuery(elt).html());
 			});
-		})
+		});
 	}
 
 	var localPackages;
@@ -304,37 +304,36 @@ amber = (function() {
 	}
 
 	that.loadHelios = function() {
-        loadCSS('helios_frame.css');
-        var frame = jQuery('<div id="helios"><iframe frameborder=0 src="' + home + 'helios.html"></iframe></div>');
-
-        jQuery('body').append(frame);
-        jQuery(frame).resizable({
-            handles: 'n',
-            start: onResizeStart,
-            stop: onResizeStop,
-            resize: onResize,
-            
-        });
-
-        function onResize() {
-            jQuery('#helios')
-                .css('top', '')
-                .css('width', '100%')
-                .css('bottom', '0px');
-        }
-
-        function onResizeStart() {
-            jQuery('#helios').append('<div class="overlay"></div>')
-        }
-
-        function onResizeStop() {
-            jQuery('#helios').find('.overlay').remove();
-        }
-    };
+		loadCSS('helios_frame.css');
+		var frame = jQuery('<div id="helios"><iframe frameborder=0 src="' + home + 'helios.html"></iframe></div>');
+	
+		jQuery('body').append(frame);
+		jQuery(frame).resizable({
+			handles: 'n',
+			start: onResizeStart,
+			stop: onResizeStop,
+			resize: onResize
+		});
+	
+		function onResize() {
+			jQuery('#helios')
+				.css('top', '')
+				.css('width', '100%')
+				.css('bottom', '0px');
+		}
+	
+		function onResizeStart() {
+			jQuery('#helios').append('<div class="overlay"></div>');
+		}
+	
+		function onResizeStop() {
+			jQuery('#helios').find('.overlay').remove();
+		}
+	};
 
 	that.popupHelios = function() {
-        window.open(home + 'helios.html', "Helios", "menubar=no, status=no, scrollbars=no, menubar=no, width=1000, height=600");
-    };
+		window.open(home + 'helios.html', "Helios", "menubar=no, status=no, scrollbars=no, menubar=no, width=1000, height=600");
+	};
 
 	return that;
 })();
@@ -345,5 +344,5 @@ window.popupHelios = amber.popupHelios;
 
 // Backward compatibility
 function toggleAmberIDE () {
-    return smalltalk.TabManager._toggleAmberIDE();
+	return smalltalk.TabManager._toggleAmberIDE();
 }

+ 239 - 236
js/boot.js

@@ -50,13 +50,13 @@ if(typeof console === "undefined") {
 Array.prototype.addElement = function(el) {
 	if(typeof el === 'undefined') { return; }
 	if(this.indexOf(el) == -1) {
-        this.push(el);
-    }
+		this.push(el);
+	}
 };
 
 Array.prototype.removeElement = function(el) {
-    var i = this.indexOf(el);
-    if (i !== -1) { this.splice(i, 1); }
+	var i = this.indexOf(el);
+	if (i !== -1) { this.splice(i, 1); }
 };
 
 
@@ -76,11 +76,11 @@ function SmalltalkOrganizer() {
 }
 
 function SmalltalkPackageOrganizer() {
-    this.elements = [];
+	this.elements = [];
 }
 
 function SmalltalkClassOrganizer() {
-    this.elements = [];
+	this.elements = [];
 }
 
 function inherits(child, parent) {
@@ -106,13 +106,13 @@ function Smalltalk() {
 	var st = this;
 
 	/* This is the current call context object. While it is publicly available,
-	   Use smalltalk.getThisContext() instead which will answer a safe copy of
-	   the current context */
+		Use smalltalk.getThisContext() instead which will answer a safe copy of
+		the current context */
 
 	st.thisContext = undefined;
 
 	/* List of all reserved words in JavaScript. They may not be used as variables
-	   in Smalltalk. */
+		in Smalltalk. */
 
 	// list of reserved JavaScript keywords as of
 	//   http://es5.github.com/#x7.6.1.1
@@ -128,14 +128,14 @@ function Smalltalk() {
 		'implements', 'interface', 'let', 'package', 'private', 'protected',
 		'public', 'static', 'yield'];
 
-    var initialized = false;
+	var initialized = false;
 
-    /* Smalltalk classes */
+	/* Smalltalk classes */
 
-    var classes = [];
-    var wrappedClasses = [];
+	var classes = [];
+	var wrappedClasses = [];
 
-    /* Method not implemented handlers */
+	/* Method not implemented handlers */
 
 	var dnu = {
 		methods: [],
@@ -163,11 +163,11 @@ function Smalltalk() {
 		}
 	};
 
-    /* Answer all method selectors based on dnu handlers */
+	/* Answer all method selectors based on dnu handlers */
 
-    st.allSelectors = function() {
-        return dnu.selectors;
-    };
+	st.allSelectors = function() {
+		return dnu.selectors;
+	};
 
 	/* Unique ID number generator */
 
@@ -186,15 +186,15 @@ function Smalltalk() {
 	function pkg(spec) {
 		var that = new SmalltalkPackage();
 		that.pkgName = spec.pkgName;
-        that.organization = new SmalltalkPackageOrganizer();
+		that.organization = new SmalltalkPackageOrganizer();
 		that.properties = spec.properties || {};
 		return that;
 	}
 
 	/* Smalltalk class creation. A class is an instance of an automatically
-	   created metaclass object. Newly created classes (not their metaclass) 
-	   should be added to the smalltalk object, see smalltalk.addClass().
-	   Superclass linking is *not* handled here, see smalltalk.init()  */
+		created metaclass object. Newly created classes (not their metaclass) 
+		should be added to the smalltalk object, see smalltalk.addClass().
+		Superclass linking is *not* handled here, see smalltalk.init()  */
 
 	function klass(spec) {
 		spec = spec || {};
@@ -203,8 +203,8 @@ function Smalltalk() {
 		that.fn = spec.fn || function() {};
 		setupClass(that, spec);
 
-        that.className = spec.className;
-        that.wrapped   = spec.wrapped || false;
+		that.className = spec.className;
+		that.wrapped   = spec.wrapped || false;
 		meta.className = spec.className + ' class';
 		if(spec.superclass) {
 			that.superclass = spec.superclass;
@@ -221,22 +221,22 @@ function Smalltalk() {
 			spec.superclass ? spec.superclass.klass.fn : SmalltalkClass
 		);
 		that.instanceClass = new that.fn();
-        setupClass(that);
+		setupClass(that);
 		return that;
 	}
 
 	function setupClass(klass, spec) {
-        spec = spec || {};
+		spec = spec || {};
 		klass.iVarNames = spec.iVarNames || [];
 		klass.pkg = spec.pkg;
 
-        Object.defineProperty(klass, "toString", {
+		Object.defineProperty(klass, "toString", {
 			value: function() { return 'Smalltalk ' + this.className; },
-            enumerable:false, configurable: true, writable: false
+			enumerable:false, configurable: true, writable: false
 		});
 
 		klass.organization          = new SmalltalkClassOrganizer();
-        klass.organization.theClass = klass;
+		klass.organization.theClass = klass;
 
 		Object.defineProperty(klass, "methods", {
 			value: {},
@@ -246,7 +246,7 @@ function Smalltalk() {
 	}
 
 	/* Smalltalk method object. To add a method to a class,
-	   use smalltalk.addMethod() */
+		use smalltalk.addMethod() */
 
 	st.method = function(spec) {
 		var that = new SmalltalkMethod();
@@ -262,7 +262,7 @@ function Smalltalk() {
 	};
 
 	/* Initialize a class in its class hierarchy. Handle both classes and
-	   metaclasses. */
+		metaclasses. */
 
 	st.init = function(klass) {
 		st.initClass(klass);
@@ -271,18 +271,17 @@ function Smalltalk() {
 		}
 	};
 
-    st.initClass = function(klass) {
-        if(klass.wrapped) {
-            copySuperclass(klass);
-        }
-        else {
-            installSuperclass(klass);
-        }
-
-        if(klass === st.Object || klass.wrapped) {
-            installDnuHandlers(klass);
-        }
-    };
+	st.initClass = function(klass) {
+		if(klass.wrapped) {
+			copySuperclass(klass);
+		} else {
+			installSuperclass(klass);
+		}
+
+		if(klass === st.Object || klass.wrapped) {
+			installDnuHandlers(klass);
+		}
+	};
 
 	function wireKlass(klass) {
 		Object.defineProperty(klass.fn.prototype, "klass", {
@@ -292,20 +291,20 @@ function Smalltalk() {
 	}
 
 	function installSuperclass(klass) {
-        // only if the klass has not been initialized yet.
+		// 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);
+			inherits(klass.fn, klass.superclass.fn);
 			wireKlass(klass);
 			reinstallMethods(klass);
-        }
+		}
 	}
 
 	function copySuperclass(klass, superclass) {
 		for (superclass = superclass || klass.superclass;
-			 superclass && superclass !== nil;
-			 superclass = superclass.superclass) {
+			superclass && superclass !== nil;
+			superclass = superclass.superclass) {
 			for (var keys = Object.keys(superclass.methods), i = 0; i < keys.length; i++) {
 				installMethodIfAbsent(superclass.methods[keys[i]], klass);
 			}
@@ -313,7 +312,7 @@ function Smalltalk() {
 	}
 
 	function installMethod(method, klass) {
-        Object.defineProperty(klass.fn.prototype, method.jsSelector, {
+		Object.defineProperty(klass.fn.prototype, method.jsSelector, {
 			value: method.fn,
 			enumerable: false, configurable: true, writable: true
 		});
@@ -326,16 +325,16 @@ function Smalltalk() {
 	}
 
 	function reinstallMethods(klass) {
-        for(var keys = Object.keys(klass.methods), i=0; i<keys.length; i++) {
-            installMethod(klass.methods[keys[i]], klass);
+		for(var keys = Object.keys(klass.methods), i=0; i<keys.length; i++) {
+			installMethod(klass.methods[keys[i]], klass);
 		}
 	}
 
 	function installDnuHandlers(klass) {
 		var m = dnu.methods;
-        for(var i=0; i<m.length; i++) {
+		for(var i=0; i<m.length; i++) {
 			installMethodIfAbsent(m[i], klass);
-        }
+		}
 	}
 
 	function installNewDnuHandler(newHandler) {
@@ -346,7 +345,7 @@ function Smalltalk() {
 	}
 
 	/* Answer all registered Packages as Array */
-    // TODO: Remove this hack
+	// TODO: Remove this hack
 
 	st.packages.all = function() {
 		var packages = [];
@@ -354,19 +353,19 @@ function Smalltalk() {
 			if(!st.packages.hasOwnProperty(i) || typeof(st.packages[i]) === "function") continue;
 			packages.push(st.packages[i]);
 		}
-		return packages
+		return packages;
 	};
 
 	/* Answer all registered Smalltalk classes */
-    //TODO: remove the function and make smalltalk.classes an array
+	//TODO: remove the function and make smalltalk.classes an array
 
 	st.classes = function() {
 		return classes;
 	};
 
-    st.wrappedClasses = function() {
-        return wrappedClasses;
-    };
+	st.wrappedClasses = function() {
+		return wrappedClasses;
+	};
 
 	/* Answer the direct subclasses of klass. */
 
@@ -390,35 +389,37 @@ function Smalltalk() {
 		return subclasses;
 	};
 
-    st.allSubclasses = function(klass) {
-        var result, subclasses;
-        result = subclasses = st.subclasses(klass);
-        subclasses.forEach(function(subclass) {
-            result.push.apply(result, st.allSubclasses(subclass));
-        });
-
-        return result;
-    };
+	st.allSubclasses = function(klass) {
+		var result, subclasses;
+		result = subclasses = st.subclasses(klass);
+		subclasses.forEach(function(subclass) {
+			result.push.apply(result, st.allSubclasses(subclass));
+		});
+	
+		return result;
+	};
 
 
 	/* Create a new class wrapping a JavaScript constructor, and add it to the
-	   global smalltalk object. Package is lazily created if it does not exist with given name. */
+		global smalltalk object. Package is lazily created if it does not exist with given name. */
 
 	st.wrapClassName = function(className, pkgName, fn, superclass, wrapped) {
-        if(wrapped !== false) {
-            wrapped = true;
-        }
+		if(wrapped !== false) {
+			wrapped = true;
+		}
 		var pkg = st.addPackage(pkgName);
 		st[className] = klass({
 			className:  className,
 			superclass: superclass,
 			pkg:        pkg,
 			fn:         fn,
-            wrapped:    wrapped
+			wrapped:    wrapped
 		});
 
-        classes.addElement(st[className]);
-		if(wrapped) {wrappedClasses.addElement(st[className])}
+		classes.addElement(st[className]);
+		if(wrapped) {
+			wrappedClasses.addElement(st[className]);
+		}
 		pkg.organization.elements.addElement(st[className]);
 	};
 
@@ -429,8 +430,8 @@ function Smalltalk() {
 	};
 
 	/* Add a package to the smalltalk.packages object, creating a new one if needed.
-	   If pkgName is null or empty we return nil, which is an allowed package for a class.
-	   If package already exists we still update the properties of it. */
+		If pkgName is null or empty we return nil, which is an allowed package for a class.
+		If package already exists we still update the properties of it. */
 
 	st.addPackage = function(pkgName, properties) {
 		if(!pkgName) {return nil;}
@@ -448,18 +449,18 @@ function Smalltalk() {
 	};
 
 	/* Add a class to the smalltalk object, creating a new one if needed.
-	   A Package is lazily created if it does not exist with given name. */
+		A Package is lazily created if it does not exist with given name. */
 
 	st.addClass = function(className, superclass, iVarNames, pkgName) {
 		var pkg = st.addPackage(pkgName);
-        if (superclass == nil) { superclass = null; }
+		if (superclass == nil) { superclass = null; }
 		if(st[className] && st[className].superclass == superclass) {
 			st[className].superclass = superclass;
 			st[className].iVarNames = iVarNames;
 			st[className].pkg = pkg || st[className].pkg;
 		} else {
-            if(st[className]) {
-                st.removeClass(st[className]);
+			if(st[className]) {
+				st.removeClass(st[className]);
 			}
 			st[className] = klass({
 				className: className,
@@ -469,114 +470,113 @@ function Smalltalk() {
 			});
 		}
 
-        classes.addElement(st[className]);
-        pkg.organization.elements.addElement(st[className]);
+		classes.addElement(st[className]);
+		pkg.organization.elements.addElement(st[className]);
 	};
 
-    st.removeClass = function(klass) {
-        klass.pkg.organization.elements.removeElement(klass);
-        classes.removeElement(klass);
-        delete st[klass.className];
-    };
+	st.removeClass = function(klass) {
+		klass.pkg.organization.elements.removeElement(klass);
+		classes.removeElement(klass);
+		delete st[klass.className];
+	};
 
-	/* 
-     * Add/remove a method to/from a class 
-     */
+	/* Add/remove a method to/from a class */
 
-    /* This is a temporary version of addMethod() for backward compatibility */
+	/* This is a temporary version of addMethod() for backward compatibility */
 	st.addMethod = function(method_exJsSelector, klass_exMethod, exKlass) {
-        if (typeof method_exJsSelector === "string") { //legacy
-            if (method_exJsSelector !== st.selector(klass_exMethod.selector)) {
-                console.log("DISCREPANCY: arg, in_method");
-                console.log(method_exJsSelector);
-                console.log(st.selector(klass_exMethod.selector));
-                klass_exMethod.jsSelector = method_exJsSelector;
-            }
-            return new_addMethod(klass_exMethod, exKlass);
-        }
-
-        return new_addMethod(method_exJsSelector, klass_exMethod);
-    }
-
-    // later, st.addMethod can be this:
-    function new_addMethod(method, klass) {
-        if (!(method.jsSelector)) {
-            method.jsSelector = st.selector(method.selector);
-        }
+		if (typeof method_exJsSelector === "string") { //legacy
+			if (method_exJsSelector !== st.selector(klass_exMethod.selector)) {
+				console.log("DISCREPANCY: arg, in_method");
+				console.log(method_exJsSelector);
+				console.log(st.selector(klass_exMethod.selector));
+				klass_exMethod.jsSelector = method_exJsSelector;
+			}
+			return new_addMethod(klass_exMethod, exKlass);
+		}
+	
+		return new_addMethod(method_exJsSelector, klass_exMethod);
+	};
+	
+	// later, st.addMethod can be this:
+	function new_addMethod(method, klass) {
+		if (!(method.jsSelector)) {
+			method.jsSelector = st.selector(method.selector);
+		}
 		installMethod(method, klass);
 		klass.methods[method.selector] = method;
 		method.methodClass = klass;
 
-        // During the bootstrap, #addCompiledMethod is not used.
-        // 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);
-            });
-        }
-
-        for(var i=0; i<method.messageSends.length; i++) {
-            var dnuHandler = dnu.get(method.messageSends[i]);
-            if(initialized) {
-                installNewDnuHandler(dnuHandler);
+		// During the bootstrap, #addCompiledMethod is not used.
+		// 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);
+			});
+		}
+	
+		for(var i=0; i<method.messageSends.length; i++) {
+			var dnuHandler = dnu.get(method.messageSends[i]);
+			if(initialized) {
+				installNewDnuHandler(dnuHandler);
 			}
 		}
-	};
+	}
 
-    st.removeMethod = function(method) {
-        var protocol = method.category;
-        var klass = method.methodClass;
+	st.removeMethod = function(method) {
+		var protocol = method.category;
+		var klass = method.methodClass;
 
-        delete klass.fn.prototype[st.selector(method.selector)];
-	    delete klass.methods[method.selector];
+		delete klass.fn.prototype[st.selector(method.selector)];
+		delete klass.methods[method.selector];
 
 		var selectors = Object.keys(klass.methods);
-        // Do *not* delete protocols from here.
-        // This is handled by #removeCompiledMethod
-    };
+		// Do *not* delete protocols from here.
+		// This is handled by #removeCompiledMethod
+	};
 
 	/* Handles unhandled errors during message sends */
-    // simply send the message and handle #dnu:
+	// simply send the message and handle #dnu:
 
 	st.send = function(receiver, selector, args, klass) {
 		var method;
-		if(receiver == null) {
+		if(receiver === null) {
 			receiver = nil;
 		}
 		method = klass ? klass.fn.prototype[selector] : receiver.klass && receiver[selector];
 		if(method) {
-            return method.apply(receiver, args);
+			return method.apply(receiver, args);
 		} else {
 			return messageNotUnderstood(receiver, selector, args);
 		}
-	}
+	};
 
 	st.withContext = function(worker, setup, index) {
 		if(st.thisContext) {
             st.thisContext.pc++;
 			return inContext(worker, setup, index);
 		} else {
-			try {return inContext(worker, setup)}
-			catch(error) {
+			try {
+				return inContext(worker, setup);
+			} catch(error) {
 				if(error.smalltalkError) {
 					handleError(error);
-                } else {
-                    var errorWrapper = st.JavaScriptException._on_(error);
-                    try {errorWrapper._signal()} catch(ex) {}
-                    errorWrapper._context_(st.getThisContext());
-                    handleError(errorWrapper);
-                }
+				} else {
+					var errorWrapper = st.JavaScriptException._on_(error);
+					try {errorWrapper._signal();} catch(ex) {}
+					errorWrapper._context_(st.getThisContext());
+					handleError(errorWrapper);
+				}
 				// Reset the context stack in any case
 				st.thisContext = undefined;
-                // Throw the exception anyway, as we want to stop
-                // the execution to avoid infinite loops
-                // Update: do not throw the exception. It's really annoying.
+				// Throw the exception anyway, as we want to stop
+				// the execution to avoid infinite loops
+				// Update: do not throw the exception. It's really annoying.
 				// throw error;
 			}
 		}
@@ -591,15 +591,15 @@ function Smalltalk() {
 	}
 
 	/* Handles Smalltalk errors. Triggers the registered ErrorHandler
-	   (See the Smalltalk class ErrorHandler and its subclasses */
+		(See the Smalltalk class ErrorHandler and its subclasses */
 
 	function handleError(error) {
-        st.ErrorHandler._current()._handleError_(error);
+		st.ErrorHandler._current()._handleError_(error);
 	}
 
 	/* Handles #dnu: *and* JavaScript method calls.
-	   if the receiver has no klass, we consider it a JS object (outside of the
-	   Amber system). Else assume that the receiver understands #doesNotUnderstand: */
+		if the receiver has no klass, we consider it a JS object (outside of the
+		Amber system). Else assume that the receiver understands #doesNotUnderstand: */
 
 	function messageNotUnderstood(receiver, selector, args) {
 		/* Handles JS method calls. */
@@ -608,7 +608,7 @@ function Smalltalk() {
 		}
 
 		/* Handles not understood messages. Also see the Amber counter-part
-		   Object>>doesNotUnderstand: */
+			Object>>doesNotUnderstand: */
 
 		return receiver._doesNotUnderstand_(
 			st.Message._new()
@@ -618,17 +618,17 @@ function Smalltalk() {
 	}
 
 	/* Call a method of a JS object, or answer a property if it exists.
-	   Else try wrapping a JSObjectProxy around the receiver.
+		Else try wrapping a JSObjectProxy around the receiver.
 
-       If the object property is a function, then call it, except if it starts with
-       an uppercase character (we probably want to answer the function itself in this
-       case and send it #new from Amber).
+		If the object property is a function, then call it, except if it starts with
+		an uppercase character (we probably want to answer the function itself in this
+		case and send it #new from Amber).
 
-	   Converts keyword-based selectors by using the first
-	   keyword only, but keeping all message arguments.
-
-	   Example:
-	   "self do: aBlock with: anObject" -> "self.do(aBlock, anObject)" */
+		Converts keyword-based selectors by using the first
+		keyword only, but keeping all message arguments.
+		
+		Example:
+		"self do: aBlock with: anObject" -> "self.do(aBlock, anObject)" */
 
 	function callJavaScriptMethod(receiver, selector, args) {
 		var jsSelector = selector._asJavaScriptSelector();
@@ -650,16 +650,17 @@ function Smalltalk() {
 	/* Handle thisContext pseudo variable */
 
 	st.getThisContext = function() {
-        if(st.thisContext) {
-		    st.thisContext.init();
-            return st.thisContext;
-        } else {
-            return nil;
-        }
+		if(st.thisContext) {
+			st.thisContext.init();
+			return st.thisContext;
+		} else {
+			return nil;
+		}
 	};
 
 	function pushContext(setup) {
-		return st.thisContext = new SmalltalkMethodContext(smalltalk.thisContext, setup);
+		st.thisContext = new SmalltalkMethodContext(smalltalk.thisContext, setup);
+		return st.thisContext;
 	}
 
 	function popContext(context) {
@@ -668,28 +669,28 @@ function Smalltalk() {
 
 	/* Convert a Smalltalk selector into a JS selector */
 
-    st.selector = function(string) {
-        var selector = '_' + string;
-	    selector = selector.replace(/:/g, '_');
-	    selector = selector.replace(/[\&]/g, '_and');
-	    selector = selector.replace(/[\|]/g, '_or');
-	    selector = selector.replace(/[+]/g, '_plus');
-	    selector = selector.replace(/-/g, '_minus');
-	    selector = selector.replace(/[*]/g ,'_star');
-	    selector = selector.replace(/[\/]/g ,'_slash');
-	    selector = selector.replace(/[\\]/g ,'_backslash');
-	    selector = selector.replace(/[\~]/g ,'_tild');
-	    selector = selector.replace(/>/g ,'_gt');
-	    selector = selector.replace(/</g ,'_lt');
-	    selector = selector.replace(/=/g ,'_eq');
-	    selector = selector.replace(/,/g ,'_comma');
-	    selector = selector.replace(/[@]/g ,'_at');
-        return selector
-    };
+	st.selector = function(string) {
+		var selector = '_' + string;
+		selector = selector.replace(/:/g, '_');
+		selector = selector.replace(/[\&]/g, '_and');
+		selector = selector.replace(/[\|]/g, '_or');
+		selector = selector.replace(/[+]/g, '_plus');
+		selector = selector.replace(/-/g, '_minus');
+		selector = selector.replace(/[*]/g ,'_star');
+		selector = selector.replace(/[\/]/g ,'_slash');
+		selector = selector.replace(/[\\]/g ,'_backslash');
+		selector = selector.replace(/[\~]/g ,'_tild');
+		selector = selector.replace(/>/g ,'_gt');
+		selector = selector.replace(/</g ,'_lt');
+		selector = selector.replace(/=/g ,'_eq');
+		selector = selector.replace(/,/g ,'_comma');
+		selector = selector.replace(/[@]/g ,'_at');
+		return selector;
+	};
 
 	/* Convert a string to a valid smalltalk selector.
-	   if you modify the following functions, also change String>>asSelector
-	   accordingly */
+		if you modify the following functions, also change String>>asSelector
+		accordingly */
 
 	st.convertSelector = function(selector) {
 		if(selector.match(/__/)) {
@@ -718,7 +719,7 @@ function Smalltalk() {
 			.replace(/_lt/g, '<')
 			.replace(/_eq/g, '=')
 			.replace(/_comma/g, ',')
-			.replace(/_at/g, '@')
+			.replace(/_at/g, '@');
 	}
 
 	/* Converts a JavaScript object to valid Smalltalk Object */
@@ -741,40 +742,40 @@ function Smalltalk() {
 		return object;
 	};
 
-    /* Boolean assertion */
-    st.assert = function(shouldBeBoolean) {
-        if ((undefined !== shouldBeBoolean) && (shouldBeBoolean.klass === smalltalk.Boolean)) {
-            return shouldBeBoolean == true;
-        } else {
-            smalltalk.NonBooleanReceiver._new()._object_(shouldBeBoolean)._signal();
-        }
+	/* Boolean assertion */
+	st.assert = function(shouldBeBoolean) {
+		if ((undefined !== shouldBeBoolean) && (shouldBeBoolean.klass === smalltalk.Boolean)) {
+			return (shouldBeBoolean == true);
+		} else {
+			smalltalk.NonBooleanReceiver._new()._object_(shouldBeBoolean)._signal();
+		}
     };
 
-    /* Backward compatibility with Amber 0.9.1 */
-    st.symbolFor = function(aString) { return aString; }
-
-    /* Smalltalk initialization. Called on page load */
-
-    st.initialize = function() {
+	/* Backward compatibility with Amber 0.9.1 */
+	st.symbolFor = function(aString) { return aString; };
+	
+	/* Smalltalk initialization. Called on page load */
+	
+	st.initialize = function() {
 		if(initialized) { return; }
 
 		classes.forEach(function(klass) {
-            st.init(klass);
-        });
-        classes.forEach(function(klass) {
-            klass._initialize();
-        });
-
-        initialized = true;
-    };
+			st.init(klass);
+		});
+		classes.forEach(function(klass) {
+			klass._initialize();
+		});
+	
+		initialized = true;
+	};
 }
 
 inherits(Smalltalk, SmalltalkObject);
 
 function SmalltalkMethodContext(home, setup) {
 	this.homeContext = home;
-    this.setup       = setup || function() {};
-    this.pc          = 0;
+	this.setup       = setup || function() {};
+	this.pc          = 0;
 }
 
 // Fallbacks
@@ -786,39 +787,41 @@ SmalltalkMethodContext.prototype.lookupClass = null;
 inherits(SmalltalkMethodContext, SmalltalkObject);
 
 SmalltalkMethodContext.prototype.fill = function(receiver, selector, locals, lookupClass) {
-    this.receiver    = receiver;
-    this.selector    = selector;
-    this.locals      = locals || {};
-    this.lookupClass = lookupClass;
+	this.receiver    = receiver;
+	this.selector    = selector;
+	this.locals      = locals || {};
+	this.lookupClass = lookupClass;
 };
 
 SmalltalkMethodContext.prototype.fillBlock = function(locals, ctx) {
-    this.locals        = locals || {};
-    this.outerContext  = ctx;
+	this.locals        = locals || {};
+	this.outerContext  = ctx;
 };
 
 SmalltalkMethodContext.prototype.init = function() {
 	var home = this.homeContext;
-	if(home) {home = home.init()}
+	if(home) {
+		home = home.init();
+	}
 
     this.setup(this);
 };
 
 SmalltalkMethodContext.prototype.method = function() {
-    var method;
-    var lookup = this.lookupClass || this.receiver.klass;
-    while(!method && lookup) {
-        method = lookup.methods[smalltalk.convertSelector(this.selector)];
-        lookup = lookup.superclass
-    }
-    return method;
+	var method;
+	var lookup = this.lookupClass || this.receiver.klass;
+	while(!method && lookup) {
+		method = lookup.methods[smalltalk.convertSelector(this.selector)];
+		lookup = lookup.superclass;
+	}
+	return method;
 };
 
 // TODO: this is just wrong :)
 SmalltalkMethodContext.prototype.resume = function() {
-    //Brutally set the receiver as thisContext, then re-enter the function
-    smalltalk.thisContext = this;
-    return this.method.apply(receiver, temps);
+	//Brutally set the receiver as thisContext, then re-enter the function
+	smalltalk.thisContext = this;
+	return this.method.apply(receiver, temps);
 };
 
 /* Global Smalltalk objects. */
@@ -836,8 +839,8 @@ if(this.jQuery) {
  */
 
 var _st = function(o) {
-	if(o == null) {return nil}
-	if(o.klass) {return o}
+	if(o == null) {return nil;}
+	if(o.klass) {return o;}
 	return smalltalk.JSObjectProxy._on_(o);
 }; 
 

+ 87 - 86
js/parser.js

@@ -451,7 +451,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, first, others) {return first + others.join("")})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
+          result0 = (function(offset, line, column, first, others) {return first + others.join("");})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -520,7 +520,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, first, others) {return first + others.join("")})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
+          result0 = (function(offset, line, column, first, others) {return first + others.join("");})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -568,7 +568,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, first, last) {return first + last})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
+          result0 = (function(offset, line, column, first, last) {return first + last;})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -637,7 +637,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, first, others) {return first + others.join("")})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
+          result0 = (function(offset, line, column, first, others) {return first + others.join("");})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -706,7 +706,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, first, others) {return first + others.join("")})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
+          result0 = (function(offset, line, column, first, others) {return first + others.join("");})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -754,7 +754,7 @@ smalltalk.parser = (function(){
             }
           }
           if (result2 !== null) {
-            result2 = (function(offset, line, column) {return "'"})(pos2.offset, pos2.line, pos2.column);
+            result2 = (function(offset, line, column) {return "'";})(pos2.offset, pos2.line, pos2.column);
           }
           if (result2 === null) {
             pos = clone(pos2);
@@ -783,7 +783,7 @@ smalltalk.parser = (function(){
               }
             }
             if (result2 !== null) {
-              result2 = (function(offset, line, column) {return "'"})(pos2.offset, pos2.line, pos2.column);
+              result2 = (function(offset, line, column) {return "'";})(pos2.offset, pos2.line, pos2.column);
             }
             if (result2 === null) {
               pos = clone(pos2);
@@ -827,8 +827,8 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, val) {
                              return smalltalk.ValueNode._new()
-        		     	    ._position_((line).__at(column))
-                                    ._value_(val.join("").replace(/\"/ig, '"'))
+                                    ._position_((line).__at(column))
+                                    ._value_(val.join("").replace(/\"/ig, '"'));
                          })(pos0.offset, pos0.line, pos0.column, result0[1]);
         }
         if (result0 === null) {
@@ -877,7 +877,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, rest) {return rest})(pos0.offset, pos0.line, pos0.column, result0[1]);
+          result0 = (function(offset, line, column, rest) {return rest;})(pos0.offset, pos0.line, pos0.column, result0[1]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -909,7 +909,7 @@ smalltalk.parser = (function(){
             pos1 = clone(pos);
             result0 = parse_string();
             if (result0 !== null) {
-              result0 = (function(offset, line, column, node) {return node._value()})(pos1.offset, pos1.line, pos1.column, result0);
+              result0 = (function(offset, line, column, node) {return node._value();})(pos1.offset, pos1.line, pos1.column, result0);
             }
             if (result0 === null) {
               pos = clone(pos1);
@@ -919,8 +919,8 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, val) {
                               return smalltalk.ValueNode._new()
-        		      	     ._position_((line).__at(column))
-                                     ._value_(val)
+                                     ._position_((line).__at(column))
+                                     ._value_(val);
                           })(pos0.offset, pos0.line, pos0.column, result0);
         }
         if (result0 === null) {
@@ -956,8 +956,8 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, n) {
                              return smalltalk.ValueNode._new()
-        		     	    ._position_((line).__at(column))
-                                    ._value_(n)
+                                    ._position_((line).__at(column))
+                                    ._value_(n);
                          })(pos0.offset, pos0.line, pos0.column, result0);
         }
         if (result0 === null) {
@@ -1046,7 +1046,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, neg, num) {return parseInt((neg + num.join("")), 16)})(pos0.offset, pos0.line, pos0.column, result0[0], result0[2]);
+          result0 = (function(offset, line, column, neg, num) {return parseInt((neg + num.join("")), 16);})(pos0.offset, pos0.line, pos0.column, result0[0], result0[2]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -1165,7 +1165,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, neg, int, dec) {return parseFloat((neg + int.join("") + "." + dec.join("")), 10)})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1], result0[3]);
+          result0 = (function(offset, line, column, neg, digits, dec) {return parseFloat((neg + digits.join("") + "." + dec.join("")), 10);})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1], result0[3]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -1239,7 +1239,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, neg, digits) {return (parseInt(neg+digits.join(""), 10))})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
+          result0 = (function(offset, line, column, neg, digits) {return (parseInt(neg+digits.join(""), 10));})(pos0.offset, pos0.line, pos0.column, result0[0], result0[1]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -1287,7 +1287,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, rest) {return rest})(pos0.offset, pos0.line, pos0.column, result0[1]);
+          result0 = (function(offset, line, column, rest) {return rest;})(pos0.offset, pos0.line, pos0.column, result0[1]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -1335,7 +1335,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, rest) {return rest})(pos0.offset, pos0.line, pos0.column, result0[1]);
+          result0 = (function(offset, line, column, rest) {return rest;})(pos0.offset, pos0.line, pos0.column, result0[1]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -1386,7 +1386,7 @@ smalltalk.parser = (function(){
             pos = clone(pos3);
           }
           if (result2 !== null) {
-            result2 = (function(offset, line, column, lit) {return lit._value()})(pos2.offset, pos2.line, pos2.column, result2[0]);
+            result2 = (function(offset, line, column, lit) {return lit._value();})(pos2.offset, pos2.line, pos2.column, result2[0]);
           }
           if (result2 === null) {
             pos = clone(pos2);
@@ -1415,7 +1415,7 @@ smalltalk.parser = (function(){
               pos = clone(pos3);
             }
             if (result2 !== null) {
-              result2 = (function(offset, line, column, lit) {return lit._value()})(pos2.offset, pos2.line, pos2.column, result2[0]);
+              result2 = (function(offset, line, column, lit) {return lit._value();})(pos2.offset, pos2.line, pos2.column, result2[0]);
             }
             if (result2 === null) {
               pos = clone(pos2);
@@ -1454,8 +1454,8 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, lits) {
                              return smalltalk.ValueNode._new()
-        		     	    ._position_((line).__at(column))
-                                    ._value_(lits)
+                                    ._position_((line).__at(column))
+                                    ._value_(lits);
                          })(pos0.offset, pos0.line, pos0.column, result0[1]);
         }
         if (result0 === null) {
@@ -1548,8 +1548,8 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, expressions) {
                              return smalltalk.DynamicArrayNode._new()
-        		     	    ._position_((line).__at(column))
-                                    ._nodes_(expressions)
+                                    ._position_((line).__at(column))
+                                    ._nodes_(expressions);
                          })(pos0.offset, pos0.line, pos0.column, result0[2]);
         }
         if (result0 === null) {
@@ -1627,8 +1627,8 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, expressions) {
                                 return smalltalk.DynamicDictionaryNode._new()
-        			       ._position_((line).__at(column))
-                                       ._nodes_(expressions)
+                                       ._position_((line).__at(column))
+                                       ._nodes_(expressions);
                             })(pos0.offset, pos0.line, pos0.column, result0[2]);
         }
         if (result0 === null) {
@@ -1665,7 +1665,7 @@ smalltalk.parser = (function(){
           }
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column) {return true})(pos1.offset, pos1.line, pos1.column);
+          result0 = (function(offset, line, column) {return true;})(pos1.offset, pos1.line, pos1.column);
         }
         if (result0 === null) {
           pos = clone(pos1);
@@ -1682,7 +1682,7 @@ smalltalk.parser = (function(){
             }
           }
           if (result0 !== null) {
-            result0 = (function(offset, line, column) {return false})(pos1.offset, pos1.line, pos1.column);
+            result0 = (function(offset, line, column) {return false;})(pos1.offset, pos1.line, pos1.column);
           }
           if (result0 === null) {
             pos = clone(pos1);
@@ -1699,7 +1699,7 @@ smalltalk.parser = (function(){
               }
             }
             if (result0 !== null) {
-              result0 = (function(offset, line, column) {return nil})(pos1.offset, pos1.line, pos1.column);
+              result0 = (function(offset, line, column) {return nil;})(pos1.offset, pos1.line, pos1.column);
             }
             if (result0 === null) {
               pos = clone(pos1);
@@ -1709,8 +1709,8 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, val) {
                                return smalltalk.ValueNode._new()
-        		       	      ._position_((line).__at(column))
-                                      ._value_(val)
+                                      ._position_((line).__at(column))
+                                      ._value_(val);
                            })(pos0.offset, pos0.line, pos0.column, result0);
         }
         if (result0 === null) {
@@ -1818,8 +1818,8 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, identifier) {
                              return smalltalk.VariableNode._new()
-        		     	    ._position_((line).__at(column))
-                                    ._value_(identifier)
+                                    ._position_((line).__at(column))
+                                    ._value_(identifier);
                          })(pos0.offset, pos0.line, pos0.column, result0);
         }
         if (result0 === null) {
@@ -1849,8 +1849,8 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, className) {
                              return smalltalk.ClassReferenceNode._new()
-        		     	    ._position_((line).__at(column))
-                                    ._value_(className)
+                                    ._position_((line).__at(column))
+                                    ._value_(className);
                          })(pos0.offset, pos0.line, pos0.column, result0);
         }
         if (result0 === null) {
@@ -1925,7 +1925,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, key, arg) {return {key:key, arg: arg}})(pos0.offset, pos0.line, pos0.column, result0[0], result0[2]);
+          result0 = (function(offset, line, column, key, arg) {return {key:key, arg: arg};})(pos0.offset, pos0.line, pos0.column, result0[0], result0[2]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -1977,7 +1977,7 @@ smalltalk.parser = (function(){
           result0 = null;
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, bin) {return bin.join("")})(pos0.offset, pos0.line, pos0.column, result0);
+          result0 = (function(offset, line, column, bin) {return bin.join("");})(pos0.offset, pos0.line, pos0.column, result0);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -2030,7 +2030,7 @@ smalltalk.parser = (function(){
           pos = clone(pos2);
         }
         if (result1 !== null) {
-          result1 = (function(offset, line, column, key, arg) {return {key:key, arg: arg}})(pos1.offset, pos1.line, pos1.column, result1[1], result1[3]);
+          result1 = (function(offset, line, column, key, arg) {return {key:key, arg: arg};})(pos1.offset, pos1.line, pos1.column, result1[1], result1[3]);
         }
         if (result1 === null) {
           pos = clone(pos1);
@@ -2067,7 +2067,7 @@ smalltalk.parser = (function(){
               pos = clone(pos2);
             }
             if (result1 !== null) {
-              result1 = (function(offset, line, column, key, arg) {return {key:key, arg: arg}})(pos1.offset, pos1.line, pos1.column, result1[1], result1[3]);
+              result1 = (function(offset, line, column, key, arg) {return {key:key, arg: arg};})(pos1.offset, pos1.line, pos1.column, result1[1], result1[3]);
             }
             if (result1 === null) {
               pos = clone(pos1);
@@ -2080,13 +2080,14 @@ smalltalk.parser = (function(){
           result0 = (function(offset, line, column, pairs) {
                              var keywords = [];
                              var params = [];
-                             for(var i=0;i<pairs.length;i++){
+                             var i = 0;
+                             for(i = 0; i < pairs.length; i++){
                                  keywords.push(pairs[i].key);
                              }
-                             for(var i=0;i<pairs.length;i++){
+                             for(i = 0; i < pairs.length; i++){
                                  params.push(pairs[i].arg);
                              }
-                             return [keywords.join(""), params]
+                             return [keywords.join(""), params];
                          })(pos0.offset, pos0.line, pos0.column, result0);
         }
         if (result0 === null) {
@@ -2139,7 +2140,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, selector, arg) {return [selector, [arg]]})(pos0.offset, pos0.line, pos0.column, result0[1], result0[3]);
+          result0 = (function(offset, line, column, selector, arg) {return [selector, [arg]];})(pos0.offset, pos0.line, pos0.column, result0[1], result0[3]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -2179,7 +2180,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, selector) {return [selector, []]})(pos0.offset, pos0.line, pos0.column, result0[1]);
+          result0 = (function(offset, line, column, selector) {return [selector, []];})(pos0.offset, pos0.line, pos0.column, result0[1]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -2267,7 +2268,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, expression) {return expression})(pos0.offset, pos0.line, pos0.column, result0[3]);
+          result0 = (function(offset, line, column, expression) {return expression;})(pos0.offset, pos0.line, pos0.column, result0[3]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -2314,7 +2315,7 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, first, others) {
                              var result = [first];
-                             for(var i=0;i<others.length;i++) {
+                             for(var i = 0; i < others.length; i++) {
                                  result.push(others[i]);
                              }
                              return result;
@@ -2386,9 +2387,9 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, variable, expression) {
                              return smalltalk.AssignmentNode._new()
-        		     	    ._position_((line).__at(column))
+                                    ._position_((line).__at(column))
                                     ._left_(variable)
-                                    ._right_(expression)
+                                    ._right_(expression);
                          })(pos0.offset, pos0.line, pos0.column, result0[0], result0[4]);
         }
         if (result0 === null) {
@@ -2466,8 +2467,8 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, expression) {
                              return smalltalk.ReturnNode._new()
-        		     	    ._position_((line).__at(column))
-                                    ._nodes_([expression])
+                                    ._position_((line).__at(column))
+                                    ._nodes_([expression]);
                          })(pos0.offset, pos0.line, pos0.column, result0[2]);
         }
         if (result0 === null) {
@@ -2527,7 +2528,7 @@ smalltalk.parser = (function(){
             pos = clone(pos3);
           }
           if (result2 !== null) {
-            result2 = (function(offset, line, column, variable) {return variable})(pos2.offset, pos2.line, pos2.column, result2[1]);
+            result2 = (function(offset, line, column, variable) {return variable;})(pos2.offset, pos2.line, pos2.column, result2[1]);
           }
           if (result2 === null) {
             pos = clone(pos2);
@@ -2556,7 +2557,7 @@ smalltalk.parser = (function(){
               pos = clone(pos3);
             }
             if (result2 !== null) {
-              result2 = (function(offset, line, column, variable) {return variable})(pos2.offset, pos2.line, pos2.column, result2[1]);
+              result2 = (function(offset, line, column, variable) {return variable;})(pos2.offset, pos2.line, pos2.column, result2[1]);
             }
             if (result2 === null) {
               pos = clone(pos2);
@@ -2587,7 +2588,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, vars) {return vars})(pos0.offset, pos0.line, pos0.column, result0[1]);
+          result0 = (function(offset, line, column, vars) {return vars;})(pos0.offset, pos0.line, pos0.column, result0[1]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -2649,7 +2650,7 @@ smalltalk.parser = (function(){
           pos = clone(pos3);
         }
         if (result1 !== null) {
-          result1 = (function(offset, line, column, param) {return param})(pos2.offset, pos2.line, pos2.column, result1[3]);
+          result1 = (function(offset, line, column, param) {return param;})(pos2.offset, pos2.line, pos2.column, result1[3]);
         }
         if (result1 === null) {
           pos = clone(pos2);
@@ -2694,7 +2695,7 @@ smalltalk.parser = (function(){
               pos = clone(pos3);
             }
             if (result1 !== null) {
-              result1 = (function(offset, line, column, param) {return param})(pos2.offset, pos2.line, pos2.column, result1[3]);
+              result1 = (function(offset, line, column, param) {return param;})(pos2.offset, pos2.line, pos2.column, result1[3]);
             }
             if (result1 === null) {
               pos = clone(pos2);
@@ -2730,7 +2731,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, params) {return params})(pos0.offset, pos0.line, pos0.column, result0[0]);
+          result0 = (function(offset, line, column, params) {return params;})(pos0.offset, pos0.line, pos0.column, result0[0]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -2804,7 +2805,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, expression) {return expression})(pos0.offset, pos0.line, pos0.column, result0[2]);
+          result0 = (function(offset, line, column, expression) {return expression;})(pos0.offset, pos0.line, pos0.column, result0[2]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -2865,7 +2866,7 @@ smalltalk.parser = (function(){
           pos = clone(pos1);
         }
         if (result0 !== null) {
-          result0 = (function(offset, line, column, ret) {return [ret]})(pos0.offset, pos0.line, pos0.column, result0[0]);
+          result0 = (function(offset, line, column, ret) {return [ret];})(pos0.offset, pos0.line, pos0.column, result0[0]);
         }
         if (result0 === null) {
           pos = clone(pos0);
@@ -2960,7 +2961,7 @@ smalltalk.parser = (function(){
             result0 = (function(offset, line, column, exps, ret) {
                                  var expressions = exps;
                                  expressions.push(ret);
-                                 return expressions
+                                 return expressions;
                              })(pos0.offset, pos0.line, pos0.column, result0[0], result0[4]);
           }
           if (result0 === null) {
@@ -3006,7 +3007,7 @@ smalltalk.parser = (function(){
             }
             if (result0 !== null) {
               result0 = (function(offset, line, column, expressions) {
-                                   return expressions || []
+                                   return expressions || [];
                                })(pos0.offset, pos0.line, pos0.column, result0[0]);
             }
             if (result0 === null) {
@@ -3087,9 +3088,9 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, temps, statements) {
                              return smalltalk.SequenceNode._new()
-        		     	    ._position_((line).__at(column))
+                                    ._position_((line).__at(column))
                                     ._temps_(temps || [])
-                                    ._nodes_(statements || [])
+                                    ._nodes_(statements || []);
                          })(pos0.offset, pos0.line, pos0.column, result0[0], result0[2]);
         }
         if (result0 === null) {
@@ -3180,9 +3181,9 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, params, sequence) {
                              return smalltalk.BlockNode._new()
-        		     	    ._position_((line).__at(column))
+                                    ._position_((line).__at(column))
                                     ._parameters_(params || [])
-                                    ._nodes_([sequence._asBlockSequenceNode()])
+                                    ._nodes_([sequence._asBlockSequenceNode()]);
                          })(pos0.offset, pos0.line, pos0.column, result0[2], result0[4]);
         }
         if (result0 === null) {
@@ -3273,8 +3274,8 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, selector) {
                              return smalltalk.SendNode._new()
-        		     	    ._position_((line).__at(column))
-                                    ._selector_(selector)
+                                    ._position_((line).__at(column))
+                                    ._selector_(selector);
                          })(pos0.offset, pos0.line, pos0.column, result0[1]);
         }
         if (result0 === null) {
@@ -3446,9 +3447,9 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, selector, arg) {
                              return smalltalk.SendNode._new()
-        		     	    ._position_((line).__at(column))
+                                    ._position_((line).__at(column))
                                     ._selector_(selector)
-                                    ._arguments_([arg])
+                                    ._arguments_([arg]);
                          })(pos0.offset, pos0.line, pos0.column, result0[1], result0[3]);
         }
         if (result0 === null) {
@@ -3589,7 +3590,7 @@ smalltalk.parser = (function(){
             pos = clone(pos3);
           }
           if (result2 !== null) {
-            result2 = (function(offset, line, column, pair) {return pair})(pos2.offset, pos2.line, pos2.column, result2[0]);
+            result2 = (function(offset, line, column, pair) {return pair;})(pos2.offset, pos2.line, pos2.column, result2[0]);
           }
           if (result2 === null) {
             pos = clone(pos2);
@@ -3614,7 +3615,7 @@ smalltalk.parser = (function(){
                 pos = clone(pos3);
               }
               if (result2 !== null) {
-                result2 = (function(offset, line, column, pair) {return pair})(pos2.offset, pos2.line, pos2.column, result2[0]);
+                result2 = (function(offset, line, column, pair) {return pair;})(pos2.offset, pos2.line, pos2.column, result2[0]);
               }
               if (result2 === null) {
                 pos = clone(pos2);
@@ -3637,14 +3638,14 @@ smalltalk.parser = (function(){
           result0 = (function(offset, line, column, pairs) {
                              var selector = [];
                              var args = [];
-                              for(var i=0;i<pairs.length;i++) {
+                              for(var i = 0; i < pairs.length; i++) {
                                   selector.push(pairs[i].key);
                                   args.push(pairs[i].arg);
                               }
                               return smalltalk.SendNode._new()
-        		      	     ._position_((line).__at(column))
+                                     ._position_((line).__at(column))
                                      ._selector_(selector.join(""))
-                                     ._arguments_(args)
+                                     ._arguments_(args);
                          })(pos0.offset, pos0.line, pos0.column, result0[1]);
         }
         if (result0 === null) {
@@ -3787,7 +3788,7 @@ smalltalk.parser = (function(){
               pos = clone(pos3);
             }
             if (result3 !== null) {
-              result3 = (function(offset, line, column, mess) {return mess})(pos2.offset, pos2.line, pos2.column, result3[3]);
+              result3 = (function(offset, line, column, mess) {return mess;})(pos2.offset, pos2.line, pos2.column, result3[3]);
             }
             if (result3 === null) {
               pos = clone(pos2);
@@ -3838,7 +3839,7 @@ smalltalk.parser = (function(){
                   pos = clone(pos3);
                 }
                 if (result3 !== null) {
-                  result3 = (function(offset, line, column, mess) {return mess})(pos2.offset, pos2.line, pos2.column, result3[3]);
+                  result3 = (function(offset, line, column, mess) {return mess;})(pos2.offset, pos2.line, pos2.column, result3[3]);
                 }
                 if (result3 === null) {
                   pos = clone(pos2);
@@ -3865,13 +3866,13 @@ smalltalk.parser = (function(){
           result0 = (function(offset, line, column, send, messages) {
                              var cascade = [];
                              cascade.push(send);
-                             for(var i=0;i<messages.length;i++) {
+                             for(var i = 0; i < messages.length; i++) {
                                  cascade.push(messages[i]);
                              }
                              return smalltalk.CascadeNode._new()
-        		     	    ._position_((line).__at(column))
+                                    ._position_((line).__at(column))
                                     ._receiver_(send._receiver())
-                                    ._nodes_(cascade)
+                                    ._nodes_(cascade);
                          })(pos0.offset, pos0.line, pos0.column, result0[1], result0[2]);
         }
         if (result0 === null) {
@@ -3920,7 +3921,7 @@ smalltalk.parser = (function(){
             }
           }
           if (result2 !== null) {
-            result2 = (function(offset, line, column) {return ">"})(pos2.offset, pos2.line, pos2.column);
+            result2 = (function(offset, line, column) {return ">";})(pos2.offset, pos2.line, pos2.column);
           }
           if (result2 === null) {
             pos = clone(pos2);
@@ -3949,7 +3950,7 @@ smalltalk.parser = (function(){
               }
             }
             if (result2 !== null) {
-              result2 = (function(offset, line, column) {return ">"})(pos2.offset, pos2.line, pos2.column);
+              result2 = (function(offset, line, column) {return ">";})(pos2.offset, pos2.line, pos2.column);
             }
             if (result2 === null) {
               pos = clone(pos2);
@@ -3993,8 +3994,8 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, val) {
                              return smalltalk.JSStatementNode._new()
-        		     	    ._position_((line).__at(column))
-                                    ._source_(val.join(""))
+                                    ._position_((line).__at(column))
+                                    ._source_(val.join(""));
                          })(pos0.offset, pos0.line, pos0.column, result0[1]);
         }
         if (result0 === null) {
@@ -4062,10 +4063,10 @@ smalltalk.parser = (function(){
         if (result0 !== null) {
           result0 = (function(offset, line, column, pattern, sequence) {
                               return smalltalk.MethodNode._new()
-        		      	     ._position_((line).__at(column))
+                                     ._position_((line).__at(column))
                                      ._selector_(pattern[0])
                                      ._arguments_(pattern[1])
-                                     ._nodes_([sequence])
+                                     ._nodes_([sequence]);
                          })(pos0.offset, pos0.line, pos0.column, result0[1], result0[3]);
         }
         if (result0 === null) {

+ 78 - 77
js/parser.pegjs

@@ -3,56 +3,56 @@ start = method
 separator      = [ \t\v\f\u00A0\uFEFF\n\r\u2028\u2029]+
 comments       = (["][^"]*["])+
 ws             = (separator / comments)*
-identifier     = first:[a-zA-Z] others:[a-zA-Z0-9]* {return first + others.join("")}
-varIdentifier  = first:[a-z] others:[a-zA-Z0-9]* {return first + others.join("")}
-keyword        = first:identifier last:[:] {return first + last}
-selector      = first:[a-zA-Z] others:[a-zA-Z0-9\:]* {return first + others.join("")}
-className      = first:[A-Z] others:[a-zA-Z0-9]* {return first + others.join("")}
-string         = ['] val:(("''" {return "'"} / [^'])*) ['] {
+identifier     = first:[a-zA-Z] others:[a-zA-Z0-9]* {return first + others.join("");}
+varIdentifier  = first:[a-z] others:[a-zA-Z0-9]* {return first + others.join("");}
+keyword        = first:identifier last:[:] {return first + last;}
+selector      = first:[a-zA-Z] others:[a-zA-Z0-9\:]* {return first + others.join("");}
+className      = first:[A-Z] others:[a-zA-Z0-9]* {return first + others.join("");}
+string         = ['] val:(("''" {return "'";} / [^'])*) ['] {
                      return smalltalk.ValueNode._new()
-		     	    ._position_((line).__at(column))
-                            ._value_(val.join("").replace(/\"/ig, '"'))
+                            ._position_((line).__at(column))
+                            ._value_(val.join("").replace(/\"/ig, '"'));
                  }
 
-symbol         = "#" rest:bareSymbol {return rest}
-bareSymbol         = val:(selector / binarySelector / node:string {return node._value()})
+symbol         = "#" rest:bareSymbol {return rest;}
+bareSymbol         = val:(selector / binarySelector / node:string {return node._value();})
                   {
                       return smalltalk.ValueNode._new()
-		      	     ._position_((line).__at(column))
-                             ._value_(val)
+                             ._position_((line).__at(column))
+                             ._value_(val);
                   }
 number         = n:(hex / float / integer) {
                      return smalltalk.ValueNode._new()
-		     	    ._position_((line).__at(column))
-                            ._value_(n)
-                 }
-hex            = neg:[-]? "16r" num:[0-9a-fA-F]+ {return parseInt((neg + num.join("")), 16)}
-float          = neg:[-]?int:[0-9]+ "." dec:[0-9]+ {return parseFloat((neg + int.join("") + "." + dec.join("")), 10)}
-integer        = neg:[-]?digits:[0-9]+ {return (parseInt(neg+digits.join(""), 10))}
-literalArray   = "#(" rest:literalArrayRest {return rest}
-bareLiteralArray   = "(" rest:literalArrayRest {return rest}
-literalArrayRest   = ws lits:(lit:(parseTimeLiteral / bareLiteralArray / bareSymbol) ws {return lit._value()})* ws ")" {
+                            ._position_((line).__at(column))
+                            ._value_(n);
+                 }
+hex            = neg:[-]? "16r" num:[0-9a-fA-F]+ {return parseInt((neg + num.join("")), 16);}
+float          = neg:[-]?digits:[0-9]+ "." dec:[0-9]+ {return parseFloat((neg + digits.join("") + "." + dec.join("")), 10);}
+integer        = neg:[-]?digits:[0-9]+ {return (parseInt(neg+digits.join(""), 10));}
+literalArray   = "#(" rest:literalArrayRest {return rest;}
+bareLiteralArray   = "(" rest:literalArrayRest {return rest;}
+literalArrayRest   = ws lits:(lit:(parseTimeLiteral / bareLiteralArray / bareSymbol) ws {return lit._value();})* ws ")" {
                      return smalltalk.ValueNode._new()
-		     	    ._position_((line).__at(column))
-                            ._value_(lits)
+                            ._position_((line).__at(column))
+                            ._value_(lits);
                  }
 dynamicArray   = "{" ws expressions:expressions? ws "."? "}" {
                      return smalltalk.DynamicArrayNode._new()
-		     	    ._position_((line).__at(column))
-                            ._nodes_(expressions)
+                            ._position_((line).__at(column))
+                            ._nodes_(expressions);
                  }
 dynamicDictionary = "#{" ws expressions: expressions? ws "}" {
                         return smalltalk.DynamicDictionaryNode._new()
-			       ._position_((line).__at(column))
-                               ._nodes_(expressions)
+                               ._position_((line).__at(column))
+                               ._nodes_(expressions);
                     }
 pseudoVariable = val:(
-                   'true' {return true}
-                 / 'false' {return false}
-                 / 'nil' {return nil}) {
+                   'true' {return true;}
+                 / 'false' {return false;}
+                 / 'nil' {return nil;}) {
                        return smalltalk.ValueNode._new()
-		       	      ._position_((line).__at(column))
-                              ._value_(val)
+                              ._position_((line).__at(column))
+                              ._value_(val);
                    }
 parseTimeLiteral        = pseudoVariable / number / literalArray / string / symbol
 runtimeLiteral        = dynamicDictionary / dynamicArray / block
@@ -61,42 +61,43 @@ literal        = runtimeLiteral / parseTimeLiteral
 
 variable       = identifier:varIdentifier {
                      return smalltalk.VariableNode._new()
-		     	    ._position_((line).__at(column))
-                            ._value_(identifier)
+                            ._position_((line).__at(column))
+                            ._value_(identifier);
                  }
 classReference = className:className {
                      return smalltalk.ClassReferenceNode._new()
-		     	    ._position_((line).__at(column))
-                            ._value_(className)
+                            ._position_((line).__at(column))
+                            ._value_(className);
                  }
 
 reference      = variable / classReference
 
-keywordPair    = key:keyword ws arg:binarySend ws {return {key:key, arg: arg}}
+keywordPair    = key:keyword ws arg:binarySend ws {return {key:key, arg: arg};}
 
-binarySelector = bin:[\\+*/=><,@%~|&-]+ {return bin.join("")}
+binarySelector = bin:[\\+*/=><,@%~|&-]+ {return bin.join("");}
 unarySelector  = identifier
 
-keywordPattern = pairs:(ws key:keyword ws arg:identifier {return {key:key, arg: arg}})+ {
+keywordPattern = pairs:(ws key:keyword ws arg:identifier {return {key:key, arg: arg};})+ {
                      var keywords = [];
                      var params = [];
-                     for(var i=0;i<pairs.length;i++){
+                     var i = 0;
+                     for(i = 0; i < pairs.length; i++){
                          keywords.push(pairs[i].key);
                      }
-                     for(var i=0;i<pairs.length;i++){
+                     for(i = 0; i < pairs.length; i++){
                          params.push(pairs[i].arg);
                      }
-                     return [keywords.join(""), params]
+                     return [keywords.join(""), params];
                  }
-binaryPattern  = ws selector:binarySelector ws arg:identifier {return [selector, [arg]]}
-unaryPattern   = ws selector:unarySelector {return [selector, []]}
+binaryPattern  = ws selector:binarySelector ws arg:identifier {return [selector, [arg]];}
+unaryPattern   = ws selector:unarySelector {return [selector, []];}
 
 expression     = assignment / cascade / keywordSend / binarySend
 
-expressionList = ws "." ws expression:expression {return expression}
+expressionList = ws "." ws expression:expression {return expression;}
 expressions    = first:expression others:expressionList* {
                      var result = [first];
-                     for(var i=0;i<others.length;i++) {
+                     for(var i = 0; i < others.length; i++) {
                          result.push(others[i]);
                      }
                      return result;
@@ -104,49 +105,49 @@ expressions    = first:expression others:expressionList* {
 
 assignment     = variable:variable ws ':=' ws expression:expression {
                      return smalltalk.AssignmentNode._new()
-		     	    ._position_((line).__at(column))
+                            ._position_((line).__at(column))
                             ._left_(variable)
-                            ._right_(expression)
+                            ._right_(expression);
                  }
 
 ret            = '^' ws expression:expression ws '.'? {
                      return smalltalk.ReturnNode._new()
-		     	    ._position_((line).__at(column))
-                            ._nodes_([expression])
+                            ._position_((line).__at(column))
+                            ._nodes_([expression]);
                  }
   
-temps          = "|" vars:(ws variable:identifier ws {return variable})* "|" {return vars}
+temps          = "|" vars:(ws variable:identifier ws {return variable;})* "|" {return vars;}
 
-blockParamList = params:((ws ":" ws param:identifier {return param})+) ws "|" {return params}
+blockParamList = params:((ws ":" ws param:identifier {return param;})+) ws "|" {return params;}
 
-subexpression  = '(' ws expression:expression ws ')' {return expression}
+subexpression  = '(' ws expression:expression ws ')' {return expression;}
 
-statements     = ret:ret [.]* {return [ret]}
+statements     = ret:ret [.]* {return [ret];}
                  / exps:expressions ws [.]+ ws ret:ret [.]* {
                        var expressions = exps;
                        expressions.push(ret);
-                       return expressions
+                       return expressions;
                    }
                  / expressions:expressions? [.]* {
-                       return expressions || []
+                       return expressions || [];
                    }
 
 sequence       = jsSequence / stSequence
 
 stSequence     = temps:temps? ws statements:statements? ws {
                      return smalltalk.SequenceNode._new()
-		     	    ._position_((line).__at(column))
+                            ._position_((line).__at(column))
                             ._temps_(temps || [])
-                            ._nodes_(statements || [])
+                            ._nodes_(statements || []);
                  }
 
 jsSequence     = jsStatement
 
 block          = '[' ws params:blockParamList? ws sequence:sequence? ws ']' {
                      return smalltalk.BlockNode._new()
-		     	    ._position_((line).__at(column))
+                            ._position_((line).__at(column))
                             ._parameters_(params || [])
-                            ._nodes_([sequence._asBlockSequenceNode()])
+                            ._nodes_([sequence._asBlockSequenceNode()]);
                  }
 
 operand        = literal / reference / subexpression
@@ -155,8 +156,8 @@ operand        = literal / reference / subexpression
 
 unaryMessage   = ws selector:unarySelector ![:] {
                      return smalltalk.SendNode._new()
-		     	    ._position_((line).__at(column))
-                            ._selector_(selector)
+                            ._position_((line).__at(column))
+                            ._selector_(selector);
                  }
 
 unaryTail      = message:unaryMessage ws tail:unaryTail? ws {
@@ -179,9 +180,9 @@ unarySend      = receiver:operand ws tail:unaryTail? {
 
 binaryMessage  = ws selector:binarySelector ws arg:(unarySend / operand) {
                      return smalltalk.SendNode._new()
-		     	    ._position_((line).__at(column))
+                            ._position_((line).__at(column))
                             ._selector_(selector)
-                            ._arguments_([arg])
+                            ._arguments_([arg]);
                  }
 
 binaryTail     = message:binaryMessage tail:binaryTail? {
@@ -203,17 +204,17 @@ binarySend     = receiver:unarySend tail:binaryTail? {
                  }
 
 
-keywordMessage = ws pairs:(pair:keywordPair ws {return pair})+ {
+keywordMessage = ws pairs:(pair:keywordPair ws {return pair;})+ {
                      var selector = [];
                      var args = [];
-                      for(var i=0;i<pairs.length;i++) {
+                      for(var i = 0; i < pairs.length; i++) {
                           selector.push(pairs[i].key);
                           args.push(pairs[i].arg);
                       }
                       return smalltalk.SendNode._new()
-		      	     ._position_((line).__at(column))
+                             ._position_((line).__at(column))
                              ._selector_(selector.join(""))
-                             ._arguments_(args)
+                             ._arguments_(args);
                  }
 
 keywordSend    = receiver:binarySend tail:keywordMessage {
@@ -222,30 +223,30 @@ keywordSend    = receiver:binarySend tail:keywordMessage {
 
 message        = binaryMessage / unaryMessage / keywordMessage
 
-cascade        = ws send:(keywordSend / binarySend) messages:(ws ";" ws mess:message ws {return mess})+ {
+cascade        = ws send:(keywordSend / binarySend) messages:(ws ";" ws mess:message ws {return mess;})+ {
                      var cascade = [];
                      cascade.push(send);
-                     for(var i=0;i<messages.length;i++) {
+                     for(var i = 0; i < messages.length; i++) {
                          cascade.push(messages[i]);
                      }
                      return smalltalk.CascadeNode._new()
-		     	    ._position_((line).__at(column))
+                            ._position_((line).__at(column))
                             ._receiver_(send._receiver())
-                            ._nodes_(cascade)
+                            ._nodes_(cascade);
                  }
 
-jsStatement    = "<" val:((">>" {return ">"} / [^>])*) ">" {
+jsStatement    = "<" val:((">>" {return ">";} / [^>])*) ">" {
                      return smalltalk.JSStatementNode._new()
-		     	    ._position_((line).__at(column))
-                            ._source_(val.join(""))
+                            ._position_((line).__at(column))
+                            ._source_(val.join(""));
                  }
 
 
 method         = ws pattern:(keywordPattern / binaryPattern / unaryPattern) ws sequence:sequence? ws {
                       return smalltalk.MethodNode._new()
-		      	     ._position_((line).__at(column))
+                             ._position_((line).__at(column))
                              ._selector_(pattern[0])
                              ._arguments_(pattern[1])
-                             ._nodes_([sequence])
+                             ._nodes_([sequence]);
                  }
 

+ 1 - 1
st/Compiler-IR.st

@@ -920,7 +920,7 @@ visitIRDynamicArray: anIRDynamicArray
 !
 
 visitIRDynamicDictionary: anIRDynamicDictionary
-	self stream nextPutAll: 'smalltalk.HashedCollection._fromPairs_(['.
+	self stream nextPutAll: 'smalltalk.HashedCollection._from_(['.
 		anIRDynamicDictionary instructions
 			do: [ :each | self visit: each ]
 			separatedBy: [self stream nextPutAll: ',' ].

+ 21 - 50
st/Helios-Core.st

@@ -616,11 +616,23 @@ unregister
 
 !HLWidget methodsFor: 'keybindings'!
 
+bindKeyDown: keyDownBlock up: keyUpBlock
+	self wrapper asJQuery
+		keydown: keyDownBlock;
+		keyup: keyUpBlock
+!
+
 registerBindings
 	self registerBindingsOn: self manager keyBinder bindings
 !
 
 registerBindingsOn: aBindingGroup
+!
+
+unbindKeyDownUp
+	self wrapper asJQuery
+		unbind: 'keydown';
+		unbind: 'keyup'
 ! !
 
 !HLWidget methodsFor: 'rendering'!
@@ -698,10 +710,6 @@ blur
 
 focus
 	self wrapper asJQuery focus
-!
-
-hasFocus
-	^ self wrapper notNil and: [ self wrapper asJQuery is: ':focus' ]
 ! !
 
 !HLFocusableWidget methodsFor: 'rendering'!
@@ -726,6 +734,10 @@ renderOn: html
 
 canHaveFocus
 	^ true
+!
+
+hasFocus
+	^ self wrapper notNil and: [ self wrapper asJQuery hasClass: self focusClass ]
 ! !
 
 HLFocusableWidget subclass: #HLListWidget
@@ -845,52 +857,11 @@ defaultItems
 
 !HLListWidget methodsFor: 'events'!
 
-setupKeyBindings
-	"TODO: refactor this!!"
-	
-	| active interval delay repeatInterval |
-	
-	active := false.
-	repeatInterval := 70.
-	self wrapper asJQuery unbind: 'keydown'.
-
-	self wrapper asJQuery keydown: [ :e |
-		
-        (e which = 38 and: [ active = false ]) ifTrue: [ 
-			active := true.
-			self activatePreviousListItem.
-        	delay := [
-				interval := [
-					(self wrapper asJQuery hasClass: self focusClass)
-						ifTrue: [
-							self activatePreviousListItem ]
-						ifFalse: [
-							active := false.
-							interval ifNotNil: [ interval clearInterval ].
-							delay ifNotNil: [ delay clearTimeout] ] ]
-					valueWithInterval: repeatInterval ]
-						valueWithTimeout: 300 ].
-			
-      	(e which = 40 and: [ active = false ]) ifTrue: [
-            active := true.
-			self activateNextListItem.
-        	delay := [
-				interval := [ 
-					(self wrapper asJQuery hasClass: self focusClass)
-						ifTrue: [
-							self activateNextListItem ]
-						ifFalse: [
-							active := false.
-							interval ifNotNil: [ interval clearInterval ].
-							delay ifNotNil: [ delay clearTimeout] ] ]
-					valueWithInterval: repeatInterval ]
-						valueWithTimeout: 300 ] ].
-	
-	self wrapper asJQuery keyup: [ :e |
-		active ifTrue: [
-			active := false.
-			interval ifNotNil: [ interval clearInterval ].
-			delay ifNotNil: [ delay clearTimeout] ] ]
+setupKeyBindings 
+	(HLRepeatingKeyBindingHandler forWidget: self)
+		whileKeyPressed: 38 do: [ self activatePreviousListItem ];
+		whileKeyPressed: 40 do: [ self activateNextListItem ];
+		rebindKeys
 ! !
 
 !HLListWidget methodsFor: 'initialization'!

+ 98 - 0
st/Helios-KeyBindings.st

@@ -597,3 +597,101 @@ on: aKeyBinder
         yourself
 ! !
 
+Object subclass: #HLRepeatingKeyBindingHandler
+	instanceVariableNames: 'repeatInterval delay interval keyBindings widget isKeyCurrentlyPressed'
+	package: 'Helios-KeyBindings'!
+!HLRepeatingKeyBindingHandler commentStamp!
+##Usage
+
+    (HLRepeatingKeyBindingHandler forWidget: aWidget)
+        whileKeyPressed: keyCode do: [xxxx];
+        whileKeyPressed: anotherKey do: [yyy];
+        rebind
+
+Performs an action on a key press, waits for 300 ms and then preforms the action every repeatInterval ms until the button is released!
+
+!HLRepeatingKeyBindingHandler methodsFor: 'accessing'!
+
+repeatInterval: aMillisecondIntegerValue 
+	repeatInterval := aMillisecondIntegerValue
+!
+
+whileKeyPressed: aKey do: aBlock
+	keyBindings at: aKey put: aBlock
+!
+
+widget: aWidget
+	widget := aWidget
+! !
+
+!HLRepeatingKeyBindingHandler methodsFor: 'actions'!
+
+bindKeys
+	widget bindKeyDown: [ :e | self handleKeyDown: e ] up: [ :e | self handleKeyUp: e ]
+!
+
+delayBeforeStartingRepeatWithAction: action
+	^ [ interval := self startRepeatingAction: action ] valueWithTimeout: 300
+!
+
+handleKeyUp
+	isKeyCurrentlyPressed := false.
+	interval ifNotNil: [ interval clearInterval ].
+	delay ifNotNil: [ delay clearTimeout ]
+!
+
+rebindKeys
+	self unbindKeys;
+		bindKeys
+!
+
+startRepeatingAction: action
+	^ [ (widget hasFocus)
+		ifTrue: [ action value ]
+		ifFalse: [ self handleKeyUp ] ] valueWithInterval: repeatInterval
+!
+
+unbindKeys
+	widget unbindKeyDownUp
+! !
+
+!HLRepeatingKeyBindingHandler methodsFor: 'events-processing'!
+
+handleKeyDown: e
+	 keyBindings keysAndValuesDo: [ :key :action | 
+		self ifKey: key wasPressedIn: e thenDo: action ]
+!
+
+handleKeyUp: e
+	isKeyCurrentlyPressed
+		ifTrue: [ self handleKeyUp ]
+!
+
+ifKey: key wasPressedIn: e thenDo: action
+	(e which = key and: [ isKeyCurrentlyPressed = false ])
+		ifTrue: [  self whileTheKeyIsPressedDo: action ]
+!
+
+whileTheKeyIsPressedDo: action
+	isKeyCurrentlyPressed := true.
+	action value.
+	delay := self delayBeforeStartingRepeatWithAction: action
+! !
+
+!HLRepeatingKeyBindingHandler methodsFor: 'initialization'!
+
+initialize 
+	super initialize.
+	keyBindings := Dictionary new.
+	isKeyCurrentlyPressed := false.
+	repeatInterval := 70.
+! !
+
+!HLRepeatingKeyBindingHandler class methodsFor: 'instance-creation'!
+
+forWidget: aWidget
+	^self new
+		widget: aWidget;
+		yourself
+! !
+

+ 27 - 6
st/Kernel-Collections.st

@@ -473,7 +473,7 @@ removeKey: aKey ifAbsent: aBlock
 !HashedCollection methodsFor: 'converting'!
 
 asDictionary
-	^Dictionary fromPairs: self associations
+	^Dictionary from: self associations
 !
 
 asJSON
@@ -578,11 +578,32 @@ includesKey: aKey
 
 !HashedCollection class methodsFor: 'instance creation'!
 
+from: aCollection
+	| newCollection |
+	newCollection := self new.
+	aCollection do: [ :each | newCollection add: each ].
+	^ newCollection
+!
+
 fromPairs: aCollection
-	| dict |
-	dict := self new.
-	aCollection do: [:each | dict add: each].
-	^dict
+	"This message is poorly named and has been replaced by #from:"
+	^ self from: aCollection
+!
+
+newFromPairs: aCollection
+	"Accept an array of elements where every two elements form an 
+	association - the odd element being the key, and the even element the value."
+	
+	| newCollection |
+	
+	aCollection size even ifFalse: [ 
+		self error: '#newFromPairs only accepts arrays of an even length' ].
+		
+	newCollection := self new.
+	( 1 to: aCollection size by: 2 ) do: [ :each | 
+		newCollection at: (aCollection at: each) put: (aCollection at: each + 1) ].
+		
+	^ newCollection
 ! !
 
 HashedCollection subclass: #Dictionary
@@ -653,7 +674,7 @@ removeKey: aKey ifAbsent: aBlock
 !Dictionary methodsFor: 'converting'!
 
 asHashedCollection
-	^HashedCollection fromPairs: self associations
+	^HashedCollection from: self associations
 !
 
 asJSON

+ 3 - 3
st/Kernel-Methods.st

@@ -49,7 +49,7 @@ whileFalse
 
 whileFalse: aBlock
 	"inlined in the Compiler"
-	<while(!!self()) {aBlock._value()}>
+	<while(!!smalltalk.assert(self._value())) {aBlock._value()}>
 !
 
 whileTrue
@@ -59,7 +59,7 @@ whileTrue
 
 whileTrue: aBlock
 	"inlined in the Compiler"
-	<while(self()) {aBlock._value()}>
+	<while(smalltalk.assert(self._value())) {aBlock._value()}>
 ! !
 
 !BlockClosure methodsFor: 'converting'!
@@ -103,7 +103,7 @@ applyTo: anObject arguments: aCollection
 !
 
 ensure: aBlock
-	<try{return self()}finally{aBlock._value()}>
+	<try{return self._value()}finally{aBlock._value()}>
 !
 
 new

+ 22 - 0
st/Kernel-Tests.st

@@ -490,6 +490,10 @@ collectionWithDuplicates
 
 !HashedCollectionTest methodsFor: 'tests'!
 
+testAsDictionary
+self assert: ( self collectionClass new asDictionary isMemberOf: Dictionary ).
+!
+
 testAt
 	self assert: (self collection at: 'a') equals: 2.
 	self should: [ self collection at: 5 ] raise: Error
@@ -503,10 +507,24 @@ testContains
 	self deny: (self collection contains: [ :each | each = Object new ])
 !
 
+testFrom
+"Accept a collection of associations."
+| associations |
+associations := { 'a' -> 1. 'b' -> 2 }.
+self assertSameContents: ( self class collectionClass from: associations ) as: #{ 'a' -> 1. 'b' -> 2 }.
+!
+
 testIndexOf
 	self assert: (self collection indexOf: 2) equals: 'a'.
 	self should: [ self collection indexOf: 999 ] raise: Error.
 	self assert: (self collection indexOf: 999 ifAbsent: [ 'sentinel' ]) equals: 'sentinel'
+!
+
+testNewFromPairs
+"Accept an array in which all odd indexes are keys and evens are values."
+| flattenedAssociations |
+flattenedAssociations := { 'a'. 1. 'b'. 2 }.
+self assertSameContents: ( self class collectionClass newFromPairs: flattenedAssociations ) as: #{ 'a' -> 1. 'b' -> 2 }.
 ! !
 
 !HashedCollectionTest class methodsFor: 'accessing'!
@@ -567,6 +585,10 @@ testAccessing
 	self deny: (d includesKey: 3@1)
 !
 
+testAsHashedCollection
+self assert: ( self collectionClass new asHashedCollection isMemberOf: HashedCollection ).
+!
+
 testDynamicDictionaries
 	self assert: #{'hello' -> 1} asDictionary equals: (Dictionary with: 'hello' -> 1)
 !

+ 3 - 3
test/Test.js

@@ -8,7 +8,7 @@ category: 'not yet classified',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-_st(self)._runTestSuite();
+self._runTestSuite();
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.NodeTestRunner.klass)})},
 args: [],
 source: "initialize\x0a\x09self runTestSuite",
@@ -49,11 +49,11 @@ 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(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!"));
+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)){
-return _st(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!"));
+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!"));
 };
 };
 }, function($ctx2) {$ctx2.fillBlock({ann:ann,result:result},$ctx1)})}));

Bu fark içinde çok fazla dosya değişikliği olduğu için bazı dosyalar gösterilmiyor