浏览代码

Completed merge with ben/helios

Nicolas Petton 11 年之前
父节点
当前提交
82713e668f

+ 2 - 5
js/Helios-Environments.deploy.js

@@ -240,12 +240,9 @@ smalltalk.method({
 selector: "adoptMethod:",
 fn: function (aMethod){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
-$1=self;
-_st($1)._compile_(_st(aMethod)._source());
-$2=_st($1)._category_(_st(aMethod)._protocol());
+return smalltalk.withContext(function($ctx1) { 
_st(self)._compile_category_(_st(aMethod)._source(),_st(aMethod)._protocol());
 return self}, function($ctx1) {$ctx1.fill(self,"adoptMethod:",{aMethod:aMethod},smalltalk.Behavior)})},
-messageSends: ["compile:", "source", "category:", "protocol"]}),
+messageSends: ["compile:category:", "source", "protocol"]}),
 smalltalk.Behavior);
 
 smalltalk.addMethod(

+ 3 - 6
js/Helios-Environments.js

@@ -328,14 +328,11 @@ selector: "adoptMethod:",
 category: '*Helios-Environments',
 fn: function (aMethod){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
var $1,$2;
-$1=self;
-_st($1)._compile_(_st(aMethod)._source());
-$2=_st($1)._category_(_st(aMethod)._protocol());
+return smalltalk.withContext(function($ctx1) { 
_st(self)._compile_category_(_st(aMethod)._source(),_st(aMethod)._protocol());
 return self}, function($ctx1) {$ctx1.fill(self,"adoptMethod:",{aMethod:aMethod},smalltalk.Behavior)})},
 args: ["aMethod"],
-source: "adoptMethod: aMethod\x0a\x09self \x0a\x09\x09compile: aMethod source;\x0a\x09\x09category: aMethod protocol.",
-messageSends: ["compile:", "source", "category:", "protocol"],
+source: "adoptMethod: aMethod\x0a\x09self \x0a\x09\x09compile: aMethod source\x0a\x09\x09category: aMethod protocol.",
+messageSends: ["compile:category:", "source", "protocol"],
 referencedClasses: []
 }),
 smalltalk.Behavior);

+ 241 - 49
js/Helios-KeyBindings.deploy.js

@@ -1,5 +1,5 @@
 smalltalk.addPackage('Helios-KeyBindings');
-smalltalk.addClass('HLBinding', smalltalk.Object, ['key', 'label', 'each'], 'Helios-KeyBindings');
+smalltalk.addClass('HLBinding', smalltalk.Object, ['key', 'label'], 'Helios-KeyBindings');
 smalltalk.addMethod(
 "_applyOn_",
 smalltalk.method({
@@ -40,7 +40,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=_st(self)._label();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"displayLabel",{}, smalltalk.HLBinding)})},
+}, function($ctx1) {$ctx1.fill(self,"displayLabel",{},smalltalk.HLBinding)})},
 messageSends: ["label"]}),
 smalltalk.HLBinding);
 
@@ -77,7 +77,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@key"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"key",{}, smalltalk.HLBinding)})},
+}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLBinding)})},
 messageSends: []}),
 smalltalk.HLBinding);
 
@@ -88,7 +88,7 @@ selector: "key:",
 fn: function (anInteger){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
self["@key"]=anInteger;
-return self}, function($ctx1) {$ctx1.fill(self,"key:",{anInteger:anInteger}, smalltalk.HLBinding)})},
+return self}, function($ctx1) {$ctx1.fill(self,"key:",{anInteger:anInteger},smalltalk.HLBinding)})},
 messageSends: []}),
 smalltalk.HLBinding);
 
@@ -101,7 +101,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@label"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"label",{}, smalltalk.HLBinding)})},
+}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLBinding)})},
 messageSends: []}),
 smalltalk.HLBinding);
 
@@ -112,7 +112,17 @@ selector: "label:",
 fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
self["@label"]=aString;
-return self}, function($ctx1) {$ctx1.fill(self,"label:",{aString:aString}, smalltalk.HLBinding)})},
+return self}, function($ctx1) {$ctx1.fill(self,"label:",{aString:aString},smalltalk.HLBinding)})},
+messageSends: []}),
+smalltalk.HLBinding);
+
+smalltalk.addMethod(
+"_release",
+smalltalk.method({
+selector: "release",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"release",{},smalltalk.HLBinding)})},
 messageSends: []}),
 smalltalk.HLBinding);
 
@@ -148,7 +158,7 @@ smalltalk.method({
 selector: "renderOn:html:",
 fn: function (aBindingHelper,html){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"renderOn:html:",{aBindingHelper:aBindingHelper,html:html}, smalltalk.HLBinding)})},
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"renderOn:html:",{aBindingHelper:aBindingHelper,html:html},smalltalk.HLBinding)})},
 messageSends: []}),
 smalltalk.HLBinding);
 
@@ -161,7 +171,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=_st((smalltalk.String || String))._fromCharCode_(_st(self)._key());
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"shortcut",{}, smalltalk.HLBinding)})},
+}, function($ctx1) {$ctx1.fill(self,"shortcut",{},smalltalk.HLBinding)})},
 messageSends: ["fromCharCode:", "key"]}),
 smalltalk.HLBinding);
 
@@ -179,7 +189,7 @@ _st($2)._label_(aString);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"on:labelled:",{anInteger:anInteger,aString:aString}, smalltalk.HLBinding.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"on:labelled:",{anInteger:anInteger,aString:aString},smalltalk.HLBinding.klass)})},
 messageSends: ["key:", "new", "label:", "yourself"]}),
 smalltalk.HLBinding.klass);
 
@@ -235,17 +245,18 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $2,$3,$4,$5,$1;
 $2=_st((smalltalk.HLBindingInput || HLBindingInput))._new();
 _st($2)._label_(_st(_st(self)._command())._inputLabel());
-_st($2)._callback_((function(val){
+_st($2)._callback_((function(val,errorBlock){
 return smalltalk.withContext(function($ctx2) {
$3=_st(self)._command();
 _st($3)._input_(val);
+_st($3)._errorBlock_(errorBlock);
 $4=_st($3)._execute();
 return $4;
-}, function($ctx2) {$ctx2.fillBlock({val:val},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({val:val,errorBlock:errorBlock},$ctx1)})}));
 $5=_st($2)._yourself();
 $1=$5;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"inputBinding",{},smalltalk.HLBindingAction)})},
-messageSends: ["label:", "inputLabel", "command", "new", "callback:", "input:", "execute", "yourself"]}),
+messageSends: ["label:", "inputLabel", "command", "new", "callback:", "input:", "errorBlock:", "execute", "yourself"]}),
 smalltalk.HLBindingAction);
 
 smalltalk.addMethod(
@@ -301,7 +312,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=_st(_st(self)._bindings())._add_(aBinding);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"add:",{aBinding:aBinding}, smalltalk.HLBindingGroup)})},
+}, function($ctx1) {$ctx1.fill(self,"add:",{aBinding:aBinding},smalltalk.HLBindingGroup)})},
 messageSends: ["add:", "bindings"]}),
 smalltalk.HLBindingGroup);
 
@@ -316,7 +327,7 @@ $1=_st((smalltalk.HLBindingAction || HLBindingAction))._on_labelled_(anInteger,a
 _st($1)._callback_(aBlock);
 $2=_st($1)._yourself();
 _st(self)._add_($2);
-return self}, function($ctx1) {$ctx1.fill(self,"addActionKey:labelled:callback:",{anInteger:anInteger,aString:aString,aBlock:aBlock}, smalltalk.HLBindingGroup)})},
+return self}, function($ctx1) {$ctx1.fill(self,"addActionKey:labelled:callback:",{anInteger:anInteger,aString:aString,aBlock:aBlock},smalltalk.HLBindingGroup)})},
 messageSends: ["add:", "callback:", "on:labelled:", "yourself"]}),
 smalltalk.HLBindingGroup);
 
@@ -327,7 +338,7 @@ selector: "addGroupKey:labelled:",
 fn: function (anInteger,aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
_st(self)._add_(_st((smalltalk.HLBindingGroup || HLBindingGroup))._on_labelled_(anInteger,aString));
-return self}, function($ctx1) {$ctx1.fill(self,"addGroupKey:labelled:",{anInteger:anInteger,aString:aString}, smalltalk.HLBindingGroup)})},
+return self}, function($ctx1) {$ctx1.fill(self,"addGroupKey:labelled:",{anInteger:anInteger,aString:aString},smalltalk.HLBindingGroup)})},
 messageSends: ["add:", "on:labelled:"]}),
 smalltalk.HLBindingGroup);
 
@@ -344,7 +355,7 @@ return smalltalk.withContext(function($ctx2) {
return _st(_st(each)._label()).__
 return smalltalk.withContext(function($ctx2) {
return nil;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"at:",{aString:aString}, smalltalk.HLBindingGroup)})},
+}, function($ctx1) {$ctx1.fill(self,"at:",{aString:aString},smalltalk.HLBindingGroup)})},
 messageSends: ["detect:ifNone:", "=", "label", "bindings"]}),
 smalltalk.HLBindingGroup);
 
@@ -382,7 +393,7 @@ return smalltalk.withContext(function($ctx2) {
return _st(_st(each)._key()).__eq
 return smalltalk.withContext(function($ctx2) {
return nil;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"atKey:",{anInteger:anInteger}, smalltalk.HLBindingGroup)})},
+}, function($ctx1) {$ctx1.fill(self,"atKey:",{anInteger:anInteger},smalltalk.HLBindingGroup)})},
 messageSends: ["detect:ifNone:", "=", "key", "bindings"]}),
 smalltalk.HLBindingGroup);
 
@@ -401,7 +412,7 @@ $1=self["@bindings"];
 $1=$2;
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"bindings",{}, smalltalk.HLBindingGroup)})},
+}, function($ctx1) {$ctx1.fill(self,"bindings",{},smalltalk.HLBindingGroup)})},
 messageSends: ["ifNil:", "new"]}),
 smalltalk.HLBindingGroup);
 
@@ -414,7 +425,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=_st(smalltalk.HLBinding.fn.prototype._displayLabel.apply(_st(self), [])).__comma("...");
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"displayLabel",{}, smalltalk.HLBindingGroup)})},
+}, function($ctx1) {$ctx1.fill(self,"displayLabel",{},smalltalk.HLBindingGroup)})},
 messageSends: [",", "displayLabel"]}),
 smalltalk.HLBindingGroup);
 
@@ -431,6 +442,19 @@ return $1;
 messageSends: ["notEmpty", "activeBindings"]}),
 smalltalk.HLBindingGroup);
 
+smalltalk.addMethod(
+"_release",
+smalltalk.method({
+selector: "release",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._bindings())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(each)._release();
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"release",{},smalltalk.HLBindingGroup)})},
+messageSends: ["do:", "release", "bindings"]}),
+smalltalk.HLBindingGroup);
+
 smalltalk.addMethod(
 "_renderOn_html_",
 smalltalk.method({
@@ -448,16 +472,24 @@ smalltalk.HLBindingGroup);
 
 
 
-smalltalk.addClass('HLBindingInput', smalltalk.HLBinding, ['input', 'callback'], 'Helios-KeyBindings');
+smalltalk.addClass('HLBindingInput', smalltalk.HLBinding, ['input', 'callback', 'status', 'inputText', 'wrapper', 'binder'], 'Helios-KeyBindings');
 smalltalk.addMethod(
 "_applyOn_",
 smalltalk.method({
 selector: "applyOn:",
 fn: function (aKeyBinder){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(self)._evaluate_(_st(self)._input());
-return self}, function($ctx1) {$ctx1.fill(self,"applyOn:",{aKeyBinder:aKeyBinder},smalltalk.HLBindingInput)})},
-messageSends: ["evaluate:", "input"]}),
+return smalltalk.withContext(function($ctx1) { 
var $early={};
+try {
+_st(self)._evaluate_onError_(_st(self)._input(),(function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._errorStatus();
+_st(self)._refresh();
+throw $early=[false];
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"applyOn:",{aKeyBinder:aKeyBinder},smalltalk.HLBindingInput)})},
+messageSends: ["evaluate:onError:", "input", "errorStatus", "refresh"]}),
 smalltalk.HLBindingInput);
 
 smalltalk.addMethod(
@@ -476,7 +508,7 @@ $1=self["@callback"];
 $1=$2;
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"callback",{},smalltalk.HLInputBinding)})},
+}, function($ctx1) {$ctx1.fill(self,"callback",{},smalltalk.HLBindingInput)})},
 messageSends: ["ifNil:"]}),
 smalltalk.HLBindingInput);
 
@@ -487,10 +519,21 @@ selector: "callback:",
 fn: function (aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
self["@callback"]=aBlock;
-return self}, function($ctx1) {$ctx1.fill(self,"callback:",{aBlock:aBlock},smalltalk.HLInputBinding)})},
+return self}, function($ctx1) {$ctx1.fill(self,"callback:",{aBlock:aBlock},smalltalk.HLBindingInput)})},
 messageSends: []}),
 smalltalk.HLBindingInput);
 
+smalltalk.addMethod(
+"_errorStatus",
+smalltalk.method({
+selector: "errorStatus",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._status_("error");
+return self}, function($ctx1) {$ctx1.fill(self,"errorStatus",{},smalltalk.HLBindingInput)})},
+messageSends: ["status:"]}),
+smalltalk.HLBindingInput);
+
 smalltalk.addMethod(
 "_evaluate_",
 smalltalk.method({
@@ -502,6 +545,17 @@ return self}, function($ctx1) {$ctx1.fill(self,"evaluate:",{aString:aString},sma
 messageSends: ["value:", "callback"]}),
 smalltalk.HLBindingInput);
 
+smalltalk.addMethod(
+"_evaluate_onError_",
+smalltalk.method({
+selector: "evaluate:onError:",
+fn: function (aString,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._callback())._value_value_(aString,aBlock);
+return self}, function($ctx1) {$ctx1.fill(self,"evaluate:onError:",{aString:aString,aBlock:aBlock},smalltalk.HLBindingInput)})},
+messageSends: ["value:value:", "callback"]}),
+smalltalk.HLBindingInput);
+
 smalltalk.addMethod(
 "_input",
 smalltalk.method({
@@ -515,6 +569,36 @@ return $1;
 messageSends: ["val", "asJQuery"]}),
 smalltalk.HLBindingInput);
 
+smalltalk.addMethod(
+"_inputText",
+smalltalk.method({
+selector: "inputText",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@inputText"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@inputText"]="";
+$1=self["@inputText"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"inputText",{},smalltalk.HLBindingInput)})},
+messageSends: ["ifNil:"]}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_inputText_",
+smalltalk.method({
+selector: "inputText:",
+fn: function (aText){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@inputText"]=aText;
+return self}, function($ctx1) {$ctx1.fill(self,"inputText:",{aText:aText},smalltalk.HLBindingInput)})},
+messageSends: []}),
+smalltalk.HLBindingInput);
+
 smalltalk.addMethod(
 "_isActive",
 smalltalk.method({
@@ -526,6 +610,78 @@ return smalltalk.withContext(function($ctx1) { 
return true;
 messageSends: []}),
 smalltalk.HLBindingInput);
 
+smalltalk.addMethod(
+"_refresh",
+smalltalk.method({
+selector: "refresh",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=self["@wrapper"];
+if(($receiver = $1) == nil || $receiver == undefined){
+$2=self;
+return $2;
+} else {
+$1;
+};
+_st(_st(self["@wrapper"])._asJQuery())._empty();
+_st((function(html){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._renderActionFor_html_(self["@binder"],html);
+}, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1)})}))._appendToJQuery_(_st(self["@wrapper"])._asJQuery());
+return self}, function($ctx1) {$ctx1.fill(self,"refresh",{},smalltalk.HLBindingInput)})},
+messageSends: ["ifNil:", "empty", "asJQuery", "appendToJQuery:", "renderActionFor:html:"]}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_release",
+smalltalk.method({
+selector: "release",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@status"]=nil;
+self["@wrapper"]=nil;
+self["@binder"]=nil;
+self["@inputText"]=nil;
+return self}, function($ctx1) {$ctx1.fill(self,"release",{},smalltalk.HLBindingInput)})},
+messageSends: []}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_renderActionFor_html_",
+smalltalk.method({
+selector: "renderActionFor:html:",
+fn: function (aBinder,html){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$5,$3,$6;
+self["@binder"]=aBinder;
+$1=self["@wrapper"];
+if(($receiver = $1) == nil || $receiver == undefined){
+self["@wrapper"]=_st(html)._span();
+self["@wrapper"];
+} else {
+$1;
+};
+$2=self["@wrapper"];
+_st($2)._class_(_st("control-group ").__comma(_st(self)._status()));
+$3=_st($2)._with_((function(){
+return smalltalk.withContext(function($ctx2) {
$4=_st(html)._input();
+_st($4)._class_("input");
+_st($4)._placeholder_(_st(self)._displayLabel());
+$5=_st($4)._with_(_st(self)._inputText());
+self["@input"]=$5;
+return self["@input"];
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st(self["@input"])._onKeyPress_((function(event){
+return smalltalk.withContext(function($ctx2) {
$6=_st(_st(event)._keyCode()).__eq((13));
+if(smalltalk.assert($6)){
+return _st(self)._applyOn_(aBinder);
+};
+}, function($ctx2) {$ctx2.fillBlock({event:event},$ctx1)})}));
+_st(_st(self["@input"])._asJQuery())._focus();
+return self}, function($ctx1) {$ctx1.fill(self,"renderActionFor:html:",{aBinder:aBinder,html:html},smalltalk.HLBindingInput)})},
+messageSends: ["ifNil:", "span", "class:", ",", "status", "with:", "input", "placeholder:", "displayLabel", "inputText", "onKeyPress:", "ifTrue:", "applyOn:", "=", "keyCode", "focus", "asJQuery"]}),
+smalltalk.HLBindingInput);
+
 smalltalk.addMethod(
 "_renderOn_html_",
 smalltalk.method({
@@ -553,6 +709,36 @@ return self}, function($ctx1) {$ctx1.fill(self,"renderOn:html:",{aBinder:aBinder
 messageSends: ["class:", "span", "with:", "input", "placeholder:", "displayLabel", "onKeyPress:", "ifTrue:", "applyOn:", "=", "keyCode", "focus", "asJQuery"]}),
 smalltalk.HLBindingInput);
 
+smalltalk.addMethod(
+"_status",
+smalltalk.method({
+selector: "status",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@status"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@status"]="info";
+$1=self["@status"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"status",{},smalltalk.HLBindingInput)})},
+messageSends: ["ifNil:"]}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_status_",
+smalltalk.method({
+selector: "status:",
+fn: function (aStatus){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@status"]=aStatus;
+return self}, function($ctx1) {$ctx1.fill(self,"status:",{aStatus:aStatus},smalltalk.HLBindingInput)})},
+messageSends: []}),
+smalltalk.HLBindingInput);
+
 
 
 smalltalk.addClass('HLKeyBinder', smalltalk.Object, ['modifierKey', 'helper', 'bindings', 'selectedBinding'], 'Helios-KeyBindings');
@@ -574,7 +760,7 @@ selector: "activationKey",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
return (32);
-}, function($ctx1) {$ctx1.fill(self,"activationKey",{}, smalltalk.HLKeyBinder)})},
+}, function($ctx1) {$ctx1.fill(self,"activationKey",{},smalltalk.HLKeyBinder)})},
 messageSends: []}),
 smalltalk.HLKeyBinder);
 
@@ -585,7 +771,7 @@ selector: "activationKeyLabel",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
return "ctrl + space";
-}, function($ctx1) {$ctx1.fill(self,"activationKeyLabel",{}, smalltalk.HLKeyBinder)})},
+}, function($ctx1) {$ctx1.fill(self,"activationKeyLabel",{},smalltalk.HLKeyBinder)})},
 messageSends: []}),
 smalltalk.HLKeyBinder);
 
@@ -636,10 +822,17 @@ smalltalk.method({
 selector: "deactivate",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
self["@selectedBinding"]=nil;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@selectedBinding"];
+if(($receiver = $1) == nil || $receiver == undefined){
+$1;
+} else {
+_st(self["@selectedBinding"])._release();
+};
+self["@selectedBinding"]=nil;
 _st(_st(self)._helper())._hide();
 return self}, function($ctx1) {$ctx1.fill(self,"deactivate",{},smalltalk.HLKeyBinder)})},
-messageSends: ["hide", "helper"]}),
+messageSends: ["ifNotNil:", "release", "hide", "helper"]}),
 smalltalk.HLKeyBinder);
 
 smalltalk.addMethod(
@@ -669,7 +862,7 @@ selector: "escapeKey",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
return (27);
-}, function($ctx1) {$ctx1.fill(self,"escapeKey",{}, smalltalk.HLKeyBinder)})},
+}, function($ctx1) {$ctx1.fill(self,"escapeKey",{},smalltalk.HLKeyBinder)})},
 messageSends: []}),
 smalltalk.HLKeyBinder);
 
@@ -680,7 +873,7 @@ selector: "flushBindings",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
self["@bindings"]=nil;
-return self}, function($ctx1) {$ctx1.fill(self,"flushBindings",{}, smalltalk.HLKeyBinder)})},
+return self}, function($ctx1) {$ctx1.fill(self,"flushBindings",{},smalltalk.HLKeyBinder)})},
 messageSends: []}),
 smalltalk.HLKeyBinder);
 
@@ -703,7 +896,7 @@ return false;
 };
 $2=_st(self)._handleBindingFor_(event);
 return $2;
-}, function($ctx1) {$ctx1.fill(self,"handleActiveKeyDown:",{event:event}, smalltalk.HLKeyBinder)})},
+}, function($ctx1) {$ctx1.fill(self,"handleActiveKeyDown:",{event:event},smalltalk.HLKeyBinder)})},
 messageSends: ["ifTrue:", "deactivate", "preventDefault", "or:", "and:", "ctrlKey", "=", "which", "escapeKey", "handleBindingFor:"]}),
 smalltalk.HLKeyBinder);
 
@@ -724,7 +917,7 @@ _st(self)._applyBinding_(binding);
 _st(anEvent)._preventDefault();
 return false;
 };
-return self}, function($ctx1) {$ctx1.fill(self,"handleBindingFor:",{anEvent:anEvent,binding:binding}, smalltalk.HLKeyBinder)})},
+return self}, function($ctx1) {$ctx1.fill(self,"handleBindingFor:",{anEvent:anEvent,binding:binding},smalltalk.HLKeyBinder)})},
 messageSends: ["atKey:", "which", "selectedBinding", "ifNotNil:", "applyBinding:", "preventDefault"]}),
 smalltalk.HLKeyBinder);
 
@@ -744,7 +937,7 @@ _st(event)._preventDefault();
 return false;
 };
 };
-return self}, function($ctx1) {$ctx1.fill(self,"handleInactiveKeyDown:",{event:event}, smalltalk.HLKeyBinder)})},
+return self}, function($ctx1) {$ctx1.fill(self,"handleInactiveKeyDown:",{event:event},smalltalk.HLKeyBinder)})},
 messageSends: ["ifTrue:", "activate", "preventDefault", "ctrlKey", "=", "activationKey", "which"]}),
 smalltalk.HLKeyBinder);
 
@@ -762,7 +955,7 @@ $1=_st(self)._handleActiveKeyDown_(event);
 $1=_st(self)._handleInactiveKeyDown_(event);
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"handleKeyDown:",{event:event}, smalltalk.HLKeyBinder)})},
+}, function($ctx1) {$ctx1.fill(self,"handleKeyDown:",{event:event},smalltalk.HLKeyBinder)})},
 messageSends: ["ifTrue:ifFalse:", "handleActiveKeyDown:", "handleInactiveKeyDown:", "isActive"]}),
 smalltalk.HLKeyBinder);
 
@@ -775,7 +968,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@helper"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"helper",{}, smalltalk.HLKeyBinder)})},
+}, function($ctx1) {$ctx1.fill(self,"helper",{},smalltalk.HLKeyBinder)})},
 messageSends: []}),
 smalltalk.HLKeyBinder);
 
@@ -791,7 +984,6 @@ self["@helper"]=_st((smalltalk.HLKeyBinderHelper || HLKeyBinderHelper))._on_(sel
 $1=self["@helper"];
 _st($1)._renderStart();
 $2=_st($1)._renderCog();
-self["@active"]=false;
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLKeyBinder)})},
 messageSends: ["initialize", "on:", "renderStart", "renderCog"]}),
 smalltalk.HLKeyBinder);
@@ -835,7 +1027,7 @@ $1=_st(self)._bindings();
 $1=$2;
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"selectedBinding",{}, smalltalk.HLKeyBinder)})},
+}, function($ctx1) {$ctx1.fill(self,"selectedBinding",{},smalltalk.HLKeyBinder)})},
 messageSends: ["ifNil:", "bindings"]}),
 smalltalk.HLKeyBinder);
 
@@ -848,7 +1040,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
_st(_st(window)._jQuery_("body"))._keydown_((function(event){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._handleKeyDown_(event);
 }, function($ctx2) {$ctx2.fillBlock({event:event},$ctx1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"setupEvents",{}, smalltalk.HLKeyBinder)})},
+return self}, function($ctx1) {$ctx1.fill(self,"setupEvents",{},smalltalk.HLKeyBinder)})},
 messageSends: ["keydown:", "handleKeyDown:", "jQuery:"]}),
 smalltalk.HLKeyBinder);
 
@@ -861,7 +1053,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=_st(_st(navigator)._platform())._match_("Mac");
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"systemIsMac",{}, smalltalk.HLKeyBinder)})},
+}, function($ctx1) {$ctx1.fill(self,"systemIsMac",{},smalltalk.HLKeyBinder)})},
 messageSends: ["match:", "platform"]}),
 smalltalk.HLKeyBinder);
 
@@ -875,7 +1067,7 @@ selector: "cssClass",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
return "key_helper";
-}, function($ctx1) {$ctx1.fill(self,"cssClass",{}, smalltalk.HLKeyBinderHelper)})},
+}, function($ctx1) {$ctx1.fill(self,"cssClass",{},smalltalk.HLKeyBinderHelper)})},
 messageSends: []}),
 smalltalk.HLKeyBinderHelper);
 
@@ -911,7 +1103,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@keyBinder"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"keyBinder",{}, smalltalk.HLKeyBinderHelper)})},
+}, function($ctx1) {$ctx1.fill(self,"keyBinder",{},smalltalk.HLKeyBinderHelper)})},
 messageSends: []}),
 smalltalk.HLKeyBinderHelper);
 
@@ -922,7 +1114,7 @@ selector: "keyBinder:",
 fn: function (aKeyBinder){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
self["@keyBinder"]=aKeyBinder;
-return self}, function($ctx1) {$ctx1.fill(self,"keyBinder:",{aKeyBinder:aKeyBinder}, smalltalk.HLKeyBinderHelper)})},
+return self}, function($ctx1) {$ctx1.fill(self,"keyBinder:",{aKeyBinder:aKeyBinder},smalltalk.HLKeyBinderHelper)})},
 messageSends: []}),
 smalltalk.HLKeyBinderHelper);
 
@@ -932,7 +1124,7 @@ smalltalk.method({
 selector: "registerBindings",
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"registerBindings",{}, smalltalk.HLKeyBinderHelper)})},
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"registerBindings",{},smalltalk.HLKeyBinderHelper)})},
 messageSends: []}),
 smalltalk.HLKeyBinderHelper);
 
@@ -958,7 +1150,7 @@ selector: "renderBindingOn:",
 fn: function (html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._selectedBinding())._renderOn_html_(self,html);
-return self}, function($ctx1) {$ctx1.fill(self,"renderBindingOn:",{html:html}, smalltalk.HLKeyBinderHelper)})},
+return self}, function($ctx1) {$ctx1.fill(self,"renderBindingOn:",{html:html},smalltalk.HLKeyBinderHelper)})},
 messageSends: ["renderOn:html:", "selectedBinding"]}),
 smalltalk.HLKeyBinderHelper);
 
@@ -1044,7 +1236,7 @@ $4="Action";
 $4=$5;
 };
 $2=_st($3)._with_($4);
-return self}, function($ctx1) {$ctx1.fill(self,"renderSelectionOn:",{html:html}, smalltalk.HLKeyBinderHelper)})},
+return self}, function($ctx1) {$ctx1.fill(self,"renderSelectionOn:",{html:html},smalltalk.HLKeyBinderHelper)})},
 messageSends: ["class:", "span", "with:", "ifNil:", "label", "selectedBinding"]}),
 smalltalk.HLKeyBinderHelper);
 
@@ -1064,7 +1256,7 @@ return $2;
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
return _st(_st(window)._jQuery_("#keybinding-start-helper"))._fadeOut_((1000));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._valueWithTimeout_((2000));
-return self}, function($ctx1) {$ctx1.fill(self,"renderStart",{}, smalltalk.HLKeyBinderHelper)})},
+return self}, function($ctx1) {$ctx1.fill(self,"renderStart",{},smalltalk.HLKeyBinderHelper)})},
 messageSends: ["appendToJQuery:", "asJQuery", "id:", "div", "with:", ",", "activationKeyLabel", "keyBinder", "valueWithTimeout:", "fadeOut:", "jQuery:"]}),
 smalltalk.HLKeyBinderHelper);
 
@@ -1077,7 +1269,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=_st(_st(self)._keyBinder())._selectedBinding();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"selectedBinding",{}, smalltalk.HLKeyBinderHelper)})},
+}, function($ctx1) {$ctx1.fill(self,"selectedBinding",{},smalltalk.HLKeyBinderHelper)})},
 messageSends: ["selectedBinding", "keyBinder"]}),
 smalltalk.HLKeyBinderHelper);
 
@@ -1117,7 +1309,7 @@ _st($2)._keyBinder_(aKeyBinder);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"on:",{aKeyBinder:aKeyBinder}, smalltalk.HLKeyBinderHelper.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"on:",{aKeyBinder:aKeyBinder},smalltalk.HLKeyBinderHelper.klass)})},
 messageSends: ["keyBinder:", "new", "yourself"]}),
 smalltalk.HLKeyBinderHelper.klass);
 

+ 300 - 53
js/Helios-KeyBindings.js

@@ -1,5 +1,5 @@
 smalltalk.addPackage('Helios-KeyBindings');
-smalltalk.addClass('HLBinding', smalltalk.Object, ['key', 'label', 'each'], 'Helios-KeyBindings');
+smalltalk.addClass('HLBinding', smalltalk.Object, ['key', 'label'], 'Helios-KeyBindings');
 smalltalk.addMethod(
 "_applyOn_",
 smalltalk.method({
@@ -56,7 +56,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=_st(self)._label();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"displayLabel",{}, smalltalk.HLBinding)})},
+}, function($ctx1) {$ctx1.fill(self,"displayLabel",{},smalltalk.HLBinding)})},
 args: [],
 source: "displayLabel\x0a\x09^ self label",
 messageSends: ["label"],
@@ -108,7 +108,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@key"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"key",{}, smalltalk.HLBinding)})},
+}, function($ctx1) {$ctx1.fill(self,"key",{},smalltalk.HLBinding)})},
 args: [],
 source: "key\x0a\x09^ key",
 messageSends: [],
@@ -124,7 +124,7 @@ category: 'accessing',
 fn: function (anInteger){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
self["@key"]=anInteger;
-return self}, function($ctx1) {$ctx1.fill(self,"key:",{anInteger:anInteger}, smalltalk.HLBinding)})},
+return self}, function($ctx1) {$ctx1.fill(self,"key:",{anInteger:anInteger},smalltalk.HLBinding)})},
 args: ["anInteger"],
 source: "key: anInteger\x0a\x09key := anInteger",
 messageSends: [],
@@ -142,7 +142,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@label"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"label",{}, smalltalk.HLBinding)})},
+}, function($ctx1) {$ctx1.fill(self,"label",{},smalltalk.HLBinding)})},
 args: [],
 source: "label\x0a\x09^ label",
 messageSends: [],
@@ -158,7 +158,7 @@ category: 'accessing',
 fn: function (aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
self["@label"]=aString;
-return self}, function($ctx1) {$ctx1.fill(self,"label:",{aString:aString}, smalltalk.HLBinding)})},
+return self}, function($ctx1) {$ctx1.fill(self,"label:",{aString:aString},smalltalk.HLBinding)})},
 args: ["aString"],
 source: "label: aString\x0a\x09label := aString",
 messageSends: [],
@@ -166,6 +166,21 @@ referencedClasses: []
 }),
 smalltalk.HLBinding);
 
+smalltalk.addMethod(
+"_release",
+smalltalk.method({
+selector: "release",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"release",{},smalltalk.HLBinding)})},
+args: [],
+source: "release",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLBinding);
+
 smalltalk.addMethod(
 "_renderActionFor_html_",
 smalltalk.method({
@@ -204,7 +219,7 @@ selector: "renderOn:html:",
 category: 'rendering',
 fn: function (aBindingHelper,html){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"renderOn:html:",{aBindingHelper:aBindingHelper,html:html}, smalltalk.HLBinding)})},
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"renderOn:html:",{aBindingHelper:aBindingHelper,html:html},smalltalk.HLBinding)})},
 args: ["aBindingHelper", "html"],
 source: "renderOn: aBindingHelper html: html",
 messageSends: [],
@@ -222,7 +237,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=_st((smalltalk.String || String))._fromCharCode_(_st(self)._key());
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"shortcut",{}, smalltalk.HLBinding)})},
+}, function($ctx1) {$ctx1.fill(self,"shortcut",{},smalltalk.HLBinding)})},
 args: [],
 source: "shortcut\x0a\x09^ String fromCharCode: self key",
 messageSends: ["fromCharCode:", "key"],
@@ -245,7 +260,7 @@ _st($2)._label_(aString);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"on:labelled:",{anInteger:anInteger,aString:aString}, smalltalk.HLBinding.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"on:labelled:",{anInteger:anInteger,aString:aString},smalltalk.HLBinding.klass)})},
 args: ["anInteger", "aString"],
 source: "on: anInteger labelled: aString\x0a\x09^ self new\x0a    \x09key: anInteger;\x0a        label: aString;\x0a        yourself",
 messageSends: ["key:", "new", "label:", "yourself"],
@@ -321,19 +336,20 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $2,$3,$4,$5,$1;
 $2=_st((smalltalk.HLBindingInput || HLBindingInput))._new();
 _st($2)._label_(_st(_st(self)._command())._inputLabel());
-_st($2)._callback_((function(val){
+_st($2)._callback_((function(val,errorBlock){
 return smalltalk.withContext(function($ctx2) {
$3=_st(self)._command();
 _st($3)._input_(val);
+_st($3)._errorBlock_(errorBlock);
 $4=_st($3)._execute();
 return $4;
-}, function($ctx2) {$ctx2.fillBlock({val:val},$ctx1)})}));
+}, function($ctx2) {$ctx2.fillBlock({val:val,errorBlock:errorBlock},$ctx1)})}));
 $5=_st($2)._yourself();
 $1=$5;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"inputBinding",{},smalltalk.HLBindingAction)})},
 args: [],
-source: "inputBinding\x0a\x09^ HLBindingInput new\x0a\x09\x09label: self command inputLabel;\x0a\x09\x09callback: [ :val | \x0a\x09\x09\x09self command \x0a\x09\x09\x09\x09input: val;\x0a\x09\x09\x09\x09execute ];\x0a\x09\x09yourself",
-messageSends: ["label:", "inputLabel", "command", "new", "callback:", "input:", "execute", "yourself"],
+source: "inputBinding\x0a\x09^ HLBindingInput new\x0a\x09\x09label: self command inputLabel;\x0a\x09\x09callback: [ :val :errorBlock | \x0a\x09\x09\x09self command \x0a\x09\x09\x09\x09input: val;\x0a\x09\x09\x09\x09errorBlock: errorBlock;\x0a\x09\x09\x09\x09execute ];\x0a\x09\x09yourself",
+messageSends: ["label:", "inputLabel", "command", "new", "callback:", "input:", "errorBlock:", "execute", "yourself"],
 referencedClasses: ["HLBindingInput"]
 }),
 smalltalk.HLBindingAction);
@@ -407,7 +423,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=_st(_st(self)._bindings())._add_(aBinding);
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"add:",{aBinding:aBinding}, smalltalk.HLBindingGroup)})},
+}, function($ctx1) {$ctx1.fill(self,"add:",{aBinding:aBinding},smalltalk.HLBindingGroup)})},
 args: ["aBinding"],
 source: "add: aBinding\x0a\x09^ self bindings add: aBinding",
 messageSends: ["add:", "bindings"],
@@ -427,7 +443,7 @@ $1=_st((smalltalk.HLBindingAction || HLBindingAction))._on_labelled_(anInteger,a
 _st($1)._callback_(aBlock);
 $2=_st($1)._yourself();
 _st(self)._add_($2);
-return self}, function($ctx1) {$ctx1.fill(self,"addActionKey:labelled:callback:",{anInteger:anInteger,aString:aString,aBlock:aBlock}, smalltalk.HLBindingGroup)})},
+return self}, function($ctx1) {$ctx1.fill(self,"addActionKey:labelled:callback:",{anInteger:anInteger,aString:aString,aBlock:aBlock},smalltalk.HLBindingGroup)})},
 args: ["anInteger", "aString", "aBlock"],
 source: "addActionKey: anInteger labelled: aString callback: aBlock\x0a\x09self add: ((HLBindingAction on: anInteger labelled: aString)\x0a    \x09callback: aBlock;\x0a        yourself)",
 messageSends: ["add:", "callback:", "on:labelled:", "yourself"],
@@ -443,7 +459,7 @@ category: 'accessing',
 fn: function (anInteger,aString){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
_st(self)._add_(_st((smalltalk.HLBindingGroup || HLBindingGroup))._on_labelled_(anInteger,aString));
-return self}, function($ctx1) {$ctx1.fill(self,"addGroupKey:labelled:",{anInteger:anInteger,aString:aString}, smalltalk.HLBindingGroup)})},
+return self}, function($ctx1) {$ctx1.fill(self,"addGroupKey:labelled:",{anInteger:anInteger,aString:aString},smalltalk.HLBindingGroup)})},
 args: ["anInteger", "aString"],
 source: "addGroupKey: anInteger labelled: aString\x0a\x09self add: (HLBindingGroup on: anInteger labelled: aString)",
 messageSends: ["add:", "on:labelled:"],
@@ -465,7 +481,7 @@ return smalltalk.withContext(function($ctx2) {
return _st(_st(each)._label()).__
 return smalltalk.withContext(function($ctx2) {
return nil;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"at:",{aString:aString}, smalltalk.HLBindingGroup)})},
+}, function($ctx1) {$ctx1.fill(self,"at:",{aString:aString},smalltalk.HLBindingGroup)})},
 args: ["aString"],
 source: "at: aString\x0a\x09^ self bindings \x0a    \x09detect: [ :each | each label = aString ]\x0a      \x09ifNone: [ nil ]",
 messageSends: ["detect:ifNone:", "=", "label", "bindings"],
@@ -513,7 +529,7 @@ return smalltalk.withContext(function($ctx2) {
return _st(_st(each)._key()).__eq
 return smalltalk.withContext(function($ctx2) {
return nil;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"atKey:",{anInteger:anInteger}, smalltalk.HLBindingGroup)})},
+}, function($ctx1) {$ctx1.fill(self,"atKey:",{anInteger:anInteger},smalltalk.HLBindingGroup)})},
 args: ["anInteger"],
 source: "atKey: anInteger\x0a\x09^ self bindings \x0a    \x09detect: [ :each | each key = anInteger ]\x0a      \x09ifNone: [ nil ]",
 messageSends: ["detect:ifNone:", "=", "key", "bindings"],
@@ -537,7 +553,7 @@ $1=self["@bindings"];
 $1=$2;
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"bindings",{}, smalltalk.HLBindingGroup)})},
+}, function($ctx1) {$ctx1.fill(self,"bindings",{},smalltalk.HLBindingGroup)})},
 args: [],
 source: "bindings\x0a\x09^ bindings ifNil: [ bindings := OrderedCollection new ]",
 messageSends: ["ifNil:", "new"],
@@ -555,7 +571,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=_st(smalltalk.HLBinding.fn.prototype._displayLabel.apply(_st(self), [])).__comma("...");
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"displayLabel",{}, smalltalk.HLBindingGroup)})},
+}, function($ctx1) {$ctx1.fill(self,"displayLabel",{},smalltalk.HLBindingGroup)})},
 args: [],
 source: "displayLabel\x0a\x09^ super displayLabel, '...'",
 messageSends: [",", "displayLabel"],
@@ -581,6 +597,24 @@ referencedClasses: []
 }),
 smalltalk.HLBindingGroup);
 
+smalltalk.addMethod(
+"_release",
+smalltalk.method({
+selector: "release",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._bindings())._do_((function(each){
+return smalltalk.withContext(function($ctx2) {
return _st(each)._release();
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"release",{},smalltalk.HLBindingGroup)})},
+args: [],
+source: "release\x0a\x09self bindings do: [ :each | each release ]",
+messageSends: ["do:", "release", "bindings"],
+referencedClasses: []
+}),
+smalltalk.HLBindingGroup);
+
 smalltalk.addMethod(
 "_renderOn_html_",
 smalltalk.method({
@@ -603,7 +637,7 @@ smalltalk.HLBindingGroup);
 
 
 
-smalltalk.addClass('HLBindingInput', smalltalk.HLBinding, ['input', 'callback'], 'Helios-KeyBindings');
+smalltalk.addClass('HLBindingInput', smalltalk.HLBinding, ['input', 'callback', 'status', 'inputText', 'wrapper', 'binder'], 'Helios-KeyBindings');
 smalltalk.addMethod(
 "_applyOn_",
 smalltalk.method({
@@ -611,11 +645,19 @@ selector: "applyOn:",
 category: 'actions',
 fn: function (aKeyBinder){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
_st(self)._evaluate_(_st(self)._input());
-return self}, function($ctx1) {$ctx1.fill(self,"applyOn:",{aKeyBinder:aKeyBinder},smalltalk.HLBindingInput)})},
+return smalltalk.withContext(function($ctx1) { 
var $early={};
+try {
+_st(self)._evaluate_onError_(_st(self)._input(),(function(){
+return smalltalk.withContext(function($ctx2) {
_st(self)._errorStatus();
+_st(self)._refresh();
+throw $early=[false];
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"applyOn:",{aKeyBinder:aKeyBinder},smalltalk.HLBindingInput)})},
 args: ["aKeyBinder"],
-source: "applyOn: aKeyBinder\x0a\x09self evaluate: self input",
-messageSends: ["evaluate:", "input"],
+source: "applyOn: aKeyBinder\x0a\x09self \x0a\x09\x09evaluate: self input \x0a\x09\x09onError: [ \x0a\x09\x09\x09self errorStatus.\x0a\x09\x09\x09self refresh.\x0a\x09\x09\x09^ false ]",
+messageSends: ["evaluate:onError:", "input", "errorStatus", "refresh"],
 referencedClasses: []
 }),
 smalltalk.HLBindingInput);
@@ -637,7 +679,7 @@ $1=self["@callback"];
 $1=$2;
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"callback",{},smalltalk.HLInputBinding)})},
+}, function($ctx1) {$ctx1.fill(self,"callback",{},smalltalk.HLBindingInput)})},
 args: [],
 source: "callback\x0a\x09^ callback ifNil: [ callback := [ :value | ] ]",
 messageSends: ["ifNil:"],
@@ -653,7 +695,7 @@ category: 'accessing',
 fn: function (aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
self["@callback"]=aBlock;
-return self}, function($ctx1) {$ctx1.fill(self,"callback:",{aBlock:aBlock},smalltalk.HLInputBinding)})},
+return self}, function($ctx1) {$ctx1.fill(self,"callback:",{aBlock:aBlock},smalltalk.HLBindingInput)})},
 args: ["aBlock"],
 source: "callback: aBlock\x0a\x09callback := aBlock",
 messageSends: [],
@@ -661,6 +703,22 @@ referencedClasses: []
 }),
 smalltalk.HLBindingInput);
 
+smalltalk.addMethod(
+"_errorStatus",
+smalltalk.method({
+selector: "errorStatus",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(self)._status_("error");
+return self}, function($ctx1) {$ctx1.fill(self,"errorStatus",{},smalltalk.HLBindingInput)})},
+args: [],
+source: "errorStatus\x0a\x09self status: 'error'",
+messageSends: ["status:"],
+referencedClasses: []
+}),
+smalltalk.HLBindingInput);
+
 smalltalk.addMethod(
 "_evaluate_",
 smalltalk.method({
@@ -677,6 +735,22 @@ referencedClasses: []
 }),
 smalltalk.HLBindingInput);
 
+smalltalk.addMethod(
+"_evaluate_onError_",
+smalltalk.method({
+selector: "evaluate:onError:",
+category: 'actions',
+fn: function (aString,aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._callback())._value_value_(aString,aBlock);
+return self}, function($ctx1) {$ctx1.fill(self,"evaluate:onError:",{aString:aString,aBlock:aBlock},smalltalk.HLBindingInput)})},
+args: ["aString", "aBlock"],
+source: "evaluate: aString onError: aBlock\x0a\x09self callback value: aString value: aBlock",
+messageSends: ["value:value:", "callback"],
+referencedClasses: []
+}),
+smalltalk.HLBindingInput);
+
 smalltalk.addMethod(
 "_input",
 smalltalk.method({
@@ -695,6 +769,46 @@ referencedClasses: []
 }),
 smalltalk.HLBindingInput);
 
+smalltalk.addMethod(
+"_inputText",
+smalltalk.method({
+selector: "inputText",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@inputText"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@inputText"]="";
+$1=self["@inputText"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"inputText",{},smalltalk.HLBindingInput)})},
+args: [],
+source: "inputText\x0a\x09^ inputText ifNil: [ inputText := '' ].",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_inputText_",
+smalltalk.method({
+selector: "inputText:",
+category: 'accessing',
+fn: function (aText){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@inputText"]=aText;
+return self}, function($ctx1) {$ctx1.fill(self,"inputText:",{aText:aText},smalltalk.HLBindingInput)})},
+args: ["aText"],
+source: "inputText: aText\x0a\x09inputText := aText",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLBindingInput);
+
 smalltalk.addMethod(
 "_isActive",
 smalltalk.method({
@@ -711,6 +825,93 @@ referencedClasses: []
 }),
 smalltalk.HLBindingInput);
 
+smalltalk.addMethod(
+"_refresh",
+smalltalk.method({
+selector: "refresh",
+category: 'rendering',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2;
+$1=self["@wrapper"];
+if(($receiver = $1) == nil || $receiver == undefined){
+$2=self;
+return $2;
+} else {
+$1;
+};
+_st(_st(self["@wrapper"])._asJQuery())._empty();
+_st((function(html){
+return smalltalk.withContext(function($ctx2) {
return _st(self)._renderActionFor_html_(self["@binder"],html);
+}, function($ctx2) {$ctx2.fillBlock({html:html},$ctx1)})}))._appendToJQuery_(_st(self["@wrapper"])._asJQuery());
+return self}, function($ctx1) {$ctx1.fill(self,"refresh",{},smalltalk.HLBindingInput)})},
+args: [],
+source: "refresh\x0a\x09wrapper ifNil: [ ^ self ].\x0a    \x0a\x09wrapper asJQuery empty.\x0a    [ :html | self renderActionFor: binder html: html ] appendToJQuery: wrapper asJQuery",
+messageSends: ["ifNil:", "empty", "asJQuery", "appendToJQuery:", "renderActionFor:html:"],
+referencedClasses: []
+}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_release",
+smalltalk.method({
+selector: "release",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@status"]=nil;
+self["@wrapper"]=nil;
+self["@binder"]=nil;
+self["@inputText"]=nil;
+return self}, function($ctx1) {$ctx1.fill(self,"release",{},smalltalk.HLBindingInput)})},
+args: [],
+source: "release\x0a\x09status := nil.\x0a\x09wrapper := nil.\x0a\x09binder := nil.\x0a\x09inputText := nil",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_renderActionFor_html_",
+smalltalk.method({
+selector: "renderActionFor:html:",
+category: 'rendering',
+fn: function (aBinder,html){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $1,$2,$4,$5,$3,$6;
+self["@binder"]=aBinder;
+$1=self["@wrapper"];
+if(($receiver = $1) == nil || $receiver == undefined){
+self["@wrapper"]=_st(html)._span();
+self["@wrapper"];
+} else {
+$1;
+};
+$2=self["@wrapper"];
+_st($2)._class_(_st("control-group ").__comma(_st(self)._status()));
+$3=_st($2)._with_((function(){
+return smalltalk.withContext(function($ctx2) {
$4=_st(html)._input();
+_st($4)._class_("input");
+_st($4)._placeholder_(_st(self)._displayLabel());
+$5=_st($4)._with_(_st(self)._inputText());
+self["@input"]=$5;
+return self["@input"];
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st(self["@input"])._onKeyPress_((function(event){
+return smalltalk.withContext(function($ctx2) {
$6=_st(_st(event)._keyCode()).__eq((13));
+if(smalltalk.assert($6)){
+return _st(self)._applyOn_(aBinder);
+};
+}, function($ctx2) {$ctx2.fillBlock({event:event},$ctx1)})}));
+_st(_st(self["@input"])._asJQuery())._focus();
+return self}, function($ctx1) {$ctx1.fill(self,"renderActionFor:html:",{aBinder:aBinder,html:html},smalltalk.HLBindingInput)})},
+args: ["aBinder", "html"],
+source: "renderActionFor: aBinder html: html\x0a\x09binder := aBinder.\x0a\x09wrapper ifNil: [ wrapper := html span ].\x0a\x09\x0a\x09wrapper\x0a\x09\x09class: 'control-group ', self status; \x0a\x09\x09with: [\x0a\x09\x09\x09input := html input\x0a\x09\x09\x09\x09class: 'input';\x0a\x09\x09\x09\x09placeholder: self displayLabel;\x0a\x09\x09\x09\x09with: self inputText ].\x0a\x09\x09\x09\x09\x0a\x09input onKeyPress: [ :event |\x0a\x09\x09event keyCode = 13 \x0a\x09\x09\x09ifTrue: [ self applyOn: aBinder ] ].\x0a\x09\x09\x09\x09\x0a\x09input asJQuery focus",
+messageSends: ["ifNil:", "span", "class:", ",", "status", "with:", "input", "placeholder:", "displayLabel", "inputText", "onKeyPress:", "ifTrue:", "applyOn:", "=", "keyCode", "focus", "asJQuery"],
+referencedClasses: []
+}),
+smalltalk.HLBindingInput);
+
 smalltalk.addMethod(
 "_renderOn_html_",
 smalltalk.method({
@@ -743,6 +944,46 @@ referencedClasses: []
 }),
 smalltalk.HLBindingInput);
 
+smalltalk.addMethod(
+"_status",
+smalltalk.method({
+selector: "status",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
var $2,$1;
+$2=self["@status"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@status"]="info";
+$1=self["@status"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"status",{},smalltalk.HLBindingInput)})},
+args: [],
+source: "status\x0a\x09^ status ifNil: [ status := 'info' ]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.HLBindingInput);
+
+smalltalk.addMethod(
+"_status_",
+smalltalk.method({
+selector: "status:",
+category: 'accessing',
+fn: function (aStatus){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
self["@status"]=aStatus;
+return self}, function($ctx1) {$ctx1.fill(self,"status:",{aStatus:aStatus},smalltalk.HLBindingInput)})},
+args: ["aStatus"],
+source: "status: aStatus\x0a\x09status := aStatus",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLBindingInput);
+
 
 
 smalltalk.addClass('HLKeyBinder', smalltalk.Object, ['modifierKey', 'helper', 'bindings', 'selectedBinding'], 'Helios-KeyBindings');
@@ -770,7 +1011,7 @@ category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
return (32);
-}, function($ctx1) {$ctx1.fill(self,"activationKey",{}, smalltalk.HLKeyBinder)})},
+}, function($ctx1) {$ctx1.fill(self,"activationKey",{},smalltalk.HLKeyBinder)})},
 args: [],
 source: "activationKey\x0a\x09\x22SPACE\x22\x0a\x09^ 32",
 messageSends: [],
@@ -786,7 +1027,7 @@ category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
return "ctrl + space";
-}, function($ctx1) {$ctx1.fill(self,"activationKeyLabel",{}, smalltalk.HLKeyBinder)})},
+}, function($ctx1) {$ctx1.fill(self,"activationKeyLabel",{},smalltalk.HLKeyBinder)})},
 args: [],
 source: "activationKeyLabel\x0a\x09^ 'ctrl + space'",
 messageSends: [],
@@ -852,12 +1093,19 @@ selector: "deactivate",
 category: 'actions',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
self["@selectedBinding"]=nil;
+return smalltalk.withContext(function($ctx1) { 
var $1;
+$1=self["@selectedBinding"];
+if(($receiver = $1) == nil || $receiver == undefined){
+$1;
+} else {
+_st(self["@selectedBinding"])._release();
+};
+self["@selectedBinding"]=nil;
 _st(_st(self)._helper())._hide();
 return self}, function($ctx1) {$ctx1.fill(self,"deactivate",{},smalltalk.HLKeyBinder)})},
 args: [],
-source: "deactivate\x0a    selectedBinding := nil.\x0a\x09self helper hide",
-messageSends: ["hide", "helper"],
+source: "deactivate\x0a\x09selectedBinding ifNotNil: [ selectedBinding release ].\x0a    selectedBinding := nil.\x0a\x09self helper hide",
+messageSends: ["ifNotNil:", "release", "hide", "helper"],
 referencedClasses: []
 }),
 smalltalk.HLKeyBinder);
@@ -895,7 +1143,7 @@ category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
return (27);
-}, function($ctx1) {$ctx1.fill(self,"escapeKey",{}, smalltalk.HLKeyBinder)})},
+}, function($ctx1) {$ctx1.fill(self,"escapeKey",{},smalltalk.HLKeyBinder)})},
 args: [],
 source: "escapeKey\x0a\x09\x22ESC\x22\x0a\x09^ 27",
 messageSends: [],
@@ -911,7 +1159,7 @@ category: 'actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
self["@bindings"]=nil;
-return self}, function($ctx1) {$ctx1.fill(self,"flushBindings",{}, smalltalk.HLKeyBinder)})},
+return self}, function($ctx1) {$ctx1.fill(self,"flushBindings",{},smalltalk.HLKeyBinder)})},
 args: [],
 source: "flushBindings\x0a\x09bindings := nil",
 messageSends: [],
@@ -939,7 +1187,7 @@ return false;
 };
 $2=_st(self)._handleBindingFor_(event);
 return $2;
-}, function($ctx1) {$ctx1.fill(self,"handleActiveKeyDown:",{event:event}, smalltalk.HLKeyBinder)})},
+}, function($ctx1) {$ctx1.fill(self,"handleActiveKeyDown:",{event:event},smalltalk.HLKeyBinder)})},
 args: ["event"],
 source: "handleActiveKeyDown: event\x0a\x0a\x09\x22ESC or ctrl+g deactivate the keyBinder\x22\x0a\x09(event which = self escapeKey or: [\x0a\x09\x09event which = 71 and: [ event ctrlKey ] ])\x0a        \x09ifTrue: [ \x0a            \x09self deactivate.\x0a\x09\x09\x09\x09event preventDefault.\x0a\x09\x09\x09\x09^ false ].\x0a            \x0a    \x22Handle the keybinding\x22\x0a    ^ self handleBindingFor: event",
 messageSends: ["ifTrue:", "deactivate", "preventDefault", "or:", "and:", "ctrlKey", "=", "which", "escapeKey", "handleBindingFor:"],
@@ -965,7 +1213,7 @@ _st(self)._applyBinding_(binding);
 _st(anEvent)._preventDefault();
 return false;
 };
-return self}, function($ctx1) {$ctx1.fill(self,"handleBindingFor:",{anEvent:anEvent,binding:binding}, smalltalk.HLKeyBinder)})},
+return self}, function($ctx1) {$ctx1.fill(self,"handleBindingFor:",{anEvent:anEvent,binding:binding},smalltalk.HLKeyBinder)})},
 args: ["anEvent"],
 source: "handleBindingFor: anEvent\x0a\x09| binding |\x0a    binding := self selectedBinding atKey: anEvent which.\x0a    \x0a    binding ifNotNil: [ \x0a    \x09self applyBinding: binding.\x0a\x09\x09anEvent preventDefault.\x0a\x09\x09^ false ]",
 messageSends: ["atKey:", "which", "selectedBinding", "ifNotNil:", "applyBinding:", "preventDefault"],
@@ -990,7 +1238,7 @@ _st(event)._preventDefault();
 return false;
 };
 };
-return self}, function($ctx1) {$ctx1.fill(self,"handleInactiveKeyDown:",{event:event}, smalltalk.HLKeyBinder)})},
+return self}, function($ctx1) {$ctx1.fill(self,"handleInactiveKeyDown:",{event:event},smalltalk.HLKeyBinder)})},
 args: ["event"],
 source: "handleInactiveKeyDown: event\x0a      event which = self activationKey ifTrue: [\x0a      \x09\x09event ctrlKey  ifTrue: [\x0a\x09\x09\x09\x09\x09self activate. \x0a               \x09\x09 event preventDefault. \x0a                \x09^ false ] ]",
 messageSends: ["ifTrue:", "activate", "preventDefault", "ctrlKey", "=", "activationKey", "which"],
@@ -1013,7 +1261,7 @@ $1=_st(self)._handleActiveKeyDown_(event);
 $1=_st(self)._handleInactiveKeyDown_(event);
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"handleKeyDown:",{event:event}, smalltalk.HLKeyBinder)})},
+}, function($ctx1) {$ctx1.fill(self,"handleKeyDown:",{event:event},smalltalk.HLKeyBinder)})},
 args: ["event"],
 source: "handleKeyDown: event\x0a\x09^ self isActive\x0a    \x09ifTrue: [ self handleActiveKeyDown: event ]\x0a      \x09ifFalse: [ self handleInactiveKeyDown: event ]",
 messageSends: ["ifTrue:ifFalse:", "handleActiveKeyDown:", "handleInactiveKeyDown:", "isActive"],
@@ -1031,7 +1279,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@helper"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"helper",{}, smalltalk.HLKeyBinder)})},
+}, function($ctx1) {$ctx1.fill(self,"helper",{},smalltalk.HLKeyBinder)})},
 args: [],
 source: "helper\x0a\x09^ helper",
 messageSends: [],
@@ -1052,10 +1300,9 @@ self["@helper"]=_st((smalltalk.HLKeyBinderHelper || HLKeyBinderHelper))._on_(sel
 $1=self["@helper"];
 _st($1)._renderStart();
 $2=_st($1)._renderCog();
-self["@active"]=false;
 return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLKeyBinder)})},
 args: [],
-source: "initialize\x0a\x09super initialize.\x0a\x09helper := HLKeyBinderHelper on: self.\x0a\x09helper \x09\x0a\x09\x09renderStart;\x0a\x09\x09renderCog.\x0a    active := false",
+source: "initialize\x0a\x09super initialize.\x0a\x09helper := HLKeyBinderHelper on: self.\x0a\x09helper \x09\x0a\x09\x09renderStart;\x0a\x09\x09renderCog",
 messageSends: ["initialize", "on:", "renderStart", "renderCog"],
 referencedClasses: ["HLKeyBinderHelper"]
 }),
@@ -1111,7 +1358,7 @@ $1=_st(self)._bindings();
 $1=$2;
 };
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"selectedBinding",{}, smalltalk.HLKeyBinder)})},
+}, function($ctx1) {$ctx1.fill(self,"selectedBinding",{},smalltalk.HLKeyBinder)})},
 args: [],
 source: "selectedBinding\x0a\x09^ selectedBinding ifNil: [ self bindings ]",
 messageSends: ["ifNil:", "bindings"],
@@ -1129,7 +1376,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
_st(_st(window)._jQuery_("body"))._keydown_((function(event){
 return smalltalk.withContext(function($ctx2) {
return _st(self)._handleKeyDown_(event);
 }, function($ctx2) {$ctx2.fillBlock({event:event},$ctx1)})}));
-return self}, function($ctx1) {$ctx1.fill(self,"setupEvents",{}, smalltalk.HLKeyBinder)})},
+return self}, function($ctx1) {$ctx1.fill(self,"setupEvents",{},smalltalk.HLKeyBinder)})},
 args: [],
 source: "setupEvents\x0a\x09(window jQuery: 'body') keydown: [ :event | self handleKeyDown: event ]",
 messageSends: ["keydown:", "handleKeyDown:", "jQuery:"],
@@ -1147,7 +1394,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=_st(_st(navigator)._platform())._match_("Mac");
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"systemIsMac",{}, smalltalk.HLKeyBinder)})},
+}, function($ctx1) {$ctx1.fill(self,"systemIsMac",{},smalltalk.HLKeyBinder)})},
 args: [],
 source: "systemIsMac\x0a\x09^ navigator platform match: 'Mac'",
 messageSends: ["match:", "platform"],
@@ -1166,7 +1413,7 @@ category: 'accessing',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
return "key_helper";
-}, function($ctx1) {$ctx1.fill(self,"cssClass",{}, smalltalk.HLKeyBinderHelper)})},
+}, function($ctx1) {$ctx1.fill(self,"cssClass",{},smalltalk.HLKeyBinderHelper)})},
 args: [],
 source: "cssClass\x0a\x09^ 'key_helper'",
 messageSends: [],
@@ -1217,7 +1464,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=self["@keyBinder"];
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"keyBinder",{}, smalltalk.HLKeyBinderHelper)})},
+}, function($ctx1) {$ctx1.fill(self,"keyBinder",{},smalltalk.HLKeyBinderHelper)})},
 args: [],
 source: "keyBinder\x0a\x09^ keyBinder",
 messageSends: [],
@@ -1233,7 +1480,7 @@ category: 'accessing',
 fn: function (aKeyBinder){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
self["@keyBinder"]=aKeyBinder;
-return self}, function($ctx1) {$ctx1.fill(self,"keyBinder:",{aKeyBinder:aKeyBinder}, smalltalk.HLKeyBinderHelper)})},
+return self}, function($ctx1) {$ctx1.fill(self,"keyBinder:",{aKeyBinder:aKeyBinder},smalltalk.HLKeyBinderHelper)})},
 args: ["aKeyBinder"],
 source: "keyBinder: aKeyBinder\x0a\x09keyBinder := aKeyBinder",
 messageSends: [],
@@ -1248,7 +1495,7 @@ selector: "registerBindings",
 category: 'keyBindings',
 fn: function (){
 var self=this;
-return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"registerBindings",{}, smalltalk.HLKeyBinderHelper)})},
+return smalltalk.withContext(function($ctx1) { 
return self}, function($ctx1) {$ctx1.fill(self,"registerBindings",{},smalltalk.HLKeyBinderHelper)})},
 args: [],
 source: "registerBindings\x0a\x09\x22Do nothing\x22",
 messageSends: [],
@@ -1284,7 +1531,7 @@ category: 'rendering',
 fn: function (html){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
_st(_st(self)._selectedBinding())._renderOn_html_(self,html);
-return self}, function($ctx1) {$ctx1.fill(self,"renderBindingOn:",{html:html}, smalltalk.HLKeyBinderHelper)})},
+return self}, function($ctx1) {$ctx1.fill(self,"renderBindingOn:",{html:html},smalltalk.HLKeyBinderHelper)})},
 args: ["html"],
 source: "renderBindingOn: html\x0a\x09self selectedBinding renderOn: self html: html",
 messageSends: ["renderOn:html:", "selectedBinding"],
@@ -1390,7 +1637,7 @@ $4="Action";
 $4=$5;
 };
 $2=_st($3)._with_($4);
-return self}, function($ctx1) {$ctx1.fill(self,"renderSelectionOn:",{html:html}, smalltalk.HLKeyBinderHelper)})},
+return self}, function($ctx1) {$ctx1.fill(self,"renderSelectionOn:",{html:html},smalltalk.HLKeyBinderHelper)})},
 args: ["html"],
 source: "renderSelectionOn: html\x0a\x09\x09html span \x0a        \x09class: 'selected'; \x0a            with: (self selectedBinding label ifNil: [ 'Action' ])",
 messageSends: ["class:", "span", "with:", "ifNil:", "label", "selectedBinding"],
@@ -1415,7 +1662,7 @@ return $2;
 _st((function(){
 return smalltalk.withContext(function($ctx2) {
return _st(_st(window)._jQuery_("#keybinding-start-helper"))._fadeOut_((1000));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._valueWithTimeout_((2000));
-return self}, function($ctx1) {$ctx1.fill(self,"renderStart",{}, smalltalk.HLKeyBinderHelper)})},
+return self}, function($ctx1) {$ctx1.fill(self,"renderStart",{},smalltalk.HLKeyBinderHelper)})},
 args: [],
 source: "renderStart\x0a\x09[ :html |\x0a\x09\x09html div \x0a\x09\x09\x09id: 'keybinding-start-helper';\x0a\x09\x09\x09with: 'Press ', self keyBinder activationKeyLabel, ' to start' ] appendToJQuery: 'body' asJQuery.\x0a\x09\x0a\x09[ (window jQuery: '#keybinding-start-helper') fadeOut: 1000 ] \x0a\x09\x09valueWithTimeout: 2000",
 messageSends: ["appendToJQuery:", "asJQuery", "id:", "div", "with:", ",", "activationKeyLabel", "keyBinder", "valueWithTimeout:", "fadeOut:", "jQuery:"],
@@ -1433,7 +1680,7 @@ var self=this;
 return smalltalk.withContext(function($ctx1) { 
var $1;
 $1=_st(_st(self)._keyBinder())._selectedBinding();
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"selectedBinding",{}, smalltalk.HLKeyBinderHelper)})},
+}, function($ctx1) {$ctx1.fill(self,"selectedBinding",{},smalltalk.HLKeyBinderHelper)})},
 args: [],
 source: "selectedBinding\x0a\x09^ self keyBinder selectedBinding",
 messageSends: ["selectedBinding", "keyBinder"],
@@ -1488,7 +1735,7 @@ _st($2)._keyBinder_(aKeyBinder);
 $3=_st($2)._yourself();
 $1=$3;
 return $1;
-}, function($ctx1) {$ctx1.fill(self,"on:",{aKeyBinder:aKeyBinder}, smalltalk.HLKeyBinderHelper.klass)})},
+}, function($ctx1) {$ctx1.fill(self,"on:",{aKeyBinder:aKeyBinder},smalltalk.HLKeyBinderHelper.klass)})},
 args: ["aKeyBinder"],
 source: "on: aKeyBinder\x0a\x09^ self new\x0a    \x09keyBinder: aKeyBinder;\x0a        yourself",
 messageSends: ["keyBinder:", "new", "yourself"],

+ 9 - 9
st/Helios-Environments.st

@@ -1,7 +1,7 @@
 Smalltalk current createPackage: 'Helios-Environments'!
 Object subclass: #HLEnvironment
- instanceVariableNames: ''
- package: 'Helios-Environments'!
+	instanceVariableNames: ''
+	package: 'Helios-Environments'!
 !HLEnvironment commentStamp!
 Abstract class defining common behavior for local and remote environments!
 
@@ -51,8 +51,8 @@ compileMethod: sourceCode for: class protocol: protocol
 ! !
 
 HLEnvironment subclass: #HLLocalEnvironment
- instanceVariableNames: ''
- package: 'Helios-Environments'!
+	instanceVariableNames: ''
+	package: 'Helios-Environments'!
 
 !HLLocalEnvironment methodsFor: 'accessing'!
 
@@ -85,8 +85,8 @@ moveMethod: aMethod toClass: aClassName ifAbsent: aBlock
 ! !
 
 HLEnvironment subclass: #HLRemoteEnvironment
- instanceVariableNames: ''
- package: 'Helios-Environments'!
+	instanceVariableNames: ''
+	package: 'Helios-Environments'!
 
 !HLRemoteEnvironment methodsFor: 'accessing'!
 
@@ -112,8 +112,8 @@ eval: someCode on: aReceiver
 ! !
 
 Object subclass: #HLRemoteObject
- instanceVariableNames: ''
- package: 'Helios-Environments'!
+	instanceVariableNames: ''
+	package: 'Helios-Environments'!
 !HLRemoteObject commentStamp!
 This is a local proxy to a remote object.
 Tipically useful for evaluating and inspecting and interacting with instances of a remote VM.!
@@ -144,7 +144,7 @@ printString
 
 adoptMethod: aMethod
 	self 
-		compile: aMethod source;
+		compile: aMethod source
 		category: aMethod protocol.
 !
 

+ 80 - 6
st/Helios-KeyBindings.st

@@ -1,6 +1,6 @@
 Smalltalk current createPackage: 'Helios-KeyBindings'!
 Object subclass: #HLBinding
-	instanceVariableNames: 'key label each'
+	instanceVariableNames: 'key label'
 	package: 'Helios-KeyBindings'!
 
 !HLBinding methodsFor: 'accessing'!
@@ -39,6 +39,9 @@ applyOn: aKeyBinder
 !
 
 applyOn: aKeyBinder then: aBlock
+!
+
+release
 ! !
 
 !HLBinding methodsFor: 'rendering'!
@@ -95,9 +98,10 @@ command: aCommand
 inputBinding
 	^ HLBindingInput new
 		label: self command inputLabel;
-		callback: [ :val | 
+		callback: [ :val :errorBlock | 
 			self command 
 				input: val;
+				errorBlock: errorBlock;
 				execute ];
 		yourself
 ! !
@@ -173,6 +177,12 @@ displayLabel
 	^ super displayLabel, '...'
 ! !
 
+!HLBindingGroup methodsFor: 'actions'!
+
+release
+	self bindings do: [ :each | each release ]
+! !
+
 !HLBindingGroup methodsFor: 'rendering'!
 
 renderOn: aBindingHelper html: html
@@ -187,7 +197,7 @@ isActive
 ! !
 
 HLBinding subclass: #HLBindingInput
-	instanceVariableNames: 'input callback'
+	instanceVariableNames: 'input callback status inputText wrapper binder'
 	package: 'Helios-KeyBindings'!
 
 !HLBindingInput methodsFor: 'accessing'!
@@ -204,6 +214,14 @@ input
 	^ input asJQuery val
 !
 
+inputText
+	^ inputText ifNil: [ inputText := '' ].
+!
+
+inputText: aText
+	inputText := aText
+!
+
 renderOn: aBinder html: html
 	html span 
 		class: 'command'; 
@@ -217,16 +235,72 @@ renderOn: aBinder html: html
 			self applyOn: aBinder ] ].
 				
 	input asJQuery focus
+!
+
+status
+	^ status ifNil: [ status := 'info' ]
+!
+
+status: aStatus
+	status := aStatus
 ! !
 
 !HLBindingInput methodsFor: 'actions'!
 
 applyOn: aKeyBinder
-	self evaluate: self input
+	self 
+		evaluate: self input 
+		onError: [ 
+			self errorStatus.
+			self refresh.
+			^ false ]
+!
+
+errorStatus
+	self status: 'error'
 !
 
 evaluate: aString
 	self callback value: aString
+!
+
+evaluate: aString onError: aBlock
+	self callback value: aString value: aBlock
+!
+
+release
+	status := nil.
+	wrapper := nil.
+	binder := nil.
+	inputText := nil
+! !
+
+!HLBindingInput methodsFor: 'rendering'!
+
+refresh
+	wrapper ifNil: [ ^ self ].
+    
+	wrapper asJQuery empty.
+    [ :html | self renderActionFor: binder html: html ] appendToJQuery: wrapper asJQuery
+!
+
+renderActionFor: aBinder html: html
+	binder := aBinder.
+	wrapper ifNil: [ wrapper := html span ].
+	
+	wrapper
+		class: 'control-group ', self status; 
+		with: [
+			input := html input
+				class: 'input';
+				placeholder: self displayLabel;
+				with: self inputText ].
+				
+	input onKeyPress: [ :event |
+		event keyCode = 13 
+			ifTrue: [ self applyOn: aBinder ] ].
+				
+	input asJQuery focus
 ! !
 
 !HLBindingInput methodsFor: 'testing'!
@@ -283,6 +357,7 @@ applyBinding: aBinding
 !
 
 deactivate
+	selectedBinding ifNotNil: [ selectedBinding release ].
     selectedBinding := nil.
 	self helper hide
 !
@@ -362,8 +437,7 @@ initialize
 	helper := HLKeyBinderHelper on: self.
 	helper 	
 		renderStart;
-		renderCog.
-    active := false
+		renderCog
 ! !
 
 !HLKeyBinder methodsFor: 'testing'!