Browse Source

New confirmation dialog

Nicolas Petton 11 years ago
parent
commit
aaf615a522
10 changed files with 1557 additions and 166 deletions
  1. 87 1
      css/helios.css
  2. 264 34
      js/Helios-Browser.deploy.js
  3. 356 46
      js/Helios-Browser.js
  4. 236 7
      js/Helios-Core.deploy.js
  5. 303 9
      js/Helios-Core.js
  6. 39 19
      js/Helios-Workspace.deploy.js
  7. 48 23
      js/Helios-Workspace.js
  8. 105 12
      st/Helios-Browser.st
  9. 100 2
      st/Helios-Core.st
  10. 19 13
      st/Helios-Workspace.st

+ 87 - 1
css/helios.css

@@ -512,4 +512,90 @@ i {
     padding: 20px;
     background: rgba(0,0,0, 0.6);
     border-radius: 40px;
-}
+}
+
+#overlay {
+    z-index: 2000;
+    background: transparent;
+    position: fixed;
+    top: 0;
+    left: 0;
+    right: 0;
+    bottom: 0;
+}
+
+.confirmation {
+    z-index: 2001;
+    background: rgba(243,243,243,0.9);
+    background-image: -webkit-linear-gradient(top, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 5px, transparent 6px);
+    background-image: -moz-linear-gradient(top, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 5px, transparent 6px);
+    background-image: -o-linear-gradient(top, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 5px, transparent 6px);
+    background-image: linear-gradient(top, rgba(0,0,0,0.2) 0%, rgba(0,0,0,0) 5px, transparent 6px);
+    padding: 20px;
+    width: 250px;
+    position: fixed;
+    top: -500px;
+    left: 50%;
+    margin-left: -135px;
+    box-shadow: 0 0 6px #333;
+    transition: top .5s;
+    -webkit-transition: top .5s;
+    -moz-transition: top .5s;
+    -o-transition: top .5s;
+}
+
+.confirmation span {
+    font-size: 13px;
+    font-weight: bold;
+}
+
+.confirmation .buttons {
+    text-align: right;
+    margin-top: 20px;
+}
+
+.confirmation.active {
+    top: 0;
+}
+
+.button {
+    border-radius: 3px !important;
+    background: #ccc;
+    border: 1px solid #9B9B9B;
+    height: 20px;
+    border-radius: 5px;
+    min-width: 68px;
+    padding: 0 10px;
+    text-align: center;
+    margin: 0;
+    margin-left: 10px;
+    background: -webkit-linear-gradient(bottom, rgba(0,0,0,.09) 0%, rgba(0,0,0, 0.02) 50%, rgba(0,0,0,.04) 50.5%, rgba(0,0,0,.04) 100%) #fff;
+    font: 13px "Lucida Grande", Lucida, Verdana, sans-serif;
+}
+
+.button.default { 
+    border-top: 1px solid #535273;
+    border: 1px solid #4F4D67;
+    border-bottom: 1px solid #4B4B58;    
+    background: -webkit-linear-gradient(bottom, rgba(255,255,255,.5) 0%, rgba(255, 255, 255, 0.1) 50%, rgba(255,255,255,.3) 50.5%, rgba(255,255,255,.45) 95%, rgba(255,255,255,.8) 100%) #b1bdd5;
+    background: -moz-linear-gradient(bottom, rgba(255,255,255,.5) 0%, rgba(255, 255, 255, 0.1) 50%, rgba(255,255,255,.3) 50.5%, rgba(255,255,255,.45) 95%, rgba(255,255,255,.8) 100%) #b1bdd5;
+    -moz-box-shadow: 0 0 3px rgba(69, 113, 184, 0.8);
+    -webkit-box-shadow: 0 0 5px rgba(69, 113, 184, 0.44);
+    box-shadow: 0 0 5px rgba(69, 113, 184, 0.44);
+}
+
+
+.button:hover {
+    cursor: pointer;
+    border: 1px solid rgba(0,0,0,.6);
+}
+
+.button:active {
+    -webkit-box-shadow: inset 0 0 5px rgba(0,0,0,.5);
+    -moz-box-shadow: inset 0 0 5px rgba(0,0,0,.5);
+    box-shadow: inset 0 0 5px rgba(0,0,0,.5);
+}
+
+.button:focus {
+    outline: 0;
+}

+ 264 - 34
js/Helios-Browser.deploy.js

@@ -184,13 +184,13 @@ smalltalk.method({
 selector: "sourceWidget",
 fn: function (){
 var self=this;
-function $HLBrowserCodeWidget(){return smalltalk.HLBrowserCodeWidget||(typeof HLBrowserCodeWidget=="undefined"?nil:HLBrowserCodeWidget)}
+function $HLBrowserBottomWidget(){return smalltalk.HLBrowserBottomWidget||(typeof HLBrowserBottomWidget=="undefined"?nil:HLBrowserBottomWidget)}
 return smalltalk.withContext(function($ctx1) { 
 var $2,$3,$4,$1;
 $2=self["@sourceWidget"];
 if(($receiver = $2) == nil || $receiver == undefined){
-$3=_st($HLBrowserCodeWidget())._new();
-_st($3)._browserModel_(_st(self)._model());
+$3=_st($HLBrowserBottomWidget())._new();
+_st($3)._model_(_st(self)._model());
 $4=_st($3)._yourself();
 self["@sourceWidget"]=$4;
 $1=self["@sourceWidget"];
@@ -199,7 +199,7 @@ $1=$2;
 };
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"sourceWidget",{},smalltalk.HLBrowser)})},
-messageSends: ["ifNil:", "browserModel:", "model", "new", "yourself"]}),
+messageSends: ["ifNil:", "model:", "model", "new", "yourself"]}),
 smalltalk.HLBrowser);
 
 
@@ -260,6 +260,208 @@ messageSends: []}),
 smalltalk.HLBrowser.klass);
 
 
+smalltalk.addClass('HLBrowserBottomWidget', smalltalk.HLWidget, ['model', 'codeWidget', 'documentationWidget', 'selectedWidget'], 'Helios-Browser');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "canHaveFocus",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return true;
+}, function($ctx1) {$ctx1.fill(self,"canHaveFocus",{},smalltalk.HLBrowserBottomWidget)})},
+messageSends: []}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "codeWidget",
+fn: function (){
+var self=this;
+function $HLBrowserCodeWidget(){return smalltalk.HLBrowserCodeWidget||(typeof HLBrowserCodeWidget=="undefined"?nil:HLBrowserCodeWidget)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$4,$1;
+$2=self["@codeWidget"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$3=_st($HLBrowserCodeWidget())._new();
+_st($3)._browserModel_(_st(self)._model());
+$4=_st($3)._yourself();
+self["@codeWidget"]=$4;
+$1=self["@codeWidget"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"codeWidget",{},smalltalk.HLBrowserBottomWidget)})},
+messageSends: ["ifNil:", "browserModel:", "model", "new", "yourself"]}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "documentationWidget",
+fn: function (){
+var self=this;
+function $HLDocumentationWidget(){return smalltalk.HLDocumentationWidget||(typeof HLDocumentationWidget=="undefined"?nil:HLDocumentationWidget)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$4,$1;
+$2=self["@documentationWidget"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$3=_st($HLDocumentationWidget())._new();
+_st($3)._model_(_st(self)._model());
+$4=_st($3)._yourself();
+self["@documentationWidget"]=$4;
+$1=self["@documentationWidget"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"documentationWidget",{},smalltalk.HLBrowserBottomWidget)})},
+messageSends: ["ifNil:", "model:", "model", "new", "yourself"]}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "focus",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(_st(self)._selectedWidget())._focus();
+return self}, function($ctx1) {$ctx1.fill(self,"focus",{},smalltalk.HLBrowserBottomWidget)})},
+messageSends: ["focus", "selectedWidget"]}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "model",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@model"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"model",{},smalltalk.HLBrowserBottomWidget)})},
+messageSends: []}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "model:",
+fn: function (aModel){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@model"]=aModel;
+_st(self)._observeModel();
+return self}, function($ctx1) {$ctx1.fill(self,"model:",{aModel:aModel},smalltalk.HLBrowserBottomWidget)})},
+messageSends: ["observeModel"]}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "observeModel",
+fn: function (){
+var self=this;
+function $HLShowInstanceToggled(){return smalltalk.HLShowInstanceToggled||(typeof HLShowInstanceToggled=="undefined"?nil:HLShowInstanceToggled)}
+function $HLShowCommentToggled(){return smalltalk.HLShowCommentToggled||(typeof HLShowCommentToggled=="undefined"?nil:HLShowCommentToggled)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st(_st(self)._model())._announcer();
+_st($1)._on_do_($HLShowInstanceToggled(),(function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(self)._onShowInstanceToggled();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$2=_st($1)._on_do_($HLShowCommentToggled(),(function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(self)._onShowCommentToggled();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"observeModel",{},smalltalk.HLBrowserBottomWidget)})},
+messageSends: ["on:do:", "onShowInstanceToggled", "announcer", "model", "onShowCommentToggled"]}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "onShowCommentToggled",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self)._selectWidget_(_st(self)._documentationWidget());
+return self}, function($ctx1) {$ctx1.fill(self,"onShowCommentToggled",{},smalltalk.HLBrowserBottomWidget)})},
+messageSends: ["selectWidget:", "documentationWidget"]}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "onShowInstanceToggled",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self)._selectWidget_(_st(self)._codeWidget());
+return self}, function($ctx1) {$ctx1.fill(self,"onShowInstanceToggled",{},smalltalk.HLBrowserBottomWidget)})},
+messageSends: ["selectWidget:", "codeWidget"]}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "previous",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self}, function($ctx1) {$ctx1.fill(self,"previous",{},smalltalk.HLBrowserBottomWidget)})},
+messageSends: []}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "previous:",
+fn: function (aWidget){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self}, function($ctx1) {$ctx1.fill(self,"previous:",{aWidget:aWidget},smalltalk.HLBrowserBottomWidget)})},
+messageSends: []}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "renderContentOn:",
+fn: function (html){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(html)._with_(_st(self)._selectedWidget());
+return self}, function($ctx1) {$ctx1.fill(self,"renderContentOn:",{html:html},smalltalk.HLBrowserBottomWidget)})},
+messageSends: ["with:", "selectedWidget"]}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "selectWidget:",
+fn: function (aWidget){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@selectedWidget"]=aWidget;
+_st(self)._refresh();
+return self}, function($ctx1) {$ctx1.fill(self,"selectWidget:",{aWidget:aWidget},smalltalk.HLBrowserBottomWidget)})},
+messageSends: ["refresh"]}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "selectedWidget",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@selectedWidget"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@selectedWidget"]=_st(self)._codeWidget();
+$1=self["@selectedWidget"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"selectedWidget",{},smalltalk.HLBrowserBottomWidget)})},
+messageSends: ["ifNil:", "codeWidget"]}),
+smalltalk.HLBrowserBottomWidget);
+
+
+
 smalltalk.addClass('HLBrowserListWidget', smalltalk.HLNavigationListWidget, ['model'], 'Helios-Browser');
 smalltalk.addMethod(
 smalltalk.method({
@@ -591,6 +793,7 @@ fn: function (){
 var self=this;
 function $HLPackageSelected(){return smalltalk.HLPackageSelected||(typeof HLPackageSelected=="undefined"?nil:HLPackageSelected)}
 function $HLShowInstanceToggled(){return smalltalk.HLShowInstanceToggled||(typeof HLShowInstanceToggled=="undefined"?nil:HLShowInstanceToggled)}
+function $HLShowCommentToggled(){return smalltalk.HLShowCommentToggled||(typeof HLShowCommentToggled=="undefined"?nil:HLShowCommentToggled)}
 function $HLClassSelected(){return smalltalk.HLClassSelected||(typeof HLClassSelected=="undefined"?nil:HLClassSelected)}
 function $HLClassesFocusRequested(){return smalltalk.HLClassesFocusRequested||(typeof HLClassesFocusRequested=="undefined"?nil:HLClassesFocusRequested)}
 return smalltalk.withContext(function($ctx1) { 
@@ -604,6 +807,10 @@ _st($1)._on_do_($HLShowInstanceToggled(),(function(ann){
 return smalltalk.withContext(function($ctx2) {
 return _st(self)._onShowInstanceToggled();
 }, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+_st($1)._on_do_($HLShowCommentToggled(),(function(ann){
+return smalltalk.withContext(function($ctx2) {
+return _st(self)._onShowCommentToggled();
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
 _st($1)._on_do_($HLClassSelected(),(function(ann){
 return smalltalk.withContext(function($ctx2) {
 return _st(self)._onClassSelected_(_st(ann)._item());
@@ -613,7 +820,7 @@ return smalltalk.withContext(function($ctx2) {
 return _st(self)._onClassesFocusRequested();
 }, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"observeModel",{},smalltalk.HLClassesListWidget)})},
-messageSends: ["on:do:", "onPackageSelected:", "item", "announcer", "model", "onShowInstanceToggled", "onClassSelected:", "onClassesFocusRequested"]}),
+messageSends: ["on:do:", "onPackageSelected:", "item", "announcer", "model", "onShowInstanceToggled", "onShowCommentToggled", "onClassSelected:", "onClassesFocusRequested"]}),
 smalltalk.HLClassesListWidget);
 
 smalltalk.addMethod(
@@ -789,6 +996,17 @@ return self}, function($ctx1) {$ctx1.fill(self,"onPackageSelected:",{aPackage:aP
 messageSends: ["selectedItem:", "setItemsForSelectedPackage", "refresh"]}),
 smalltalk.HLClassesListWidget);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "onShowCommentToggled",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self)._refresh();
+return self}, function($ctx1) {$ctx1.fill(self,"onShowCommentToggled",{},smalltalk.HLClassesListWidget)})},
+messageSends: ["refresh"]}),
+smalltalk.HLClassesListWidget);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "onShowInstanceToggled",
@@ -2455,16 +2673,15 @@ selector: "removeClass",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
 _st(self)._withChangesDo_((function(){
 return smalltalk.withContext(function($ctx2) {
-$1=_st(_st(self)._manager())._confirm_(_st("Do you REALLY want to remove class ").__comma(_st(_st(self)._selectedClass())._name()));
-if(smalltalk.assert($1)){
+return _st(_st(self)._manager())._confirm_ifTrue_(_st("Do you REALLY want to remove class ").__comma(_st(_st(self)._selectedClass())._name()),(function(){
+return smalltalk.withContext(function($ctx3) {
 return _st(_st(self)._environment())._removeClass_(_st(self)._selectedClass());
-};
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"removeClass",{},smalltalk.HLBrowserModel)})},
-messageSends: ["withChangesDo:", "ifTrue:", "removeClass:", "selectedClass", "environment", "confirm:", ",", "name", "manager"]}),
+messageSends: ["withChangesDo:", "confirm:ifTrue:", ",", "name", "selectedClass", "removeClass:", "environment", "manager"]}),
 smalltalk.HLBrowserModel);
 
 smalltalk.addMethod(
@@ -2473,16 +2690,15 @@ selector: "removeMethod",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
 _st(self)._withChangesDo_((function(){
 return smalltalk.withContext(function($ctx2) {
-$1=_st(_st(self)._manager())._confirm_(_st(_st(_st("Do you REALLY want to remove method ").__comma(_st(_st(_st(self)._selectedMethod())._methodClass())._name())).__comma(" >> #")).__comma(_st(_st(self)._selectedMethod())._selector()));
-if(smalltalk.assert($1)){
+return _st(_st(self)._manager())._confirm_ifTrue_(_st(_st(_st("Do you REALLY want to remove method ").__comma(_st(_st(_st(self)._selectedMethod())._methodClass())._name())).__comma(" >> #")).__comma(_st(_st(self)._selectedMethod())._selector()),(function(){
+return smalltalk.withContext(function($ctx3) {
 return _st(_st(self)._environment())._removeMethod_(_st(self)._selectedMethod());
-};
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"removeMethod",{},smalltalk.HLBrowserModel)})},
-messageSends: ["withChangesDo:", "ifTrue:", "removeMethod:", "selectedMethod", "environment", "confirm:", ",", "selector", "name", "methodClass", "manager"]}),
+messageSends: ["withChangesDo:", "confirm:ifTrue:", ",", "selector", "selectedMethod", "name", "methodClass", "removeMethod:", "environment", "manager"]}),
 smalltalk.HLBrowserModel);
 
 smalltalk.addMethod(
@@ -2491,16 +2707,15 @@ selector: "removeProtocol",
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
 _st(self)._withChangesDo_((function(){
 return smalltalk.withContext(function($ctx2) {
-$1=_st(_st(self)._manager())._confirm_(_st("Do you REALLY want to remove protocol ").__comma(_st(self)._selectedProtocol()));
-if(smalltalk.assert($1)){
+return _st(_st(self)._manager())._confirm_ifTrue_(_st("Do you REALLY want to remove protocol ").__comma(_st(self)._selectedProtocol()),(function(){
+return smalltalk.withContext(function($ctx3) {
 return _st(_st(self)._environment())._removeProtocol_from_(_st(self)._selectedProtocol(),_st(self)._selectedClass());
-};
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"removeProtocol",{},smalltalk.HLBrowserModel)})},
-messageSends: ["withChangesDo:", "ifTrue:", "removeProtocol:from:", "selectedProtocol", "selectedClass", "environment", "confirm:", ",", "manager"]}),
+messageSends: ["withChangesDo:", "confirm:ifTrue:", ",", "selectedProtocol", "removeProtocol:from:", "selectedClass", "environment", "manager"]}),
 smalltalk.HLBrowserModel);
 
 smalltalk.addMethod(
@@ -2583,12 +2798,13 @@ var self=this;
 function $HLClassSelected(){return smalltalk.HLClassSelected||(typeof HLClassSelected=="undefined"?nil:HLClassSelected)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3,$4,$5;
-$1=aClass;
-if(($receiver = $1) == nil || $receiver == undefined){
+$1=_st(_st(_st(self)._selectedClass()).__eq(aClass))._and_((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(aClass)._isNil();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+if(smalltalk.assert($1)){
 $2=self;
 return $2;
-} else {
-$1;
 };
 _st(self)._withChangesDo_((function(){
 return smalltalk.withContext(function($ctx2) {
@@ -2614,7 +2830,7 @@ _st(self)._selectedProtocol_(nil);
 return _st(_st(self)._announcer())._announce_(_st($HLClassSelected())._on_(_st(self)._selectedClass()));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"selectedClass:",{aClass:aClass},smalltalk.HLBrowserModel)})},
-messageSends: ["ifNil:", "withChangesDo:", "ifTrue:", "selectedProtocol:", "=", "ifNil:ifNotNil:", "ifTrue:ifFalse:", "theNonMetaClass", "theMetaClass", "showInstance", "announce:", "on:", "selectedClass", "announcer"]}),
+messageSends: ["ifTrue:", "and:", "isNil", "=", "selectedClass", "withChangesDo:", "selectedProtocol:", "ifNil:ifNotNil:", "ifTrue:ifFalse:", "theNonMetaClass", "theMetaClass", "showInstance", "announce:", "on:", "announcer"]}),
 smalltalk.HLBrowserModel);
 
 smalltalk.addMethod(
@@ -3153,7 +3369,7 @@ messageSends: ["theClass:", "new", "selectorsCache:", "yourself"]}),
 smalltalk.HLClassCache.klass);
 
 
-smalltalk.addClass('HLDocumentationWidget', smalltalk.HLFocusableWidget, ['documentation'], 'Helios-Browser');
+smalltalk.addClass('HLDocumentationWidget', smalltalk.HLFocusableWidget, ['model'], 'Helios-Browser');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "defaultDocumentation",
@@ -3172,7 +3388,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $2,$1;
-$2=self["@documentation"];
+$2=_st(_st(_st(_st(self)._model())._selectedClass())._theNonMetaClass())._comment();
 if(($receiver = $2) == nil || $receiver == undefined){
 $1=_st(self)._defaultDocumentation();
 } else {
@@ -3180,17 +3396,30 @@ $1=$2;
 };
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"documentation",{},smalltalk.HLDocumentationWidget)})},
-messageSends: ["ifNil:", "defaultDocumentation"]}),
+messageSends: ["ifNil:", "defaultDocumentation", "comment", "theNonMetaClass", "selectedClass", "model"]}),
 smalltalk.HLDocumentationWidget);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "documentation:",
-fn: function (aString){
+selector: "model",
+fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self["@documentation"]=aString;
-return self}, function($ctx1) {$ctx1.fill(self,"documentation:",{aString:aString},smalltalk.HLDocumentationWidget)})},
+var $1;
+$1=self["@model"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"model",{},smalltalk.HLDocumentationWidget)})},
+messageSends: []}),
+smalltalk.HLDocumentationWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "model:",
+fn: function (aModel){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@model"]=aModel;
+return self}, function($ctx1) {$ctx1.fill(self,"model:",{aModel:aModel},smalltalk.HLDocumentationWidget)})},
 messageSends: []}),
 smalltalk.HLDocumentationWidget);
 
@@ -3204,9 +3433,10 @@ return smalltalk.withContext(function($ctx1) {
 var $1,$2;
 $1=_st(html)._div();
 _st($1)._class_("markdown");
-$2=_st($1)._with_(_st($Showdown())._makeHtml_(_st(self)._documentation()));
+$2=_st($1)._asJQuery();
+_st($2)._html_(_st(_st(_st($Showdown())._at_("converter"))._new())._makeHtml_(_st(self)._documentation()));
 return self}, function($ctx1) {$ctx1.fill(self,"renderContentOn:",{html:html},smalltalk.HLDocumentationWidget)})},
-messageSends: ["class:", "div", "with:", "makeHtml:", "documentation"]}),
+messageSends: ["html:", "makeHtml:", "documentation", "new", "at:", "class:", "div", "asJQuery"]}),
 smalltalk.HLDocumentationWidget);
 
 

+ 356 - 46
js/Helios-Browser.js

@@ -240,13 +240,13 @@ selector: "sourceWidget",
 category: 'widgets',
 fn: function (){
 var self=this;
-function $HLBrowserCodeWidget(){return smalltalk.HLBrowserCodeWidget||(typeof HLBrowserCodeWidget=="undefined"?nil:HLBrowserCodeWidget)}
+function $HLBrowserBottomWidget(){return smalltalk.HLBrowserBottomWidget||(typeof HLBrowserBottomWidget=="undefined"?nil:HLBrowserBottomWidget)}
 return smalltalk.withContext(function($ctx1) { 
 var $2,$3,$4,$1;
 $2=self["@sourceWidget"];
 if(($receiver = $2) == nil || $receiver == undefined){
-$3=_st($HLBrowserCodeWidget())._new();
-_st($3)._browserModel_(_st(self)._model());
+$3=_st($HLBrowserBottomWidget())._new();
+_st($3)._model_(_st(self)._model());
 $4=_st($3)._yourself();
 self["@sourceWidget"]=$4;
 $1=self["@sourceWidget"];
@@ -256,9 +256,9 @@ $1=$2;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"sourceWidget",{},smalltalk.HLBrowser)})},
 args: [],
-source: "sourceWidget\x0a\x09^ sourceWidget ifNil: [\x0a      \x09sourceWidget := HLBrowserCodeWidget new\x0a\x09\x09\x09browserModel: self model;\x0a\x09\x09\x09yourself ]",
-messageSends: ["ifNil:", "browserModel:", "model", "new", "yourself"],
-referencedClasses: ["HLBrowserCodeWidget"]
+source: "sourceWidget\x0a\x09^ sourceWidget ifNil: [\x0a      \x09sourceWidget := HLBrowserBottomWidget new\x0a\x09\x09\x09model: self model;\x0a\x09\x09\x09yourself ]",
+messageSends: ["ifNil:", "model:", "model", "new", "yourself"],
+referencedClasses: ["HLBrowserBottomWidget"]
 }),
 smalltalk.HLBrowser);
 
@@ -340,6 +340,278 @@ referencedClasses: []
 smalltalk.HLBrowser.klass);
 
 
+smalltalk.addClass('HLBrowserBottomWidget', smalltalk.HLWidget, ['model', 'codeWidget', 'documentationWidget', 'selectedWidget'], 'Helios-Browser');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "canHaveFocus",
+category: 'testing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return true;
+}, function($ctx1) {$ctx1.fill(self,"canHaveFocus",{},smalltalk.HLBrowserBottomWidget)})},
+args: [],
+source: "canHaveFocus\x0a\x09^ true",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "codeWidget",
+category: 'accessing',
+fn: function (){
+var self=this;
+function $HLBrowserCodeWidget(){return smalltalk.HLBrowserCodeWidget||(typeof HLBrowserCodeWidget=="undefined"?nil:HLBrowserCodeWidget)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$4,$1;
+$2=self["@codeWidget"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$3=_st($HLBrowserCodeWidget())._new();
+_st($3)._browserModel_(_st(self)._model());
+$4=_st($3)._yourself();
+self["@codeWidget"]=$4;
+$1=self["@codeWidget"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"codeWidget",{},smalltalk.HLBrowserBottomWidget)})},
+args: [],
+source: "codeWidget\x0a\x09^ codeWidget ifNil: [ codeWidget := HLBrowserCodeWidget new\x0a\x09\x09browserModel: self model;\x0a\x09\x09yourself ]",
+messageSends: ["ifNil:", "browserModel:", "model", "new", "yourself"],
+referencedClasses: ["HLBrowserCodeWidget"]
+}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "documentationWidget",
+category: 'accessing',
+fn: function (){
+var self=this;
+function $HLDocumentationWidget(){return smalltalk.HLDocumentationWidget||(typeof HLDocumentationWidget=="undefined"?nil:HLDocumentationWidget)}
+return smalltalk.withContext(function($ctx1) { 
+var $2,$3,$4,$1;
+$2=self["@documentationWidget"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$3=_st($HLDocumentationWidget())._new();
+_st($3)._model_(_st(self)._model());
+$4=_st($3)._yourself();
+self["@documentationWidget"]=$4;
+$1=self["@documentationWidget"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"documentationWidget",{},smalltalk.HLBrowserBottomWidget)})},
+args: [],
+source: "documentationWidget\x0a\x09^ documentationWidget ifNil: [ documentationWidget := HLDocumentationWidget new\x0a\x09\x09model: self model;\x0a\x09\x09yourself ]",
+messageSends: ["ifNil:", "model:", "model", "new", "yourself"],
+referencedClasses: ["HLDocumentationWidget"]
+}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "focus",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(_st(self)._selectedWidget())._focus();
+return self}, function($ctx1) {$ctx1.fill(self,"focus",{},smalltalk.HLBrowserBottomWidget)})},
+args: [],
+source: "focus\x0a\x09self selectedWidget focus",
+messageSends: ["focus", "selectedWidget"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "model",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=self["@model"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"model",{},smalltalk.HLBrowserBottomWidget)})},
+args: [],
+source: "model\x0a\x09^ model",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "model:",
+category: 'accessing',
+fn: function (aModel){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@model"]=aModel;
+_st(self)._observeModel();
+return self}, function($ctx1) {$ctx1.fill(self,"model:",{aModel:aModel},smalltalk.HLBrowserBottomWidget)})},
+args: ["aModel"],
+source: "model: aModel\x0a\x09model := aModel.\x0a\x09self observeModel",
+messageSends: ["observeModel"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "observeModel",
+category: 'actions',
+fn: function (){
+var self=this;
+function $HLShowInstanceToggled(){return smalltalk.HLShowInstanceToggled||(typeof HLShowInstanceToggled=="undefined"?nil:HLShowInstanceToggled)}
+function $HLShowCommentToggled(){return smalltalk.HLShowCommentToggled||(typeof HLShowCommentToggled=="undefined"?nil:HLShowCommentToggled)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st(_st(self)._model())._announcer();
+_st($1)._on_do_($HLShowInstanceToggled(),(function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(self)._onShowInstanceToggled();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+$2=_st($1)._on_do_($HLShowCommentToggled(),(function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(self)._onShowCommentToggled();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"observeModel",{},smalltalk.HLBrowserBottomWidget)})},
+args: [],
+source: "observeModel\x0a\x09self model announcer \x0a\x09\x09on: HLShowInstanceToggled\x0a\x09\x09do: [ self onShowInstanceToggled ];\x0a\x09\x09on: HLShowCommentToggled\x0a\x09\x09do: [ self onShowCommentToggled ]",
+messageSends: ["on:do:", "onShowInstanceToggled", "announcer", "model", "onShowCommentToggled"],
+referencedClasses: ["HLShowInstanceToggled", "HLShowCommentToggled"]
+}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "onShowCommentToggled",
+category: 'reactions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self)._selectWidget_(_st(self)._documentationWidget());
+return self}, function($ctx1) {$ctx1.fill(self,"onShowCommentToggled",{},smalltalk.HLBrowserBottomWidget)})},
+args: [],
+source: "onShowCommentToggled\x0a\x09self selectWidget: self documentationWidget",
+messageSends: ["selectWidget:", "documentationWidget"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "onShowInstanceToggled",
+category: 'reactions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self)._selectWidget_(_st(self)._codeWidget());
+return self}, function($ctx1) {$ctx1.fill(self,"onShowInstanceToggled",{},smalltalk.HLBrowserBottomWidget)})},
+args: [],
+source: "onShowInstanceToggled\x0a\x09self selectWidget: self codeWidget",
+messageSends: ["selectWidget:", "codeWidget"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "previous",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self}, function($ctx1) {$ctx1.fill(self,"previous",{},smalltalk.HLBrowserBottomWidget)})},
+args: [],
+source: "previous\x0a\x09\x22For navigation\x22",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "previous:",
+category: 'accessing',
+fn: function (aWidget){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+return self}, function($ctx1) {$ctx1.fill(self,"previous:",{aWidget:aWidget},smalltalk.HLBrowserBottomWidget)})},
+args: ["aWidget"],
+source: "previous: aWidget\x0a\x09\x22For navigation\x22",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "renderContentOn:",
+category: 'rendering',
+fn: function (html){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(html)._with_(_st(self)._selectedWidget());
+return self}, function($ctx1) {$ctx1.fill(self,"renderContentOn:",{html:html},smalltalk.HLBrowserBottomWidget)})},
+args: ["html"],
+source: "renderContentOn: html\x0a\x09html with: self selectedWidget",
+messageSends: ["with:", "selectedWidget"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "selectWidget:",
+category: 'actions',
+fn: function (aWidget){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@selectedWidget"]=aWidget;
+_st(self)._refresh();
+return self}, function($ctx1) {$ctx1.fill(self,"selectWidget:",{aWidget:aWidget},smalltalk.HLBrowserBottomWidget)})},
+args: ["aWidget"],
+source: "selectWidget: aWidget\x0a\x09selectedWidget := aWidget.\x0a\x09self refresh",
+messageSends: ["refresh"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserBottomWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "selectedWidget",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@selectedWidget"];
+if(($receiver = $2) == nil || $receiver == undefined){
+self["@selectedWidget"]=_st(self)._codeWidget();
+$1=self["@selectedWidget"];
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"selectedWidget",{},smalltalk.HLBrowserBottomWidget)})},
+args: [],
+source: "selectedWidget\x0a\x09^ selectedWidget ifNil: [ selectedWidget := self codeWidget ]",
+messageSends: ["ifNil:", "codeWidget"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserBottomWidget);
+
+
+
 smalltalk.addClass('HLBrowserListWidget', smalltalk.HLNavigationListWidget, ['model'], 'Helios-Browser');
 smalltalk.addMethod(
 smalltalk.method({
@@ -772,6 +1044,7 @@ fn: function (){
 var self=this;
 function $HLPackageSelected(){return smalltalk.HLPackageSelected||(typeof HLPackageSelected=="undefined"?nil:HLPackageSelected)}
 function $HLShowInstanceToggled(){return smalltalk.HLShowInstanceToggled||(typeof HLShowInstanceToggled=="undefined"?nil:HLShowInstanceToggled)}
+function $HLShowCommentToggled(){return smalltalk.HLShowCommentToggled||(typeof HLShowCommentToggled=="undefined"?nil:HLShowCommentToggled)}
 function $HLClassSelected(){return smalltalk.HLClassSelected||(typeof HLClassSelected=="undefined"?nil:HLClassSelected)}
 function $HLClassesFocusRequested(){return smalltalk.HLClassesFocusRequested||(typeof HLClassesFocusRequested=="undefined"?nil:HLClassesFocusRequested)}
 return smalltalk.withContext(function($ctx1) { 
@@ -785,6 +1058,10 @@ _st($1)._on_do_($HLShowInstanceToggled(),(function(ann){
 return smalltalk.withContext(function($ctx2) {
 return _st(self)._onShowInstanceToggled();
 }, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+_st($1)._on_do_($HLShowCommentToggled(),(function(ann){
+return smalltalk.withContext(function($ctx2) {
+return _st(self)._onShowCommentToggled();
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
 _st($1)._on_do_($HLClassSelected(),(function(ann){
 return smalltalk.withContext(function($ctx2) {
 return _st(self)._onClassSelected_(_st(ann)._item());
@@ -795,9 +1072,9 @@ return _st(self)._onClassesFocusRequested();
 }, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"observeModel",{},smalltalk.HLClassesListWidget)})},
 args: [],
-source: "observeModel\x0a\x09self model announcer \x0a    \x09on: HLPackageSelected do: [ :ann | self onPackageSelected: ann item ];\x0a    \x09on: HLShowInstanceToggled do: [ :ann | self onShowInstanceToggled ];\x0a\x09\x09on: HLClassSelected do: [ :ann | self onClassSelected: ann item ];\x0a\x09\x09on: HLClassesFocusRequested do: [ :ann | self onClassesFocusRequested ]",
-messageSends: ["on:do:", "onPackageSelected:", "item", "announcer", "model", "onShowInstanceToggled", "onClassSelected:", "onClassesFocusRequested"],
-referencedClasses: ["HLPackageSelected", "HLShowInstanceToggled", "HLClassSelected", "HLClassesFocusRequested"]
+source: "observeModel\x0a\x09self model announcer \x0a    \x09on: HLPackageSelected do: [ :ann | self onPackageSelected: ann item ];\x0a    \x09on: HLShowInstanceToggled do: [ :ann | self onShowInstanceToggled ];\x0a\x09\x09on: HLShowCommentToggled do: [ :ann | self onShowCommentToggled ];\x0a\x09\x09on: HLClassSelected do: [ :ann | self onClassSelected: ann item ];\x0a\x09\x09on: HLClassesFocusRequested do: [ :ann | self onClassesFocusRequested ]",
+messageSends: ["on:do:", "onPackageSelected:", "item", "announcer", "model", "onShowInstanceToggled", "onShowCommentToggled", "onClassSelected:", "onClassesFocusRequested"],
+referencedClasses: ["HLPackageSelected", "HLShowInstanceToggled", "HLShowCommentToggled", "HLClassSelected", "HLClassesFocusRequested"]
 }),
 smalltalk.HLClassesListWidget);
 
@@ -1014,6 +1291,22 @@ referencedClasses: []
 }),
 smalltalk.HLClassesListWidget);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "onShowCommentToggled",
+category: 'reactions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(self)._refresh();
+return self}, function($ctx1) {$ctx1.fill(self,"onShowCommentToggled",{},smalltalk.HLClassesListWidget)})},
+args: [],
+source: "onShowCommentToggled\x0a\x09self refresh",
+messageSends: ["refresh"],
+referencedClasses: []
+}),
+smalltalk.HLClassesListWidget);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "onShowInstanceToggled",
@@ -3156,18 +3449,17 @@ category: 'commands actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
 _st(self)._withChangesDo_((function(){
 return smalltalk.withContext(function($ctx2) {
-$1=_st(_st(self)._manager())._confirm_(_st("Do you REALLY want to remove class ").__comma(_st(_st(self)._selectedClass())._name()));
-if(smalltalk.assert($1)){
+return _st(_st(self)._manager())._confirm_ifTrue_(_st("Do you REALLY want to remove class ").__comma(_st(_st(self)._selectedClass())._name()),(function(){
+return smalltalk.withContext(function($ctx3) {
 return _st(_st(self)._environment())._removeClass_(_st(self)._selectedClass());
-};
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"removeClass",{},smalltalk.HLBrowserModel)})},
 args: [],
-source: "removeClass\x0a\x09self withChangesDo: [\x0a\x09\x09(self manager confirm: 'Do you REALLY want to remove class ', self selectedClass name)\x0a\x09\x09\x09ifTrue: [ self environment removeClass: self selectedClass ] ]",
-messageSends: ["withChangesDo:", "ifTrue:", "removeClass:", "selectedClass", "environment", "confirm:", ",", "name", "manager"],
+source: "removeClass\x0a\x09self withChangesDo: [\x0a\x09\x09self manager \x0a\x09\x09\x09confirm: 'Do you REALLY want to remove class ', self selectedClass name\x0a\x09\x09\x09ifTrue: [ self environment removeClass: self selectedClass ] ]",
+messageSends: ["withChangesDo:", "confirm:ifTrue:", ",", "name", "selectedClass", "removeClass:", "environment", "manager"],
 referencedClasses: []
 }),
 smalltalk.HLBrowserModel);
@@ -3179,18 +3471,17 @@ category: 'commands actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
 _st(self)._withChangesDo_((function(){
 return smalltalk.withContext(function($ctx2) {
-$1=_st(_st(self)._manager())._confirm_(_st(_st(_st("Do you REALLY want to remove method ").__comma(_st(_st(_st(self)._selectedMethod())._methodClass())._name())).__comma(" >> #")).__comma(_st(_st(self)._selectedMethod())._selector()));
-if(smalltalk.assert($1)){
+return _st(_st(self)._manager())._confirm_ifTrue_(_st(_st(_st("Do you REALLY want to remove method ").__comma(_st(_st(_st(self)._selectedMethod())._methodClass())._name())).__comma(" >> #")).__comma(_st(_st(self)._selectedMethod())._selector()),(function(){
+return smalltalk.withContext(function($ctx3) {
 return _st(_st(self)._environment())._removeMethod_(_st(self)._selectedMethod());
-};
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"removeMethod",{},smalltalk.HLBrowserModel)})},
 args: [],
-source: "removeMethod\x0a\x09self withChangesDo: [\x0a\x09\x09(self manager confirm: 'Do you REALLY want to remove method ', self selectedMethod methodClass name,' >> #', self selectedMethod selector)\x0a\x09\x09\x09ifTrue: [ self environment removeMethod: self selectedMethod ] ]",
-messageSends: ["withChangesDo:", "ifTrue:", "removeMethod:", "selectedMethod", "environment", "confirm:", ",", "selector", "name", "methodClass", "manager"],
+source: "removeMethod\x0a\x09self withChangesDo: [\x0a\x09\x09self manager \x0a\x09\x09\x09confirm: 'Do you REALLY want to remove method ', self selectedMethod methodClass name,' >> #', self selectedMethod selector\x0a\x09\x09\x09ifTrue: [ self environment removeMethod: self selectedMethod ] ]",
+messageSends: ["withChangesDo:", "confirm:ifTrue:", ",", "selector", "selectedMethod", "name", "methodClass", "removeMethod:", "environment", "manager"],
 referencedClasses: []
 }),
 smalltalk.HLBrowserModel);
@@ -3202,18 +3493,17 @@ category: 'commands actions',
 fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
 _st(self)._withChangesDo_((function(){
 return smalltalk.withContext(function($ctx2) {
-$1=_st(_st(self)._manager())._confirm_(_st("Do you REALLY want to remove protocol ").__comma(_st(self)._selectedProtocol()));
-if(smalltalk.assert($1)){
+return _st(_st(self)._manager())._confirm_ifTrue_(_st("Do you REALLY want to remove protocol ").__comma(_st(self)._selectedProtocol()),(function(){
+return smalltalk.withContext(function($ctx3) {
 return _st(_st(self)._environment())._removeProtocol_from_(_st(self)._selectedProtocol(),_st(self)._selectedClass());
-};
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"removeProtocol",{},smalltalk.HLBrowserModel)})},
 args: [],
-source: "removeProtocol\x0a\x09self withChangesDo: [\x0a\x09\x09(self manager confirm: 'Do you REALLY want to remove protocol ', self selectedProtocol)\x0a\x09\x09\x09ifTrue: [ self environment \x0a\x09\x09\x09\x09removeProtocol: self selectedProtocol \x0a\x09\x09\x09\x09from: self selectedClass ] ]",
-messageSends: ["withChangesDo:", "ifTrue:", "removeProtocol:from:", "selectedProtocol", "selectedClass", "environment", "confirm:", ",", "manager"],
+source: "removeProtocol\x0a\x09self withChangesDo: [\x0a\x09\x09self manager \x0a\x09\x09\x09confirm: 'Do you REALLY want to remove protocol ', self selectedProtocol\x0a\x09\x09\x09ifTrue: [ self environment \x0a\x09\x09\x09\x09removeProtocol: self selectedProtocol \x0a\x09\x09\x09\x09from: self selectedClass ] ]",
+messageSends: ["withChangesDo:", "confirm:ifTrue:", ",", "selectedProtocol", "removeProtocol:from:", "selectedClass", "environment", "manager"],
 referencedClasses: []
 }),
 smalltalk.HLBrowserModel);
@@ -3324,12 +3614,13 @@ var self=this;
 function $HLClassSelected(){return smalltalk.HLClassSelected||(typeof HLClassSelected=="undefined"?nil:HLClassSelected)}
 return smalltalk.withContext(function($ctx1) { 
 var $1,$2,$3,$4,$5;
-$1=aClass;
-if(($receiver = $1) == nil || $receiver == undefined){
+$1=_st(_st(_st(self)._selectedClass()).__eq(aClass))._and_((function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(aClass)._isNil();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+if(smalltalk.assert($1)){
 $2=self;
 return $2;
-} else {
-$1;
 };
 _st(self)._withChangesDo_((function(){
 return smalltalk.withContext(function($ctx2) {
@@ -3356,8 +3647,8 @@ return _st(_st(self)._announcer())._announce_(_st($HLClassSelected())._on_(_st(s
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"selectedClass:",{aClass:aClass},smalltalk.HLBrowserModel)})},
 args: ["aClass"],
-source: "selectedClass: aClass\x0a\x09aClass ifNil: [ ^ self ].\x0a\x09\x0a\x09self withChangesDo: [\x0a\x09\x09selectedClass = aClass ifTrue: [ \x0a\x09\x09\x09self selectedProtocol: nil ].\x0a    \x0a\x09\x09aClass \x0a   \x09\x09\x09ifNil: [ selectedClass := nil ]\x0a    \x09\x09ifNotNil: [\x0a\x09\x09\x09\x09self showInstance \x0a   \x09\x09\x09\x09\x09ifTrue: [ selectedClass := aClass theNonMetaClass ]\x0a     \x09\x09\x09\x09ifFalse: [ selectedClass := aClass theMetaClass ] ].\x0a\x09\x09self selectedProtocol: nil.\x0a\x09\x09self announcer announce: (HLClassSelected on: self selectedClass) ]",
-messageSends: ["ifNil:", "withChangesDo:", "ifTrue:", "selectedProtocol:", "=", "ifNil:ifNotNil:", "ifTrue:ifFalse:", "theNonMetaClass", "theMetaClass", "showInstance", "announce:", "on:", "selectedClass", "announcer"],
+source: "selectedClass: aClass\x0a\x09(self selectedClass = aClass and: [ aClass isNil ]) \x0a\x09\x09ifTrue: [ ^ self ].\x0a\x09\x0a\x09self withChangesDo: [\x0a\x09\x09selectedClass = aClass ifTrue: [ \x0a\x09\x09\x09self selectedProtocol: nil ].\x0a    \x0a\x09\x09aClass \x0a   \x09\x09\x09ifNil: [ selectedClass := nil ]\x0a    \x09\x09ifNotNil: [\x0a\x09\x09\x09\x09self showInstance \x0a   \x09\x09\x09\x09\x09ifTrue: [ selectedClass := aClass theNonMetaClass ]\x0a     \x09\x09\x09\x09ifFalse: [ selectedClass := aClass theMetaClass ] ].\x0a\x09\x09self selectedProtocol: nil.\x0a\x09\x09self announcer announce: (HLClassSelected on: self selectedClass) ]",
+messageSends: ["ifTrue:", "and:", "isNil", "=", "selectedClass", "withChangesDo:", "selectedProtocol:", "ifNil:ifNotNil:", "ifTrue:ifFalse:", "theNonMetaClass", "theMetaClass", "showInstance", "announce:", "on:", "announcer"],
 referencedClasses: ["HLClassSelected"]
 }),
 smalltalk.HLBrowserModel);
@@ -4043,7 +4334,7 @@ referencedClasses: []
 smalltalk.HLClassCache.klass);
 
 
-smalltalk.addClass('HLDocumentationWidget', smalltalk.HLFocusableWidget, ['documentation'], 'Helios-Browser');
+smalltalk.addClass('HLDocumentationWidget', smalltalk.HLFocusableWidget, ['model'], 'Helios-Browser');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "defaultDocumentation",
@@ -4068,7 +4359,7 @@ fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
 var $2,$1;
-$2=self["@documentation"];
+$2=_st(_st(_st(_st(self)._model())._selectedClass())._theNonMetaClass())._comment();
 if(($receiver = $2) == nil || $receiver == undefined){
 $1=_st(self)._defaultDocumentation();
 } else {
@@ -4077,23 +4368,41 @@ $1=$2;
 return $1;
 }, function($ctx1) {$ctx1.fill(self,"documentation",{},smalltalk.HLDocumentationWidget)})},
 args: [],
-source: "documentation\x0a\x09^ documentation ifNil: [ self defaultDocumentation ]",
-messageSends: ["ifNil:", "defaultDocumentation"],
+source: "documentation\x0a\x09^ self model selectedClass theNonMetaClass comment ifNil: [ self defaultDocumentation ]",
+messageSends: ["ifNil:", "defaultDocumentation", "comment", "theNonMetaClass", "selectedClass", "model"],
 referencedClasses: []
 }),
 smalltalk.HLDocumentationWidget);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "documentation:",
+selector: "model",
 category: 'accessing',
-fn: function (aString){
+fn: function (){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-self["@documentation"]=aString;
-return self}, function($ctx1) {$ctx1.fill(self,"documentation:",{aString:aString},smalltalk.HLDocumentationWidget)})},
-args: ["aString"],
-source: "documentation: aString\x0a\x09documentation := aString",
+var $1;
+$1=self["@model"];
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"model",{},smalltalk.HLDocumentationWidget)})},
+args: [],
+source: "model\x0a\x09^ model",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLDocumentationWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "model:",
+category: 'accessing',
+fn: function (aModel){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@model"]=aModel;
+return self}, function($ctx1) {$ctx1.fill(self,"model:",{aModel:aModel},smalltalk.HLDocumentationWidget)})},
+args: ["aModel"],
+source: "model: aModel\x0a\x09model := aModel",
 messageSends: [],
 referencedClasses: []
 }),
@@ -4110,11 +4419,12 @@ return smalltalk.withContext(function($ctx1) {
 var $1,$2;
 $1=_st(html)._div();
 _st($1)._class_("markdown");
-$2=_st($1)._with_(_st($Showdown())._makeHtml_(_st(self)._documentation()));
+$2=_st($1)._asJQuery();
+_st($2)._html_(_st(_st(_st($Showdown())._at_("converter"))._new())._makeHtml_(_st(self)._documentation()));
 return self}, function($ctx1) {$ctx1.fill(self,"renderContentOn:",{html:html},smalltalk.HLDocumentationWidget)})},
 args: ["html"],
-source: "renderContentOn: html\x0a\x09html div \x0a\x09\x09class: 'markdown';\x0a\x09\x09with: (Showdown makeHtml: self documentation)",
-messageSends: ["class:", "div", "with:", "makeHtml:", "documentation"],
+source: "renderContentOn: html\x0a\x09(html div \x0a\x09\x09class: 'markdown';\x0a\x09\x09asJQuery) html: ((Showdown at: 'converter') new makeHtml: self documentation)",
+messageSends: ["html:", "makeHtml:", "documentation", "new", "at:", "class:", "div", "asJQuery"],
 referencedClasses: ["Showdown"]
 }),
 smalltalk.HLDocumentationWidget);

+ 236 - 7
js/Helios-Core.deploy.js

@@ -357,15 +357,13 @@ smalltalk.HLWidget);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "confirm:",
-fn: function (aString){
+selector: "confirm:ifTrue:",
+fn: function (aString,aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st(window)._confirm_(aString);
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"confirm:",{aString:aString},smalltalk.HLWidget)})},
-messageSends: ["confirm:"]}),
+_st(_st(self)._manager())._confirm_ifTrue_(aString,aBlock);
+return self}, function($ctx1) {$ctx1.fill(self,"confirm:ifTrue:",{aString:aString,aBlock:aBlock},smalltalk.HLWidget)})},
+messageSends: ["confirm:ifTrue:", "manager"]}),
 smalltalk.HLWidget);
 
 smalltalk.addMethod(
@@ -535,6 +533,203 @@ messageSends: []}),
 smalltalk.HLWidget.klass);
 
 
+smalltalk.addClass('HLConfirmation', smalltalk.HLWidget, ['confirmationString', 'actionBlock', 'cancelBlock'], 'Helios-Core');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "actionBlock",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@actionBlock"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=(function(){
+return smalltalk.withContext(function($ctx2) {
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"actionBlock",{},smalltalk.HLConfirmation)})},
+messageSends: ["ifNil:"]}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "actionBlock:",
+fn: function (aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@actionBlock"]=aBlock;
+return self}, function($ctx1) {$ctx1.fill(self,"actionBlock:",{aBlock:aBlock},smalltalk.HLConfirmation)})},
+messageSends: []}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "cancel",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(_st(self)._cancelBlock())._value();
+_st(self)._remove();
+return self}, function($ctx1) {$ctx1.fill(self,"cancel",{},smalltalk.HLConfirmation)})},
+messageSends: ["value", "cancelBlock", "remove"]}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "cancelBlock",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@cancelBlock"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=(function(){
+return smalltalk.withContext(function($ctx2) {
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"cancelBlock",{},smalltalk.HLConfirmation)})},
+messageSends: ["ifNil:"]}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "cancelBlock:",
+fn: function (aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@cancelBlock"]=aBlock;
+return self}, function($ctx1) {$ctx1.fill(self,"cancelBlock:",{aBlock:aBlock},smalltalk.HLConfirmation)})},
+messageSends: []}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "confirm",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(_st(self)._actionBlock())._value();
+_st(self)._remove();
+return self}, function($ctx1) {$ctx1.fill(self,"confirm",{},smalltalk.HLConfirmation)})},
+messageSends: ["value", "actionBlock", "remove"]}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "confirmationString",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@confirmationString"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$1="Confirm";
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"confirmationString",{},smalltalk.HLConfirmation)})},
+messageSends: ["ifNil:"]}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "confirmationString:",
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@confirmationString"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"confirmationString:",{aString:aString},smalltalk.HLConfirmation)})},
+messageSends: []}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "remove",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(_st(window)._jQuery_(".confirmation"))._removeClass_("active");
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
+_st(_st(window)._jQuery_("#overlay"))._remove();
+return _st(_st(window)._jQuery_(".confirmation"))._remove();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._valueWithTimeout_((300));
+return self}, function($ctx1) {$ctx1.fill(self,"remove",{},smalltalk.HLConfirmation)})},
+messageSends: ["removeClass:", "jQuery:", "valueWithTimeout:", "remove"]}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "renderContentOn:",
+fn: function (html){
+var self=this;
+var confirmButton;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$3,$5,$6,$7,$8,$4,$2;
+_st(_st(html)._div())._id_("overlay");
+$1=_st(html)._div();
+_st($1)._class_("confirmation");
+$2=_st($1)._with_((function(){
+return smalltalk.withContext(function($ctx2) {
+_st(_st(html)._span())._with_(_st(self)._confirmationString());
+$3=_st(html)._div();
+_st($3)._class_("buttons");
+$4=_st($3)._with_((function(){
+return smalltalk.withContext(function($ctx3) {
+$5=_st(html)._button();
+_st($5)._class_("button");
+_st($5)._with_("Cancel");
+$6=_st($5)._onClick_((function(){
+return smalltalk.withContext(function($ctx4) {
+return _st(self)._cancel();
+}, function($ctx4) {$ctx4.fillBlock({},$ctx1)})}));
+$6;
+$7=_st(html)._button();
+_st($7)._class_("button default");
+_st($7)._with_("Confirm");
+$8=_st($7)._onClick_((function(){
+return smalltalk.withContext(function($ctx4) {
+return _st(self)._confirm();
+}, function($ctx4) {$ctx4.fillBlock({},$ctx1)})}));
+confirmButton=$8;
+return confirmButton;
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+return $4;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st(_st(confirmButton)._asJQuery())._focus();
+_st(_st(window)._jQuery_(".confirmation"))._addClass_("active");
+_st(self)._setupKeyBindings();
+return self}, function($ctx1) {$ctx1.fill(self,"renderContentOn:",{html:html,confirmButton:confirmButton},smalltalk.HLConfirmation)})},
+messageSends: ["id:", "div", "class:", "with:", "confirmationString", "span", "button", "onClick:", "cancel", "confirm", "focus", "asJQuery", "addClass:", "jQuery:", "setupKeyBindings"]}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "setupKeyBindings",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+_st(_st(window)._jQuery_(".confirmation"))._keyup_((function(e){
+return smalltalk.withContext(function($ctx2) {
+$1=_st(_st(e)._keyCode()).__eq((27));
+if(smalltalk.assert($1)){
+return _st(self)._cancel();
+};
+}, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"setupKeyBindings",{},smalltalk.HLConfirmation)})},
+messageSends: ["keyup:", "ifTrue:", "cancel", "=", "keyCode", "jQuery:"]}),
+smalltalk.HLConfirmation);
+
+
+
 smalltalk.addClass('HLDebugger', smalltalk.HLWidget, [], 'Helios-Core');
 
 
@@ -1276,6 +1471,40 @@ return self}, function($ctx1) {$ctx1.fill(self,"addToHistory:",{aTab:aTab},small
 messageSends: ["removeFromHistory:", "add:", "history"]}),
 smalltalk.HLManager);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "confirm:ifFalse:",
+fn: function (aString,aBlock){
+var self=this;
+function $HLConfirmation(){return smalltalk.HLConfirmation||(typeof HLConfirmation=="undefined"?nil:HLConfirmation)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st($HLConfirmation())._new();
+_st($1)._confirmationString_(aString);
+_st($1)._cancelBlock_(aBlock);
+$2=_st($1)._yourself();
+_st($2)._appendToJQuery_(_st("body")._asJQuery());
+return self}, function($ctx1) {$ctx1.fill(self,"confirm:ifFalse:",{aString:aString,aBlock:aBlock},smalltalk.HLManager)})},
+messageSends: ["appendToJQuery:", "asJQuery", "confirmationString:", "new", "cancelBlock:", "yourself"]}),
+smalltalk.HLManager);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "confirm:ifTrue:",
+fn: function (aString,aBlock){
+var self=this;
+function $HLConfirmation(){return smalltalk.HLConfirmation||(typeof HLConfirmation=="undefined"?nil:HLConfirmation)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st($HLConfirmation())._new();
+_st($1)._confirmationString_(aString);
+_st($1)._actionBlock_(aBlock);
+$2=_st($1)._yourself();
+_st($2)._appendToJQuery_(_st("body")._asJQuery());
+return self}, function($ctx1) {$ctx1.fill(self,"confirm:ifTrue:",{aString:aString,aBlock:aBlock},smalltalk.HLManager)})},
+messageSends: ["appendToJQuery:", "asJQuery", "confirmationString:", "new", "actionBlock:", "yourself"]}),
+smalltalk.HLManager);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "defaultEnvironment",

+ 303 - 9
js/Helios-Core.js

@@ -477,18 +477,16 @@ smalltalk.HLWidget);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "confirm:",
+selector: "confirm:ifTrue:",
 category: 'actions',
-fn: function (aString){
+fn: function (aString,aBlock){
 var self=this;
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st(window)._confirm_(aString);
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"confirm:",{aString:aString},smalltalk.HLWidget)})},
-args: ["aString"],
-source: "confirm: aString\x0a\x09^ window confirm: aString",
-messageSends: ["confirm:"],
+_st(_st(self)._manager())._confirm_ifTrue_(aString,aBlock);
+return self}, function($ctx1) {$ctx1.fill(self,"confirm:ifTrue:",{aString:aString,aBlock:aBlock},smalltalk.HLWidget)})},
+args: ["aString", "aBlock"],
+source: "confirm: aString ifTrue: aBlock\x0a\x09self manager confirm: aString ifTrue: aBlock",
+messageSends: ["confirm:ifTrue:", "manager"],
 referencedClasses: []
 }),
 smalltalk.HLWidget);
@@ -720,6 +718,258 @@ referencedClasses: []
 smalltalk.HLWidget.klass);
 
 
+smalltalk.addClass('HLConfirmation', smalltalk.HLWidget, ['confirmationString', 'actionBlock', 'cancelBlock'], 'Helios-Core');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "actionBlock",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@actionBlock"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=(function(){
+return smalltalk.withContext(function($ctx2) {
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"actionBlock",{},smalltalk.HLConfirmation)})},
+args: [],
+source: "actionBlock\x0a\x09^ actionBlock ifNil: [ [] ]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "actionBlock:",
+category: 'accessing',
+fn: function (aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@actionBlock"]=aBlock;
+return self}, function($ctx1) {$ctx1.fill(self,"actionBlock:",{aBlock:aBlock},smalltalk.HLConfirmation)})},
+args: ["aBlock"],
+source: "actionBlock: aBlock\x0a\x09actionBlock := aBlock",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "cancel",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(_st(self)._cancelBlock())._value();
+_st(self)._remove();
+return self}, function($ctx1) {$ctx1.fill(self,"cancel",{},smalltalk.HLConfirmation)})},
+args: [],
+source: "cancel\x0a\x09self cancelBlock value.\x0a\x09self remove",
+messageSends: ["value", "cancelBlock", "remove"],
+referencedClasses: []
+}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "cancelBlock",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@cancelBlock"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$1=(function(){
+return smalltalk.withContext(function($ctx2) {
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})});
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"cancelBlock",{},smalltalk.HLConfirmation)})},
+args: [],
+source: "cancelBlock\x0a\x09^ cancelBlock ifNil: [ [] ]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "cancelBlock:",
+category: 'accessing',
+fn: function (aBlock){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@cancelBlock"]=aBlock;
+return self}, function($ctx1) {$ctx1.fill(self,"cancelBlock:",{aBlock:aBlock},smalltalk.HLConfirmation)})},
+args: ["aBlock"],
+source: "cancelBlock: aBlock\x0a\x09cancelBlock := aBlock",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "confirm",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(_st(self)._actionBlock())._value();
+_st(self)._remove();
+return self}, function($ctx1) {$ctx1.fill(self,"confirm",{},smalltalk.HLConfirmation)})},
+args: [],
+source: "confirm\x0a\x09self actionBlock value.\x0a\x09self remove",
+messageSends: ["value", "actionBlock", "remove"],
+referencedClasses: []
+}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "confirmationString",
+category: 'accessing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $2,$1;
+$2=self["@confirmationString"];
+if(($receiver = $2) == nil || $receiver == undefined){
+$1="Confirm";
+} else {
+$1=$2;
+};
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"confirmationString",{},smalltalk.HLConfirmation)})},
+args: [],
+source: "confirmationString\x0a\x09^ confirmationString ifNil: [ 'Confirm' ]",
+messageSends: ["ifNil:"],
+referencedClasses: []
+}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "confirmationString:",
+category: 'accessing',
+fn: function (aString){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self["@confirmationString"]=aString;
+return self}, function($ctx1) {$ctx1.fill(self,"confirmationString:",{aString:aString},smalltalk.HLConfirmation)})},
+args: ["aString"],
+source: "confirmationString: aString\x0a\x09confirmationString := aString",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "remove",
+category: 'actions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+_st(_st(window)._jQuery_(".confirmation"))._removeClass_("active");
+_st((function(){
+return smalltalk.withContext(function($ctx2) {
+_st(_st(window)._jQuery_("#overlay"))._remove();
+return _st(_st(window)._jQuery_(".confirmation"))._remove();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}))._valueWithTimeout_((300));
+return self}, function($ctx1) {$ctx1.fill(self,"remove",{},smalltalk.HLConfirmation)})},
+args: [],
+source: "remove\x0a\x09(window jQuery: '.confirmation') removeClass: 'active'.\x0a\x09[ \x0a\x09\x09(window jQuery: '#overlay') remove.\x0a\x09\x09(window jQuery: '.confirmation') remove\x0a\x09] valueWithTimeout: 300",
+messageSends: ["removeClass:", "jQuery:", "valueWithTimeout:", "remove"],
+referencedClasses: []
+}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "renderContentOn:",
+category: 'rendering',
+fn: function (html){
+var self=this;
+var confirmButton;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$3,$5,$6,$7,$8,$4,$2;
+_st(_st(html)._div())._id_("overlay");
+$1=_st(html)._div();
+_st($1)._class_("confirmation");
+$2=_st($1)._with_((function(){
+return smalltalk.withContext(function($ctx2) {
+_st(_st(html)._span())._with_(_st(self)._confirmationString());
+$3=_st(html)._div();
+_st($3)._class_("buttons");
+$4=_st($3)._with_((function(){
+return smalltalk.withContext(function($ctx3) {
+$5=_st(html)._button();
+_st($5)._class_("button");
+_st($5)._with_("Cancel");
+$6=_st($5)._onClick_((function(){
+return smalltalk.withContext(function($ctx4) {
+return _st(self)._cancel();
+}, function($ctx4) {$ctx4.fillBlock({},$ctx1)})}));
+$6;
+$7=_st(html)._button();
+_st($7)._class_("button default");
+_st($7)._with_("Confirm");
+$8=_st($7)._onClick_((function(){
+return smalltalk.withContext(function($ctx4) {
+return _st(self)._confirm();
+}, function($ctx4) {$ctx4.fillBlock({},$ctx1)})}));
+confirmButton=$8;
+return confirmButton;
+}, function($ctx3) {$ctx3.fillBlock({},$ctx1)})}));
+return $4;
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+_st(_st(confirmButton)._asJQuery())._focus();
+_st(_st(window)._jQuery_(".confirmation"))._addClass_("active");
+_st(self)._setupKeyBindings();
+return self}, function($ctx1) {$ctx1.fill(self,"renderContentOn:",{html:html,confirmButton:confirmButton},smalltalk.HLConfirmation)})},
+args: ["html"],
+source: "renderContentOn: html\x0a\x09| confirmButton |\x0a\x09\x0a\x09html div id: 'overlay'.\x0a\x09html div \x0a\x09\x09class: 'confirmation';\x0a\x09\x09with: [\x0a\x09\x09\x09html span with: self confirmationString.\x0a\x09\x09\x09html div \x0a\x09\x09\x09\x09class: 'buttons';\x0a\x09\x09\x09\x09with: [\x0a\x09\x09\x09\x09\x09html button\x0a\x09\x09\x09\x09\x09\x09class: 'button';\x0a\x09\x09\x09\x09\x09\x09with: 'Cancel';\x0a\x09\x09\x09\x09\x09\x09onClick: [ self cancel ].\x0a\x09\x09\x09\x09\x09confirmButton := html button\x0a\x09\x09\x09\x09\x09\x09class: 'button default';\x0a\x09\x09\x09\x09\x09\x09with: 'Confirm';\x0a\x09\x09\x09\x09\x09\x09onClick: [ self confirm ] ] ].\x0a\x0a\x09confirmButton asJQuery focus.\x0a\x09(window jQuery: '.confirmation') addClass: 'active'.\x0a\x09self setupKeyBindings",
+messageSends: ["id:", "div", "class:", "with:", "confirmationString", "span", "button", "onClick:", "cancel", "confirm", "focus", "asJQuery", "addClass:", "jQuery:", "setupKeyBindings"],
+referencedClasses: []
+}),
+smalltalk.HLConfirmation);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "setupKeyBindings",
+category: 'rendering',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+_st(_st(window)._jQuery_(".confirmation"))._keyup_((function(e){
+return smalltalk.withContext(function($ctx2) {
+$1=_st(_st(e)._keyCode()).__eq((27));
+if(smalltalk.assert($1)){
+return _st(self)._cancel();
+};
+}, function($ctx2) {$ctx2.fillBlock({e:e},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"setupKeyBindings",{},smalltalk.HLConfirmation)})},
+args: [],
+source: "setupKeyBindings\x0a\x09(window jQuery: '.confirmation') keyup: [ :e |\x0a\x09\x09e keyCode = 27 ifTrue: [ self cancel ] ]",
+messageSends: ["keyup:", "ifTrue:", "cancel", "=", "keyCode", "jQuery:"],
+referencedClasses: []
+}),
+smalltalk.HLConfirmation);
+
+
+
 smalltalk.addClass('HLDebugger', smalltalk.HLWidget, [], 'Helios-Core');
 
 
@@ -1676,6 +1926,50 @@ referencedClasses: []
 }),
 smalltalk.HLManager);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "confirm:ifFalse:",
+category: 'actions',
+fn: function (aString,aBlock){
+var self=this;
+function $HLConfirmation(){return smalltalk.HLConfirmation||(typeof HLConfirmation=="undefined"?nil:HLConfirmation)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st($HLConfirmation())._new();
+_st($1)._confirmationString_(aString);
+_st($1)._cancelBlock_(aBlock);
+$2=_st($1)._yourself();
+_st($2)._appendToJQuery_(_st("body")._asJQuery());
+return self}, function($ctx1) {$ctx1.fill(self,"confirm:ifFalse:",{aString:aString,aBlock:aBlock},smalltalk.HLManager)})},
+args: ["aString", "aBlock"],
+source: "confirm: aString ifFalse: aBlock\x0a\x09(HLConfirmation new\x0a\x09\x09confirmationString: aString;\x0a\x09\x09cancelBlock: aBlock;\x0a\x09\x09yourself)\x0a\x09\x09\x09appendToJQuery: 'body' asJQuery",
+messageSends: ["appendToJQuery:", "asJQuery", "confirmationString:", "new", "cancelBlock:", "yourself"],
+referencedClasses: ["HLConfirmation"]
+}),
+smalltalk.HLManager);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "confirm:ifTrue:",
+category: 'actions',
+fn: function (aString,aBlock){
+var self=this;
+function $HLConfirmation(){return smalltalk.HLConfirmation||(typeof HLConfirmation=="undefined"?nil:HLConfirmation)}
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st($HLConfirmation())._new();
+_st($1)._confirmationString_(aString);
+_st($1)._actionBlock_(aBlock);
+$2=_st($1)._yourself();
+_st($2)._appendToJQuery_(_st("body")._asJQuery());
+return self}, function($ctx1) {$ctx1.fill(self,"confirm:ifTrue:",{aString:aString,aBlock:aBlock},smalltalk.HLManager)})},
+args: ["aString", "aBlock"],
+source: "confirm: aString ifTrue: aBlock\x0a\x09(HLConfirmation new\x0a\x09\x09confirmationString: aString;\x0a\x09\x09actionBlock: aBlock;\x0a\x09\x09yourself)\x0a\x09\x09\x09appendToJQuery: 'body' asJQuery",
+messageSends: ["appendToJQuery:", "asJQuery", "confirmationString:", "new", "actionBlock:", "yourself"],
+referencedClasses: ["HLConfirmation"]
+}),
+smalltalk.HLManager);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "defaultEnvironment",

+ 39 - 19
js/Helios-Workspace.deploy.js

@@ -977,6 +977,7 @@ selector: "observeBrowserModel",
 fn: function (){
 var self=this;
 function $HLSaveSourceCode(){return smalltalk.HLSaveSourceCode||(typeof HLSaveSourceCode=="undefined"?nil:HLSaveSourceCode)}
+function $HLShowInstanceToggled(){return smalltalk.HLShowInstanceToggled||(typeof HLShowInstanceToggled=="undefined"?nil:HLShowInstanceToggled)}
 function $HLSourceCodeSaved(){return smalltalk.HLSourceCodeSaved||(typeof HLSourceCodeSaved=="undefined"?nil:HLSourceCodeSaved)}
 function $HLAboutToChange(){return smalltalk.HLAboutToChange||(typeof HLAboutToChange=="undefined"?nil:HLAboutToChange)}
 function $HLParseErrorRaised(){return smalltalk.HLParseErrorRaised||(typeof HLParseErrorRaised=="undefined"?nil:HLParseErrorRaised)}
@@ -994,6 +995,10 @@ _st($1)._on_do_($HLSaveSourceCode(),(function(ann){
 return smalltalk.withContext(function($ctx2) {
 return _st(self)._onSaveIt();
 }, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+_st($1)._on_do_($HLShowInstanceToggled(),(function(ann){
+return smalltalk.withContext(function($ctx2) {
+return _st(self)._onShowInstanceToggled();
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
 _st($1)._on_do_($HLSourceCodeSaved(),(function(ann){
 return smalltalk.withContext(function($ctx2) {
 return _st(self)._onSourceCodeSaved();
@@ -1035,7 +1040,7 @@ return smalltalk.withContext(function($ctx2) {
 return _st(self)._onSourceCodeFocusRequested();
 }, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"observeBrowserModel",{},smalltalk.HLBrowserCodeWidget)})},
-messageSends: ["on:do:", "onSaveIt", "announcer", "browserModel", "onSourceCodeSaved", "onBrowserAboutToChange", "onParseError:", "onCompileError:", "error", "onUnknownVariableError:", "onInstVarAdded", "onMethodSelected:", "item", "onClassSelected:", "onProtocolSelected:", "onSourceCodeFocusRequested"]}),
+messageSends: ["on:do:", "onSaveIt", "announcer", "browserModel", "onShowInstanceToggled", "onSourceCodeSaved", "onBrowserAboutToChange", "onParseError:", "onCompileError:", "error", "onUnknownVariableError:", "onInstVarAdded", "onMethodSelected:", "item", "onClassSelected:", "onProtocolSelected:", "onSourceCodeFocusRequested"]}),
 smalltalk.HLBrowserCodeWidget);
 
 smalltalk.addMethod(
@@ -1082,17 +1087,17 @@ fn: function (){
 var self=this;
 function $HLChangeForbidden(){return smalltalk.HLChangeForbidden||(typeof HLChangeForbidden=="undefined"?nil:HLChangeForbidden)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
+var $1;
 $1=_st(self)._hasModification();
 if(smalltalk.assert($1)){
-$2=_st(window)._confirm_("Do you want to cancel changes?");
-if(! smalltalk.assert($2)){
-_st($HLChangeForbidden())._signal();
-};
+_st(self)._confirm_ifFalse_("Do you want to cancel changes?",(function(){
+return smalltalk.withContext(function($ctx2) {
+return _st($HLChangeForbidden())._signal();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 _st(self)._methodContents_(_st(self)._contents());
 };
 return self}, function($ctx1) {$ctx1.fill(self,"onBrowserAboutToChange",{},smalltalk.HLBrowserCodeWidget)})},
-messageSends: ["ifTrue:", "ifFalse:", "signal", "confirm:", "methodContents:", "contents", "hasModification"]}),
+messageSends: ["ifTrue:", "confirm:ifFalse:", "signal", "methodContents:", "contents", "hasModification"]}),
 smalltalk.HLBrowserCodeWidget);
 
 smalltalk.addMethod(
@@ -1249,6 +1254,25 @@ return self}, function($ctx1) {$ctx1.fill(self,"onSaveIt",{},smalltalk.HLSourceC
 messageSends: ["save:", "contents", "browserModel"]}),
 smalltalk.HLBrowserCodeWidget);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "onShowInstanceToggled",
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st(_st(self)._browserModel())._selectedClass();
+if(($receiver = $1) == nil || $receiver == undefined){
+$2=_st(self)._contents_("");
+return $2;
+} else {
+$1;
+};
+_st(self)._contents_(_st(_st(_st(self)._browserModel())._selectedClass())._definition());
+return self}, function($ctx1) {$ctx1.fill(self,"onShowInstanceToggled",{},smalltalk.HLBrowserCodeWidget)})},
+messageSends: ["ifNil:", "contents:", "selectedClass", "browserModel", "definition"]}),
+smalltalk.HLBrowserCodeWidget);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "onSourceCodeFocusRequested",
@@ -1277,26 +1301,22 @@ smalltalk.method({
 selector: "onUnknownVariableError:",
 fn: function (anError){
 var self=this;
-var confirm;
 function $String(){return smalltalk.String||(typeof String=="undefined"?nil:String)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3,$4;
-confirm=_st(self)._confirm_(_st($String())._streamContents_((function(stream){
+var $1,$2;
+_st(self)._confirm_ifTrue_(_st($String())._streamContents_((function(stream){
 return smalltalk.withContext(function($ctx2) {
 $1=stream;
 _st($1)._nextPutAll_(_st(anError)._messageText());
 _st($1)._nextPutAll_(_st($String())._cr());
 $2=_st($1)._nextPutAll_("Would you like to define an instance variable?");
 return $2;
-}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})})));
-$3=confirm;
-if(! smalltalk.assert($3)){
-$4=self;
-return $4;
-};
-_st(_st(self)._browserModel())._addInstVarNamed_(_st(anError)._variableName());
-return self}, function($ctx1) {$ctx1.fill(self,"onUnknownVariableError:",{anError:anError,confirm:confirm},smalltalk.HLSourceCodeWidget)})},
-messageSends: ["confirm:", "streamContents:", "nextPutAll:", "messageText", "cr", "ifFalse:", "addInstVarNamed:", "variableName", "browserModel"]}),
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})})),(function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(_st(self)._browserModel())._addInstVarNamed_(_st(anError)._variableName());
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"onUnknownVariableError:",{anError:anError},smalltalk.HLBrowserCodeWidget)})},
+messageSends: ["confirm:ifTrue:", "streamContents:", "nextPutAll:", "messageText", "cr", "addInstVarNamed:", "variableName", "browserModel"]}),
 smalltalk.HLBrowserCodeWidget);
 
 smalltalk.addMethod(

+ 48 - 23
js/Helios-Workspace.js

@@ -1303,6 +1303,7 @@ category: 'actions',
 fn: function (){
 var self=this;
 function $HLSaveSourceCode(){return smalltalk.HLSaveSourceCode||(typeof HLSaveSourceCode=="undefined"?nil:HLSaveSourceCode)}
+function $HLShowInstanceToggled(){return smalltalk.HLShowInstanceToggled||(typeof HLShowInstanceToggled=="undefined"?nil:HLShowInstanceToggled)}
 function $HLSourceCodeSaved(){return smalltalk.HLSourceCodeSaved||(typeof HLSourceCodeSaved=="undefined"?nil:HLSourceCodeSaved)}
 function $HLAboutToChange(){return smalltalk.HLAboutToChange||(typeof HLAboutToChange=="undefined"?nil:HLAboutToChange)}
 function $HLParseErrorRaised(){return smalltalk.HLParseErrorRaised||(typeof HLParseErrorRaised=="undefined"?nil:HLParseErrorRaised)}
@@ -1320,6 +1321,10 @@ _st($1)._on_do_($HLSaveSourceCode(),(function(ann){
 return smalltalk.withContext(function($ctx2) {
 return _st(self)._onSaveIt();
 }, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
+_st($1)._on_do_($HLShowInstanceToggled(),(function(ann){
+return smalltalk.withContext(function($ctx2) {
+return _st(self)._onShowInstanceToggled();
+}, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
 _st($1)._on_do_($HLSourceCodeSaved(),(function(ann){
 return smalltalk.withContext(function($ctx2) {
 return _st(self)._onSourceCodeSaved();
@@ -1362,9 +1367,9 @@ return _st(self)._onSourceCodeFocusRequested();
 }, function($ctx2) {$ctx2.fillBlock({ann:ann},$ctx1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"observeBrowserModel",{},smalltalk.HLBrowserCodeWidget)})},
 args: [],
-source: "observeBrowserModel\x0a\x09self browserModel announcer\x0a\x09\x09on: HLSaveSourceCode\x0a\x09\x09do: [ :ann | self onSaveIt ];\x0a\x09\x09on: HLSourceCodeSaved\x0a\x09\x09do: [ :ann | self onSourceCodeSaved ];\x0a\x09\x09on: HLAboutToChange\x0a\x09\x09do: [ :ann | self onBrowserAboutToChange ];\x0a\x09\x09on: HLParseErrorRaised\x0a\x09\x09do: [ :ann | self onParseError: ann ];\x0a\x09\x09on: HLCompileErrorRaised\x0a\x09\x09do: [ :ann | self onCompileError: ann error ];\x0a\x09\x09on: HLUnknownVariableErrorRaised\x0a\x09\x09do: [ :ann | self onUnknownVariableError: ann error ];\x0a\x09\x09on: HLInstVarAdded \x0a\x09\x09do: [ :ann | self onInstVarAdded ];\x0a\x09\x09on: HLMethodSelected \x0a\x09\x09do: [ :ann | self onMethodSelected: ann item ];\x0a    \x09on: HLClassSelected \x0a\x09\x09do: [ :ann | self onClassSelected: ann item ];\x0a    \x09on: HLProtocolSelected \x0a\x09\x09do: [ :ann | self onProtocolSelected: ann item ];\x0a\x09\x09on: HLSourceCodeFocusRequested \x0a\x09\x09do: [ :ann | self onSourceCodeFocusRequested ]",
-messageSends: ["on:do:", "onSaveIt", "announcer", "browserModel", "onSourceCodeSaved", "onBrowserAboutToChange", "onParseError:", "onCompileError:", "error", "onUnknownVariableError:", "onInstVarAdded", "onMethodSelected:", "item", "onClassSelected:", "onProtocolSelected:", "onSourceCodeFocusRequested"],
-referencedClasses: ["HLSaveSourceCode", "HLSourceCodeSaved", "HLAboutToChange", "HLParseErrorRaised", "HLCompileErrorRaised", "HLUnknownVariableErrorRaised", "HLInstVarAdded", "HLMethodSelected", "HLClassSelected", "HLProtocolSelected", "HLSourceCodeFocusRequested"]
+source: "observeBrowserModel\x0a\x09self browserModel announcer\x0a\x09\x09on: HLSaveSourceCode\x0a\x09\x09do: [ :ann | self onSaveIt ];\x0a\x09\x09on: HLShowInstanceToggled\x0a\x09\x09do: [ :ann | self onShowInstanceToggled ];\x0a\x09\x09on: HLSourceCodeSaved\x0a\x09\x09do: [ :ann | self onSourceCodeSaved ];\x0a\x09\x09on: HLAboutToChange\x0a\x09\x09do: [ :ann | self onBrowserAboutToChange ];\x0a\x09\x09on: HLParseErrorRaised\x0a\x09\x09do: [ :ann | self onParseError: ann ];\x0a\x09\x09on: HLCompileErrorRaised\x0a\x09\x09do: [ :ann | self onCompileError: ann error ];\x0a\x09\x09on: HLUnknownVariableErrorRaised\x0a\x09\x09do: [ :ann | self onUnknownVariableError: ann error ];\x0a\x09\x09on: HLInstVarAdded \x0a\x09\x09do: [ :ann | self onInstVarAdded ];\x0a\x09\x09on: HLMethodSelected \x0a\x09\x09do: [ :ann | self onMethodSelected: ann item ];\x0a    \x09on: HLClassSelected \x0a\x09\x09do: [ :ann | self onClassSelected: ann item ];\x0a    \x09on: HLProtocolSelected \x0a\x09\x09do: [ :ann | self onProtocolSelected: ann item ];\x0a\x09\x09on: HLSourceCodeFocusRequested \x0a\x09\x09do: [ :ann | self onSourceCodeFocusRequested ]",
+messageSends: ["on:do:", "onSaveIt", "announcer", "browserModel", "onShowInstanceToggled", "onSourceCodeSaved", "onBrowserAboutToChange", "onParseError:", "onCompileError:", "error", "onUnknownVariableError:", "onInstVarAdded", "onMethodSelected:", "item", "onClassSelected:", "onProtocolSelected:", "onSourceCodeFocusRequested"],
+referencedClasses: ["HLSaveSourceCode", "HLShowInstanceToggled", "HLSourceCodeSaved", "HLAboutToChange", "HLParseErrorRaised", "HLCompileErrorRaised", "HLUnknownVariableErrorRaised", "HLInstVarAdded", "HLMethodSelected", "HLClassSelected", "HLProtocolSelected", "HLSourceCodeFocusRequested"]
 }),
 smalltalk.HLBrowserCodeWidget);
 
@@ -1418,19 +1423,19 @@ fn: function (){
 var self=this;
 function $HLChangeForbidden(){return smalltalk.HLChangeForbidden||(typeof HLChangeForbidden=="undefined"?nil:HLChangeForbidden)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
+var $1;
 $1=_st(self)._hasModification();
 if(smalltalk.assert($1)){
-$2=_st(window)._confirm_("Do you want to cancel changes?");
-if(! smalltalk.assert($2)){
-_st($HLChangeForbidden())._signal();
-};
+_st(self)._confirm_ifFalse_("Do you want to cancel changes?",(function(){
+return smalltalk.withContext(function($ctx2) {
+return _st($HLChangeForbidden())._signal();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
 _st(self)._methodContents_(_st(self)._contents());
 };
 return self}, function($ctx1) {$ctx1.fill(self,"onBrowserAboutToChange",{},smalltalk.HLBrowserCodeWidget)})},
 args: [],
-source: "onBrowserAboutToChange\x0a\x09self hasModification\x0a\x09\x09ifTrue: [ \x0a\x09\x09\x09(window confirm: 'Do you want to cancel changes?') ifFalse: [ \x0a\x09\x09\x09\x09HLChangeForbidden signal ].\x0a\x09\x09\x09\x0a\x09\x09\x09\x22Don't ask twice\x22\x0a\x09\x09\x09self methodContents: self contents ]",
-messageSends: ["ifTrue:", "ifFalse:", "signal", "confirm:", "methodContents:", "contents", "hasModification"],
+source: "onBrowserAboutToChange\x0a\x09self hasModification\x0a\x09\x09ifTrue: [ \x0a\x09\x09\x09self \x0a\x09\x09\x09\x09confirm: 'Do you want to cancel changes?' \x0a\x09\x09\x09\x09ifFalse: [ HLChangeForbidden signal ].\x0a\x09\x09\x09\x0a\x09\x09\x09\x22Don't ask twice\x22\x0a\x09\x09\x09self methodContents: self contents ]",
+messageSends: ["ifTrue:", "confirm:ifFalse:", "signal", "methodContents:", "contents", "hasModification"],
 referencedClasses: ["HLChangeForbidden"]
 }),
 smalltalk.HLBrowserCodeWidget);
@@ -1629,6 +1634,30 @@ referencedClasses: []
 }),
 smalltalk.HLBrowserCodeWidget);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "onShowInstanceToggled",
+category: 'reactions',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1,$2;
+$1=_st(_st(self)._browserModel())._selectedClass();
+if(($receiver = $1) == nil || $receiver == undefined){
+$2=_st(self)._contents_("");
+return $2;
+} else {
+$1;
+};
+_st(self)._contents_(_st(_st(_st(self)._browserModel())._selectedClass())._definition());
+return self}, function($ctx1) {$ctx1.fill(self,"onShowInstanceToggled",{},smalltalk.HLBrowserCodeWidget)})},
+args: [],
+source: "onShowInstanceToggled\x0a\x09self browserModel selectedClass ifNil: [ ^ self contents: '' ].\x0a    \x0a    self contents: self browserModel selectedClass definition",
+messageSends: ["ifNil:", "contents:", "selectedClass", "browserModel", "definition"],
+referencedClasses: []
+}),
+smalltalk.HLBrowserCodeWidget);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "onSourceCodeFocusRequested",
@@ -1668,28 +1697,24 @@ selector: "onUnknownVariableError:",
 category: 'reactions',
 fn: function (anError){
 var self=this;
-var confirm;
 function $String(){return smalltalk.String||(typeof String=="undefined"?nil:String)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2,$3,$4;
-confirm=_st(self)._confirm_(_st($String())._streamContents_((function(stream){
+var $1,$2;
+_st(self)._confirm_ifTrue_(_st($String())._streamContents_((function(stream){
 return smalltalk.withContext(function($ctx2) {
 $1=stream;
 _st($1)._nextPutAll_(_st(anError)._messageText());
 _st($1)._nextPutAll_(_st($String())._cr());
 $2=_st($1)._nextPutAll_("Would you like to define an instance variable?");
 return $2;
-}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})})));
-$3=confirm;
-if(! smalltalk.assert($3)){
-$4=self;
-return $4;
-};
-_st(_st(self)._browserModel())._addInstVarNamed_(_st(anError)._variableName());
-return self}, function($ctx1) {$ctx1.fill(self,"onUnknownVariableError:",{anError:anError,confirm:confirm},smalltalk.HLSourceCodeWidget)})},
+}, function($ctx2) {$ctx2.fillBlock({stream:stream},$ctx1)})})),(function(){
+return smalltalk.withContext(function($ctx2) {
+return _st(_st(self)._browserModel())._addInstVarNamed_(_st(anError)._variableName());
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1)})}));
+return self}, function($ctx1) {$ctx1.fill(self,"onUnknownVariableError:",{anError:anError},smalltalk.HLBrowserCodeWidget)})},
 args: ["anError"],
-source: "onUnknownVariableError: anError\x0a\x09| confirm |\x0a\x0a\x09confirm := self confirm: (String streamContents: [ :stream |\x0a\x09\x09stream \x0a\x09\x09\x09nextPutAll: anError messageText;\x0a\x09\x09\x09nextPutAll: String cr;\x0a\x09\x09\x09nextPutAll: 'Would you like to define an instance variable?' ]).\x0a\x09\x09\x09\x0a\x09confirm ifFalse: [ ^ self ].\x0a\x09\x0a\x09self browserModel addInstVarNamed: anError variableName",
-messageSends: ["confirm:", "streamContents:", "nextPutAll:", "messageText", "cr", "ifFalse:", "addInstVarNamed:", "variableName", "browserModel"],
+source: "onUnknownVariableError: anError\x0a\x09self \x0a\x09\x09confirm: (String streamContents: [ :stream |\x0a\x09\x09\x09stream \x0a\x09\x09\x09\x09nextPutAll: anError messageText;\x0a\x09\x09\x09\x09nextPutAll: String cr;\x0a\x09\x09\x09\x09nextPutAll: 'Would you like to define an instance variable?' ])\x0a\x09\x09ifTrue: [\x0a\x09\x09\x09self browserModel addInstVarNamed: anError variableName ]",
+messageSends: ["confirm:ifTrue:", "streamContents:", "nextPutAll:", "messageText", "cr", "addInstVarNamed:", "variableName", "browserModel"],
 referencedClasses: ["String"]
 }),
 smalltalk.HLBrowserCodeWidget);

+ 105 - 12
st/Helios-Browser.st

@@ -81,8 +81,8 @@ protocolsListWidget
 
 sourceWidget
 	^ sourceWidget ifNil: [
-      	sourceWidget := HLBrowserCodeWidget new
-			browserModel: self model;
+      	sourceWidget := HLBrowserBottomWidget new
+			model: self model;
 			yourself ]
 ! !
 
@@ -109,6 +109,86 @@ canBeOpenAsTab
 	^ true
 ! !
 
+HLWidget subclass: #HLBrowserBottomWidget
+	instanceVariableNames: 'model codeWidget documentationWidget selectedWidget'
+	package: 'Helios-Browser'!
+
+!HLBrowserBottomWidget methodsFor: 'accessing'!
+
+codeWidget
+	^ codeWidget ifNil: [ codeWidget := HLBrowserCodeWidget new
+		browserModel: self model;
+		yourself ]
+!
+
+documentationWidget
+	^ documentationWidget ifNil: [ documentationWidget := HLDocumentationWidget new
+		model: self model;
+		yourself ]
+!
+
+model
+	^ model
+!
+
+model: aModel
+	model := aModel.
+	self observeModel
+!
+
+previous
+	"For navigation"
+!
+
+previous: aWidget
+	"For navigation"
+!
+
+selectedWidget
+	^ selectedWidget ifNil: [ selectedWidget := self codeWidget ]
+! !
+
+!HLBrowserBottomWidget methodsFor: 'actions'!
+
+focus
+	self selectedWidget focus
+!
+
+observeModel
+	self model announcer 
+		on: HLShowInstanceToggled
+		do: [ self onShowInstanceToggled ];
+		on: HLShowCommentToggled
+		do: [ self onShowCommentToggled ]
+!
+
+selectWidget: aWidget
+	selectedWidget := aWidget.
+	self refresh
+! !
+
+!HLBrowserBottomWidget methodsFor: 'reactions'!
+
+onShowCommentToggled
+	self selectWidget: self documentationWidget
+!
+
+onShowInstanceToggled
+	self selectWidget: self codeWidget
+! !
+
+!HLBrowserBottomWidget methodsFor: 'rendering'!
+
+renderContentOn: html
+	html with: self selectedWidget
+! !
+
+!HLBrowserBottomWidget methodsFor: 'testing'!
+
+canHaveFocus
+	^ true
+! !
+
 HLNavigationListWidget subclass: #HLBrowserListWidget
 	instanceVariableNames: 'model'
 	package: 'Helios-Browser'!
@@ -271,6 +351,7 @@ observeModel
 	self model announcer 
     	on: HLPackageSelected do: [ :ann | self onPackageSelected: ann item ];
     	on: HLShowInstanceToggled do: [ :ann | self onShowInstanceToggled ];
+		on: HLShowCommentToggled do: [ :ann | self onShowCommentToggled ];
 		on: HLClassSelected do: [ :ann | self onClassSelected: ann item ];
 		on: HLClassesFocusRequested do: [ :ann | self onClassesFocusRequested ]
 !
@@ -377,6 +458,10 @@ onPackageSelected: aPackage
     self refresh
 !
 
+onShowCommentToggled
+	self refresh
+!
+
 onShowInstanceToggled
 	self refresh
 ! !
@@ -912,7 +997,8 @@ selectedClass
 !
 
 selectedClass: aClass
-	aClass ifNil: [ ^ self ].
+	(self selectedClass = aClass and: [ aClass isNil ]) 
+		ifTrue: [ ^ self ].
 	
 	self withChangesDo: [
 		selectedClass = aClass ifTrue: [ 
@@ -1090,19 +1176,22 @@ openClassNamed: aString
 
 removeClass
 	self withChangesDo: [
-		(self manager confirm: 'Do you REALLY want to remove class ', self selectedClass name)
+		self manager 
+			confirm: 'Do you REALLY want to remove class ', self selectedClass name
 			ifTrue: [ self environment removeClass: self selectedClass ] ]
 !
 
 removeMethod
 	self withChangesDo: [
-		(self manager confirm: 'Do you REALLY want to remove method ', self selectedMethod methodClass name,' >> #', self selectedMethod selector)
+		self manager 
+			confirm: 'Do you REALLY want to remove method ', self selectedMethod methodClass name,' >> #', self selectedMethod selector
 			ifTrue: [ self environment removeMethod: self selectedMethod ] ]
 !
 
 removeProtocol
 	self withChangesDo: [
-		(self manager confirm: 'Do you REALLY want to remove protocol ', self selectedProtocol)
+		self manager 
+			confirm: 'Do you REALLY want to remove protocol ', self selectedProtocol
 			ifTrue: [ self environment 
 				removeProtocol: self selectedProtocol 
 				from: self selectedClass ] ]
@@ -1344,17 +1433,21 @@ on: aClass selectorsCache: aSelectorsCache
 ! !
 
 HLFocusableWidget subclass: #HLDocumentationWidget
-	instanceVariableNames: 'documentation'
+	instanceVariableNames: 'model'
 	package: 'Helios-Browser'!
 
 !HLDocumentationWidget methodsFor: 'accessing'!
 
 documentation
-	^ documentation ifNil: [ self defaultDocumentation ]
+	^ self model selectedClass theNonMetaClass comment ifNil: [ self defaultDocumentation ]
 !
 
-documentation: aString
-	documentation := aString
+model
+	^ model
+!
+
+model: aModel
+	model := aModel
 ! !
 
 !HLDocumentationWidget methodsFor: 'defaults'!
@@ -1367,9 +1460,9 @@ defaultDocumentation
 !HLDocumentationWidget methodsFor: 'rendering'!
 
 renderContentOn: html
-	html div 
+	(html div 
 		class: 'markdown';
-		with: (Showdown makeHtml: self documentation)
+		asJQuery) html: ((Showdown at: 'converter') new makeHtml: self documentation)
 ! !
 
 Object subclass: #HLSelectorsCache

+ 100 - 2
st/Helios-Core.st

@@ -141,8 +141,8 @@ alert: aString
 	window alert: aString
 !
 
-confirm: aString
-	^ window confirm: aString
+confirm: aString ifTrue: aBlock
+	self manager confirm: aString ifTrue: aBlock
 !
 
 execute: aCommand
@@ -206,6 +206,88 @@ canBeOpenAsTab
 	^ false
 ! !
 
+HLWidget subclass: #HLConfirmation
+	instanceVariableNames: 'confirmationString actionBlock cancelBlock'
+	package: 'Helios-Core'!
+
+!HLConfirmation methodsFor: 'accessing'!
+
+actionBlock
+	^ actionBlock ifNil: [ [] ]
+!
+
+actionBlock: aBlock
+	actionBlock := aBlock
+!
+
+cancelBlock
+	^ cancelBlock ifNil: [ [] ]
+!
+
+cancelBlock: aBlock
+	cancelBlock := aBlock
+!
+
+confirmationString
+	^ confirmationString ifNil: [ 'Confirm' ]
+!
+
+confirmationString: aString
+	confirmationString := aString
+! !
+
+!HLConfirmation methodsFor: 'actions'!
+
+cancel
+	self cancelBlock value.
+	self remove
+!
+
+confirm
+	self actionBlock value.
+	self remove
+!
+
+remove
+	(window jQuery: '.confirmation') removeClass: 'active'.
+	[ 
+		(window jQuery: '#overlay') remove.
+		(window jQuery: '.confirmation') remove
+	] valueWithTimeout: 300
+! !
+
+!HLConfirmation methodsFor: 'rendering'!
+
+renderContentOn: html
+	| confirmButton |
+	
+	html div id: 'overlay'.
+	html div 
+		class: 'confirmation';
+		with: [
+			html span with: self confirmationString.
+			html div 
+				class: 'buttons';
+				with: [
+					html button
+						class: 'button';
+						with: 'Cancel';
+						onClick: [ self cancel ].
+					confirmButton := html button
+						class: 'button default';
+						with: 'Confirm';
+						onClick: [ self confirm ] ] ].
+
+	confirmButton asJQuery focus.
+	(window jQuery: '.confirmation') addClass: 'active'.
+	self setupKeyBindings
+!
+
+setupKeyBindings
+	(window jQuery: '.confirmation') keyup: [ :e |
+		e keyCode = 27 ifTrue: [ self cancel ] ]
+! !
+
 HLWidget subclass: #HLDebugger
 	instanceVariableNames: ''
 	package: 'Helios-Core'!
@@ -574,6 +656,22 @@ addToHistory: aTab
 	self history add: aTab
 !
 
+confirm: aString ifFalse: aBlock
+	(HLConfirmation new
+		confirmationString: aString;
+		cancelBlock: aBlock;
+		yourself)
+			appendToJQuery: 'body' asJQuery
+!
+
+confirm: aString ifTrue: aBlock
+	(HLConfirmation new
+		confirmationString: aString;
+		actionBlock: aBlock;
+		yourself)
+			appendToJQuery: 'body' asJQuery
+!
+
 removeActiveTab
 	self removeTab: self activeTab
 !

+ 19 - 13
st/Helios-Workspace.st

@@ -486,6 +486,8 @@ observeBrowserModel
 	self browserModel announcer
 		on: HLSaveSourceCode
 		do: [ :ann | self onSaveIt ];
+		on: HLShowInstanceToggled
+		do: [ :ann | self onShowInstanceToggled ];
 		on: HLSourceCodeSaved
 		do: [ :ann | self onSourceCodeSaved ];
 		on: HLAboutToChange
@@ -538,8 +540,9 @@ saveIt
 onBrowserAboutToChange
 	self hasModification
 		ifTrue: [ 
-			(window confirm: 'Do you want to cancel changes?') ifFalse: [ 
-				HLChangeForbidden signal ].
+			self 
+				confirm: 'Do you want to cancel changes?' 
+				ifFalse: [ HLChangeForbidden signal ].
 			
 			"Don't ask twice"
 			self methodContents: self contents ]
@@ -603,6 +606,12 @@ onSaveIt
 	self browserModel save: self contents
 !
 
+onShowInstanceToggled
+	self browserModel selectedClass ifNil: [ ^ self contents: '' ].
+    
+    self contents: self browserModel selectedClass definition
+!
+
 onSourceCodeFocusRequested
 	self focus
 !
@@ -613,17 +622,14 @@ onSourceCodeSaved
 !
 
 onUnknownVariableError: anError
-	| confirm |
-
-	confirm := self confirm: (String streamContents: [ :stream |
-		stream 
-			nextPutAll: anError messageText;
-			nextPutAll: String cr;
-			nextPutAll: 'Would you like to define an instance variable?' ]).
-			
-	confirm ifFalse: [ ^ self ].
-	
-	self browserModel addInstVarNamed: anError variableName
+	self 
+		confirm: (String streamContents: [ :stream |
+			stream 
+				nextPutAll: anError messageText;
+				nextPutAll: String cr;
+				nextPutAll: 'Would you like to define an instance variable?' ])
+		ifTrue: [
+			self browserModel addInstVarNamed: anError variableName ]
 ! !
 
 !HLBrowserCodeWidget class methodsFor: 'instance creation'!