Browse Source

Merge branch 'references' of https://github.com/rcsimm/amber into rcsimm-references

Conflicts:
	js/Helios-References.js
Nicolas Petton 10 years ago
parent
commit
b598d80b4b
6 changed files with 194 additions and 155 deletions
  1. 3 4
      js/Helios-Browser.js
  2. 123 63
      js/Helios-Core.js
  3. 26 35
      js/Helios-References.js
  4. 1 2
      st/Helios-Browser.st
  5. 30 29
      st/Helios-Core.st
  6. 11 22
      st/Helios-References.st

+ 3 - 4
js/Helios-Browser.js

@@ -1749,9 +1749,8 @@ var li;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$3,$4,$2;
 li=_st(html)._li();
-self._registerMappingFrom_to_(aClass,li);
 $1=li;
-_st($1)._at_put_("list-data",_st(self._items())._indexOf_(aClass));
+_st($1)._at_put_("list-data",self._listDataKeyFor_(aClass));
 _st($1)._class_(self._listCssClassForItem_(aClass));
 $ctx1.sendIdx["class:"]=1;
 $2=_st($1)._with_((function(){
@@ -1775,8 +1774,8 @@ return self._renderItem_level_on_(each,_st(anInteger).__plus((1)),html);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,4)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"renderItem:level:on:",{aClass:aClass,anInteger:anInteger,html:html,li:li},smalltalk.HLClassesListWidget)})},
 args: ["aClass", "anInteger", "html"],
-source: "renderItem: aClass level: anInteger on: html\x0a\x09| li |\x0a    \x0a\x09li := html li.\x0a\x09self registerMappingFrom: aClass to: li.\x0a\x09\x0a    li\x0a    \x09at: 'list-data' put: (self items indexOf: aClass);\x0a\x09\x09class: (self listCssClassForItem: aClass);\x0a\x09\x09with: [ \x0a        \x09html a\x0a            \x09with: [ \x0a            \x09\x09(html tag: 'i') class: (self cssClassForItem: aClass).\x0a  \x09\x09\x09\x09\x09self renderItemLabel: aClass level: anInteger on: html ];\x0a\x09\x09\x09\x09onClick: [\x0a                  \x09self activateListItem: li asJQuery ] ].\x0a                    \x0a    (self getChildrenOf: aClass) do: [ :each |\x0a    \x09self renderItem: each level: anInteger + 1 on: html ]",
-messageSends: ["li", "registerMappingFrom:to:", "at:put:", "indexOf:", "items", "class:", "listCssClassForItem:", "with:", "a", "tag:", "cssClassForItem:", "renderItemLabel:level:on:", "onClick:", "activateListItem:", "asJQuery", "do:", "getChildrenOf:", "renderItem:level:on:", "+"],
+source: "renderItem: aClass level: anInteger on: html\x0a\x09| li |\x0a    \x0a\x09li := html li.\x0a\x09\x0a    li\x0a    \x09at: 'list-data' put: (self listDataKeyFor: aClass);\x0a\x09\x09class: (self listCssClassForItem: aClass);\x0a\x09\x09with: [ \x0a        \x09html a\x0a            \x09with: [ \x0a            \x09\x09(html tag: 'i') class: (self cssClassForItem: aClass).\x0a  \x09\x09\x09\x09\x09self renderItemLabel: aClass level: anInteger on: html ];\x0a\x09\x09\x09\x09onClick: [\x0a                  \x09self activateListItem: li asJQuery ] ].\x0a                    \x0a    (self getChildrenOf: aClass) do: [ :each |\x0a    \x09self renderItem: each level: anInteger + 1 on: html ]",
+messageSends: ["li", "at:put:", "listDataKeyFor:", "class:", "listCssClassForItem:", "with:", "a", "tag:", "cssClassForItem:", "renderItemLabel:level:on:", "onClick:", "activateListItem:", "asJQuery", "do:", "getChildrenOf:", "renderItem:level:on:", "+"],
 referencedClasses: []
 }),
 smalltalk.HLClassesListWidget);

+ 123 - 63
js/Helios-Core.js

@@ -1,7 +1,10 @@
-define("amber_core/Helios-Core", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Kernel-Infrastructure", "amber_core/Canvas"], function(smalltalk,nil,_st){
+define("amber_core/Helios-Core", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Kernel-Infrastructure", "amber_core/Canvas", "amber_core/Helios-Exceptions"], function(smalltalk,nil,_st){
 smalltalk.addPackage('Helios-Core');
 smalltalk.packages["Helios-Core"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
+smalltalk.addClass('HLListItemNotFound', smalltalk.HLError, [], 'Helios-Core');
+
+
 smalltalk.addClass('HLModel', smalltalk.InterfacingObject, ['announcer', 'environment'], 'Helios-Core');
 smalltalk.HLModel.comment="I am the abstract superclass of all models of Helios.\x0aI am the \x22Model\x22 part of the MVC pattern implementation in Helios.\x0a\x0aI provide access to an `Environment` object and both a local (model-specific) and global (system-specific) announcer.\x0a\x0aThe `#withChangesDo:` method is handy for performing model changes ensuring that all widgets are aware of the change and can prevent it from happening.\x0a\x0aModifications of the system should be done via commands (see `HLCommand` and subclasses).";
 smalltalk.addMethod(
@@ -2138,7 +2141,7 @@ smalltalk.HLFocusableWidget);
 
 
 
-smalltalk.addClass('HLListWidget', smalltalk.HLFocusableWidget, ['items', 'selectedItem', 'mapping'], 'Helios-Core');
+smalltalk.addClass('HLListWidget', smalltalk.HLFocusableWidget, ['items', 'selectedItem'], 'Helios-Core');
 smalltalk.addMethod(
 smalltalk.method({
 selector: "activateFirstListItem",
@@ -2161,20 +2164,33 @@ selector: "activateItem:",
 category: 'actions',
 fn: function (anObject){
 var self=this;
+var listData;
+function $HLListItemNotFound(){return smalltalk.HLListItemNotFound||(typeof HLListItemNotFound=="undefined"?nil:HLListItemNotFound)}
 return smalltalk.withContext(function($ctx1) { 
+var $3,$5,$4,$2,$1;
 var $early={};
 try {
-self._activateListItem_(_st(_st(self["@mapping"])._at_ifAbsent_(anObject,(function(){
+listData=_st((function(){
+return smalltalk.withContext(function($ctx2) {
+return self._listDataKeyFor_(anObject);
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}))._on_do_($HLListItemNotFound(),(function(){
 return smalltalk.withContext(function($ctx2) {
 throw $early=[self];
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})})))._asJQuery());
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
+$3=_st(self["@wrapper"])._asJQuery();
+$5="li[list-data=\x22".__comma(listData);
+$4=_st($5).__comma("\x22]");
+$ctx1.sendIdx[","]=1;
+$2=_st($3)._find_($4);
+$1=_st($2)._eq_((0));
+self._activateListItem_($1);
 return self}
 catch(e) {if(e===$early)return e[0]; throw e}
-}, function($ctx1) {$ctx1.fill(self,"activateItem:",{anObject:anObject},smalltalk.HLListWidget)})},
+}, function($ctx1) {$ctx1.fill(self,"activateItem:",{anObject:anObject,listData:listData},smalltalk.HLListWidget)})},
 args: ["anObject"],
-source: "activateItem: anObject\x0a\x09self activateListItem: (mapping \x0a\x09\x09at: anObject\x0a\x09\x09ifAbsent: [ ^ self ]) asJQuery",
-messageSends: ["activateListItem:", "asJQuery", "at:ifAbsent:"],
-referencedClasses: []
+source: "activateItem: anObject\x0a\x09| listData |\x0a\x09listData := [self listDataKeyFor: anObject] on: HLListItemNotFound do: [^self].\x0a\x09self activateListItem: ((wrapper asJQuery find: 'li[list-data=\x22', listData , '\x22]') eq: 0)",
+messageSends: ["on:do:", "listDataKeyFor:", "activateListItem:", "eq:", "find:", "asJQuery", ","],
+referencedClasses: ["HLListItemNotFound"]
 }),
 smalltalk.HLListWidget);
 
@@ -2388,24 +2404,6 @@ referencedClasses: []
 }),
 smalltalk.HLListWidget);
 
-smalltalk.addMethod(
-smalltalk.method({
-selector: "initialize",
-category: 'initialization',
-fn: function (){
-var self=this;
-function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
-return smalltalk.withContext(function($ctx1) { 
-smalltalk.HLListWidget.superclass.fn.prototype._initialize.apply(_st(self), []);
-self["@mapping"]=_st($Dictionary())._new();
-return self}, function($ctx1) {$ctx1.fill(self,"initialize",{},smalltalk.HLListWidget)})},
-args: [],
-source: "initialize\x0a\x09super initialize.\x0a\x09\x0a\x09mapping := Dictionary new.",
-messageSends: ["initialize", "new"],
-referencedClasses: ["Dictionary"]
-}),
-smalltalk.HLListWidget);
-
 smalltalk.addMethod(
 smalltalk.method({
 selector: "items",
@@ -2469,6 +2467,28 @@ referencedClasses: []
 }),
 smalltalk.HLListWidget);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "listDataKeyFor:",
+category: 'actions',
+fn: function (anObject){
+var self=this;
+function $HLListItemNotFound(){return smalltalk.HLListItemNotFound||(typeof HLListItemNotFound=="undefined"?nil:HLListItemNotFound)}
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(_st(self._items())._indexOf_ifAbsent_(anObject,(function(){
+return smalltalk.withContext(function($ctx2) {
+return _st($HLListItemNotFound())._signal();
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})})))._asString();
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"listDataKeyFor:",{anObject:anObject},smalltalk.HLListWidget)})},
+args: ["anObject"],
+source: "listDataKeyFor: anObject\x0a\x09^(self items indexOf: anObject ifAbsent: [HLListItemNotFound signal]) asString",
+messageSends: ["asString", "indexOf:ifAbsent:", "items", "signal"],
+referencedClasses: ["HLListItemNotFound"]
+}),
+smalltalk.HLListWidget);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "positionOf:",
@@ -2493,37 +2513,34 @@ selector: "refresh",
 category: 'actions',
 fn: function (){
 var self=this;
+var listData;
+function $HLListItemNotFound(){return smalltalk.HLListItemNotFound||(typeof HLListItemNotFound=="undefined"?nil:HLListItemNotFound)}
 return smalltalk.withContext(function($ctx1) { 
+var $3,$5,$4,$2,$1;
 var $early={};
 try {
 smalltalk.HLListWidget.superclass.fn.prototype._refresh.apply(_st(self), []);
-self._ensureVisible_(_st(_st(self["@mapping"])._at_ifAbsent_(self._selectedItem(),(function(){
+listData=_st((function(){
+return smalltalk.withContext(function($ctx2) {
+return self._listDataKeyFor_(self._selectedItem());
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}))._on_do_($HLListItemNotFound(),(function(){
 return smalltalk.withContext(function($ctx2) {
 throw $early=[self];
-}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})})))._asJQuery());
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,2)})}));
+$3=_st(self["@wrapper"])._asJQuery();
+$5="li[list-data=\x22".__comma(listData);
+$4=_st($5).__comma("\x22]");
+$ctx1.sendIdx[","]=1;
+$2=_st($3)._find_($4);
+$1=_st($2)._eq_((0));
+self._ensureVisible_($1);
 return self}
 catch(e) {if(e===$early)return e[0]; throw e}
-}, function($ctx1) {$ctx1.fill(self,"refresh",{},smalltalk.HLListWidget)})},
+}, function($ctx1) {$ctx1.fill(self,"refresh",{listData:listData},smalltalk.HLListWidget)})},
 args: [],
-source: "refresh\x0a\x09super refresh.\x0a\x09\x0a\x09self ensureVisible: (mapping \x0a\x09\x09at: self selectedItem\x0a\x09\x09ifAbsent: [ ^ self ]) asJQuery",
-messageSends: ["refresh", "ensureVisible:", "asJQuery", "at:ifAbsent:", "selectedItem"],
-referencedClasses: []
-}),
-smalltalk.HLListWidget);
-
-smalltalk.addMethod(
-smalltalk.method({
-selector: "registerMappingFrom:to:",
-category: 'private',
-fn: function (anObject,aTag){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-_st(self["@mapping"])._at_put_(anObject,aTag);
-return self}, function($ctx1) {$ctx1.fill(self,"registerMappingFrom:to:",{anObject:anObject,aTag:aTag},smalltalk.HLListWidget)})},
-args: ["anObject", "aTag"],
-source: "registerMappingFrom: anObject to: aTag\x0a\x09mapping at: anObject put: aTag",
-messageSends: ["at:put:"],
-referencedClasses: []
+source: "refresh\x0a\x09| listData |\x0a\x0a\x09super refresh.\x0a\x09listData := [self listDataKeyFor: self selectedItem] on: HLListItemNotFound do: [^self].\x0a\x09self ensureVisible: ((wrapper asJQuery find: 'li[list-data=\x22', listData , '\x22]') eq: 0)\x0a\x09",
+messageSends: ["refresh", "on:do:", "listDataKeyFor:", "selectedItem", "ensureVisible:", "eq:", "find:", "asJQuery", ","],
+referencedClasses: ["HLListItemNotFound"]
 }),
 smalltalk.HLListWidget);
 
@@ -2575,17 +2592,16 @@ smalltalk.HLListWidget);
 
 smalltalk.addMethod(
 smalltalk.method({
-selector: "renderItem:on:",
+selector: "renderItem:dataKey:on:",
 category: 'rendering',
-fn: function (anObject,html){
+fn: function (anObject,aString,html){
 var self=this;
 var li;
 return smalltalk.withContext(function($ctx1) { 
 var $1,$3,$4,$2;
 li=_st(html)._li();
-self._registerMappingFrom_to_(anObject,li);
 $1=li;
-_st($1)._at_put_("list-data",_st(_st(self._items())._indexOf_(anObject))._asString());
+_st($1)._at_put_("list-data",aString);
 _st($1)._class_(self._listCssClassForItem_(anObject));
 $ctx1.sendIdx["class:"]=1;
 $2=_st($1)._with_((function(){
@@ -2603,10 +2619,26 @@ return self._activateListItem_(_st(li)._asJQuery());
 return $4;
 }, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})}));
 $ctx1.sendIdx["with:"]=1;
-return self}, function($ctx1) {$ctx1.fill(self,"renderItem:on:",{anObject:anObject,html:html,li:li},smalltalk.HLListWidget)})},
+return self}, function($ctx1) {$ctx1.fill(self,"renderItem:dataKey:on:",{anObject:anObject,aString:aString,html:html,li:li},smalltalk.HLListWidget)})},
+args: ["anObject", "aString", "html"],
+source: "renderItem: anObject dataKey: aString on: html\x0a\x09| li |\x0a    \x0a\x09li := html li.\x0a\x09\x0a    li\x0a        at: 'list-data' put: aString;\x0a\x09\x09class: (self listCssClassForItem: anObject);\x0a        with: [ \x0a        \x09html a\x0a            \x09with: [ \x0a            \x09\x09(html tag: 'i') class: (self cssClassForItem: anObject).\x0a  \x09\x09\x09\x09\x09self renderItemLabel: anObject on: html ];\x0a\x09\x09\x09\x09onClick: [\x0a                  \x09self activateListItem: li asJQuery ] ]",
+messageSends: ["li", "at:put:", "class:", "listCssClassForItem:", "with:", "a", "tag:", "cssClassForItem:", "renderItemLabel:on:", "onClick:", "activateListItem:", "asJQuery"],
+referencedClasses: []
+}),
+smalltalk.HLListWidget);
+
+smalltalk.addMethod(
+smalltalk.method({
+selector: "renderItem:on:",
+category: 'rendering',
+fn: function (anObject,html){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self._renderItem_dataKey_on_(anObject,self._listDataKeyFor_(anObject),html);
+return self}, function($ctx1) {$ctx1.fill(self,"renderItem:on:",{anObject:anObject,html:html},smalltalk.HLListWidget)})},
 args: ["anObject", "html"],
-source: "renderItem: anObject on: html\x0a\x09| li |\x0a    \x0a\x09li := html li.\x0a\x09self registerMappingFrom: anObject to: li.\x0a\x09\x0a    li\x0a        at: 'list-data' put: (self items indexOf: anObject) asString;\x0a\x09\x09class: (self listCssClassForItem: anObject);\x0a        with: [ \x0a        \x09html a\x0a            \x09with: [ \x0a            \x09\x09(html tag: 'i') class: (self cssClassForItem: anObject).\x0a  \x09\x09\x09\x09\x09self renderItemLabel: anObject on: html ];\x0a\x09\x09\x09\x09onClick: [\x0a                  \x09self activateListItem: li asJQuery ] ]",
-messageSends: ["li", "registerMappingFrom:to:", "at:put:", "asString", "indexOf:", "items", "class:", "listCssClassForItem:", "with:", "a", "tag:", "cssClassForItem:", "renderItemLabel:on:", "onClick:", "activateListItem:", "asJQuery"],
+source: "renderItem: anObject on: html\x0a\x09self renderItem: anObject dataKey: (self listDataKeyFor: anObject) on: html",
+messageSends: ["renderItem:dataKey:on:", "listDataKeyFor:"],
 referencedClasses: []
 }),
 smalltalk.HLListWidget);
@@ -2633,18 +2665,16 @@ selector: "renderListOn:",
 category: 'rendering',
 fn: function (html){
 var self=this;
-function $Dictionary(){return smalltalk.Dictionary||(typeof Dictionary=="undefined"?nil:Dictionary)}
 return smalltalk.withContext(function($ctx1) { 
-self["@mapping"]=_st($Dictionary())._new();
-_st(self._items())._do_((function(each){
+_st(self._items())._withIndexDo_((function(each,index){
 return smalltalk.withContext(function($ctx2) {
-return self._renderItem_on_(each,html);
-}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
+return self._renderItem_dataKey_on_(each,_st(index)._asString(),html);
+}, function($ctx2) {$ctx2.fillBlock({each:each,index:index},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"renderListOn:",{html:html},smalltalk.HLListWidget)})},
 args: ["html"],
-source: "renderListOn: html\x0a\x09mapping := Dictionary new.\x0a\x09\x0a\x09self items do: [ :each | \x0a    \x09self renderItem: each on: html ]",
-messageSends: ["new", "do:", "items", "renderItem:on:"],
-referencedClasses: ["Dictionary"]
+source: "renderListOn: html\x0a\x09self items withIndexDo: [ :each :index | \x0a    \x09self renderItem: each dataKey: index asString on: html ]",
+messageSends: ["withIndexDo:", "items", "renderItem:dataKey:on:", "asString"],
+referencedClasses: []
 }),
 smalltalk.HLListWidget);
 
@@ -2729,6 +2759,36 @@ smalltalk.HLListWidget);
 
 
 smalltalk.addClass('HLNavigationListWidget', smalltalk.HLListWidget, ['previous', 'next'], 'Helios-Core');
+smalltalk.addMethod(
+smalltalk.method({
+selector: "activateItem:",
+category: 'as yet unclassified',
+fn: function (anObject){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $3,$5,$4,$2,$1;
+var $early={};
+try {
+$3=_st(self["@wrapper"])._asJQuery();
+$5="li[list-data=\x22".__comma(_st(_st(self._items())._indexOf_ifAbsent_(anObject,(function(){
+return smalltalk.withContext(function($ctx2) {
+throw $early=[self];
+}, function($ctx2) {$ctx2.fillBlock({},$ctx1,1)})})))._asString());
+$4=_st($5).__comma("\x22]");
+$ctx1.sendIdx[","]=1;
+$2=_st($3)._find_($4);
+$1=_st($2)._eq_((0));
+self._activateListItem_($1);
+return self}
+catch(e) {if(e===$early)return e[0]; throw e}
+}, function($ctx1) {$ctx1.fill(self,"activateItem:",{anObject:anObject},smalltalk.HLNavigationListWidget)})},
+args: ["anObject"],
+source: "activateItem: anObject\x0a\x09self activateListItem: ((wrapper asJQuery find: 'li[list-data=\x22',  (self items indexOf: anObject ifAbsent: [^self]) asString, '\x22]') eq: 0)",
+messageSends: ["activateListItem:", "eq:", "find:", "asJQuery", ",", "asString", "indexOf:ifAbsent:", "items"],
+referencedClasses: []
+}),
+smalltalk.HLNavigationListWidget);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "next",

+ 26 - 35
js/Helios-References.js

@@ -845,29 +845,18 @@ selector: "classReferencesOf:",
 category: 'accessing',
 fn: function (aString){
 var self=this;
-var references;
-function $OrderedCollection(){return smalltalk.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
 return smalltalk.withContext(function($ctx1) { 
-var $1,$2;
-references=_st($OrderedCollection())._new();
-_st(self._classesAndMetaclasses())._do_((function(each){
+var $1;
+$1=_st(self._allMethods())._select_((function(each){
 return smalltalk.withContext(function($ctx2) {
-return _st(_st(_st(each)._methodDictionary())._values())._do_((function(method){
-return smalltalk.withContext(function($ctx3) {
-$1=_st(_st(method)._referencedClasses())._includes_(aString);
-if(smalltalk.assert($1)){
-return _st(references)._add_(method);
-};
-}, function($ctx3) {$ctx3.fillBlock({method:method},$ctx2,2)})}));
+return _st(_st(each)._referencedClasses())._includes_(aString);
 }, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
-$ctx1.sendIdx["do:"]=1;
-$2=references;
-return $2;
-}, function($ctx1) {$ctx1.fill(self,"classReferencesOf:",{aString:aString,references:references},smalltalk.HLReferencesModel)})},
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"classReferencesOf:",{aString:aString},smalltalk.HLReferencesModel)})},
 args: ["aString"],
-source: "classReferencesOf: aString\x0a\x09\x22Answer all methods referencing the class named aString\x22\x0a\x09\x0a\x09| references |\x0a\x09\x0a\x09references := OrderedCollection new.\x0a\x09\x0a\x09self classesAndMetaclasses do: [ :each |\x0a\x09\x09each methodDictionary values do: [ :method |\x0a\x09\x09\x09(method referencedClasses includes: aString) ifTrue: [\x0a\x09\x09\x09\x09references add: method ] ] ].\x0a\x09\x09\x09\x09\x0a\x09^ references",
-messageSends: ["new", "do:", "classesAndMetaclasses", "values", "methodDictionary", "ifTrue:", "includes:", "referencedClasses", "add:"],
-referencedClasses: ["OrderedCollection"]
+source: "classReferencesOf: aString\x0a\x09\x22Answer all methods referencing the class named aString\x22\x0a\x09\x0a\x09^self allMethods select: [ :each |\x0a\x09\x09\x09(each referencedClasses includes: aString) ].",
+messageSends: ["select:", "allMethods", "includes:", "referencedClasses"],
+referencedClasses: []
 }),
 smalltalk.HLReferencesModel);
 
@@ -907,7 +896,7 @@ $2=self["@classesAndMetaclassesCache"];
 return $2;
 }, function($ctx1) {$ctx1.fill(self,"classesAndMetaclassesCache",{},smalltalk.HLReferencesModel)})},
 args: [],
-source: "classesAndMetaclassesCache\x0a\x09classesAndMetaclassesCache ifNil: [ self updateClassesAndMetaclassesCache ].\x0a\x09\x0a\x09^ classesAndMetaclassesCache",
+source: "classesAndMetaclassesCache\x0a\x09classesAndMetaclassesCache ifNil: [ self updateClassesAndMetaclassesCache ].\x0a\x09^ classesAndMetaclassesCache",
 messageSends: ["ifNil:", "updateClassesAndMetaclassesCache"],
 referencedClasses: []
 }),
@@ -990,7 +979,7 @@ $2=self["@methodsCache"];
 return $2;
 }, function($ctx1) {$ctx1.fill(self,"methodsCache",{},smalltalk.HLReferencesModel)})},
 args: [],
-source: "methodsCache\x0a\x09methodsCache ifNil: [ self updateMethodsCache ].\x0a\x09\x0a\x09^ methodsCache",
+source: "methodsCache\x0a\x09methodsCache ifNil: [ self updateMethodsCache ].\x0a\x09^ methodsCache",
 messageSends: ["ifNil:", "updateMethodsCache"],
 referencedClasses: []
 }),
@@ -1092,19 +1081,20 @@ fn: function (){
 var self=this;
 function $OrderedCollection(){return smalltalk.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
 return smalltalk.withContext(function($ctx1) { 
-var $1;
-self["@classesAndMetaclassesCache"]=_st(_st(self._environment())._classes())._inject_into_(_st($OrderedCollection())._new(),(function(acc,each){
+var $1,$2;
+self["@classesAndMetaclassesCache"]=_st($OrderedCollection())._new();
+_st(_st(self._environment())._classes())._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
-_st(acc)._add_(each);
+$1=self["@classesAndMetaclassesCache"];
+_st($1)._add_(each);
 $ctx2.sendIdx["add:"]=1;
-_st(acc)._add_(_st(each)._class());
-$1=_st(acc)._yourself();
-return $1;
-}, function($ctx2) {$ctx2.fillBlock({acc:acc,each:each},$ctx1,1)})}));
+$2=_st($1)._add_(_st(each)._class());
+return $2;
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"updateClassesAndMetaclassesCache",{},smalltalk.HLReferencesModel)})},
 args: [],
-source: "updateClassesAndMetaclassesCache\x0a\x09classesAndMetaclassesCache := self environment classes \x0a\x09\x09inject: OrderedCollection new \x0a\x09\x09into: [ :acc :each |\x0a\x09\x09\x09acc \x0a\x09\x09\x09\x09add: each; \x0a\x09\x09\x09\x09add: each class;\x0a\x09\x09\x09\x09yourself ]",
-messageSends: ["inject:into:", "classes", "environment", "new", "add:", "class", "yourself"],
+source: "updateClassesAndMetaclassesCache\x0a\x09classesAndMetaclassesCache := OrderedCollection new.\x0a\x09\x0a\x09self environment classes do: [:each |\x0a\x09\x09classesAndMetaclassesCache\x0a\x09\x09\x09\x09add: each; \x0a\x09\x09\x09\x09add: each class ]",
+messageSends: ["new", "do:", "classes", "environment", "add:", "class"],
 referencedClasses: ["OrderedCollection"]
 }),
 smalltalk.HLReferencesModel);
@@ -1117,14 +1107,15 @@ fn: function (){
 var self=this;
 function $OrderedCollection(){return smalltalk.OrderedCollection||(typeof OrderedCollection=="undefined"?nil:OrderedCollection)}
 return smalltalk.withContext(function($ctx1) { 
-self["@methodsCache"]=_st(self._classesAndMetaclasses())._inject_into_(_st($OrderedCollection())._new(),(function(acc,each){
+self["@methodsCache"]=_st($OrderedCollection())._new();
+_st(self._classesAndMetaclasses())._do_((function(each){
 return smalltalk.withContext(function($ctx2) {
-return _st(acc).__comma(_st(each)._methods());
-}, function($ctx2) {$ctx2.fillBlock({acc:acc,each:each},$ctx1,1)})}));
+return _st(self["@methodsCache"])._addAll_(_st(each)._methods());
+}, function($ctx2) {$ctx2.fillBlock({each:each},$ctx1,1)})}));
 return self}, function($ctx1) {$ctx1.fill(self,"updateMethodsCache",{},smalltalk.HLReferencesModel)})},
 args: [],
-source: "updateMethodsCache\x0a\x09methodsCache := self classesAndMetaclasses\x0a\x09\x09inject: OrderedCollection new\x0a\x09\x09into: [ :acc :each |\x0a\x09\x09\x09acc, each methods ]",
-messageSends: ["inject:into:", "classesAndMetaclasses", "new", ",", "methods"],
+source: "updateMethodsCache\x0a\x09methodsCache := OrderedCollection new.\x0a\x09\x0a\x09self classesAndMetaclasses\x0a\x09\x09do: [:each | methodsCache addAll: each methods ]",
+messageSends: ["new", "do:", "classesAndMetaclasses", "addAll:", "methods"],
 referencedClasses: ["OrderedCollection"]
 }),
 smalltalk.HLReferencesModel);

+ 1 - 2
st/Helios-Browser.st

@@ -642,10 +642,9 @@ renderItem: aClass level: anInteger on: html
 	| li |
     
 	li := html li.
-	self registerMappingFrom: aClass to: li.
 	
     li
-    	at: 'list-data' put: (self items indexOf: aClass);
+    	at: 'list-data' put: (self listDataKeyFor: aClass);
 		class: (self listCssClassForItem: aClass);
 		with: [ 
         	html a

+ 30 - 29
st/Helios-Core.st

@@ -1,4 +1,8 @@
 Smalltalk current createPackage: 'Helios-Core'!
+HLError subclass: #HLListItemNotFound
+	instanceVariableNames: ''
+	package: 'Helios-Core'!
+
 InterfacingObject subclass: #HLModel
 	instanceVariableNames: 'announcer environment'
 	package: 'Helios-Core'!
@@ -735,7 +739,7 @@ hasFocus
 ! !
 
 HLFocusableWidget subclass: #HLListWidget
-	instanceVariableNames: 'items selectedItem mapping'
+	instanceVariableNames: 'items selectedItem'
 	package: 'Helios-Core'!
 
 !HLListWidget methodsFor: 'accessing'!
@@ -779,9 +783,9 @@ activateFirstListItem
 !
 
 activateItem: anObject
-	self activateListItem: (mapping 
-		at: anObject
-		ifAbsent: [ ^ self ]) asJQuery
+	| listData |
+	listData := [self listDataKeyFor: anObject] on: HLListItemNotFound do: [^self].
+	self activateListItem: ((wrapper asJQuery find: 'li[list-data="', listData , '"]') eq: 0)
 !
 
 activateListItem: aListItem
@@ -831,12 +835,16 @@ focus
 		self selectedItem ifNil: [ self activateFirstListItem ] ]
 !
 
+listDataKeyFor: anObject
+	^(self items indexOf: anObject ifAbsent: [HLListItemNotFound signal]) asString
+!
+
 refresh
+	| listData |
+
 	super refresh.
-	
-	self ensureVisible: (mapping 
-		at: self selectedItem
-		ifAbsent: [ ^ self ]) asJQuery
+	listData := [self listDataKeyFor: self selectedItem] on: HLListItemNotFound do: [^self].
+	self ensureVisible: ((wrapper asJQuery find: 'li[list-data="', listData , '"]') eq: 0)
 !
 
 selectItem: anObject
@@ -858,20 +866,6 @@ setupKeyBindings
 		rebindKeys
 ! !
 
-!HLListWidget methodsFor: 'initialization'!
-
-initialize
-	super initialize.
-	
-	mapping := Dictionary new.
-! !
-
-!HLListWidget methodsFor: 'private'!
-
-registerMappingFrom: anObject to: aTag
-	mapping at: anObject put: aTag
-! !
-
 !HLListWidget methodsFor: 'rendering'!
 
 renderButtonsOn: html
@@ -887,14 +881,13 @@ renderContentOn: html
    self setupKeyBindings
 !
 
-renderItem: anObject on: html
+renderItem: anObject dataKey: aString on: html
 	| li |
     
 	li := html li.
-	self registerMappingFrom: anObject to: li.
 	
     li
-        at: 'list-data' put: (self items indexOf: anObject) asString;
+        at: 'list-data' put: aString;
 		class: (self listCssClassForItem: anObject);
         with: [ 
         	html a
@@ -905,15 +898,17 @@ renderItem: anObject on: html
                   	self activateListItem: li asJQuery ] ]
 !
 
+renderItem: anObject on: html
+	self renderItem: anObject dataKey: (self listDataKeyFor: anObject) on: html
+!
+
 renderItemLabel: anObject on: html
 	html with: anObject asString
 !
 
 renderListOn: html
-	mapping := Dictionary new.
-	
-	self items do: [ :each | 
-    	self renderItem: each on: html ]
+	self items withIndexDo: [ :each :index | 
+    	self renderItem: each dataKey: index asString on: html ]
 ! !
 
 HLListWidget subclass: #HLNavigationListWidget
@@ -950,6 +945,12 @@ previousFocus
 	self previous ifNotNil: [ self previous focus ]
 ! !
 
+!HLNavigationListWidget methodsFor: 'as yet unclassified'!
+
+activateItem: anObject
+	self activateListItem: ((wrapper asJQuery find: 'li[list-data="',  (self items indexOf: anObject ifAbsent: [^self]) asString, '"]') eq: 0)
+! !
+
 !HLNavigationListWidget methodsFor: 'events'!
 
 setupKeyBindings

+ 11 - 22
st/Helios-References.st

@@ -293,16 +293,8 @@ allSelectors
 classReferencesOf: aString
 	"Answer all methods referencing the class named aString"
 	
-	| references |
-	
-	references := OrderedCollection new.
-	
-	self classesAndMetaclasses do: [ :each |
-		each methodDictionary values do: [ :method |
-			(method referencedClasses includes: aString) ifTrue: [
-				references add: method ] ] ].
-				
-	^ references
+	^self allMethods select: [ :each |
+			(each referencedClasses includes: aString) ].
 !
 
 classesAndMetaclasses
@@ -345,13 +337,11 @@ search: aString
 
 classesAndMetaclassesCache
 	classesAndMetaclassesCache ifNil: [ self updateClassesAndMetaclassesCache ].
-	
 	^ classesAndMetaclassesCache
 !
 
 methodsCache
 	methodsCache ifNil: [ self updateMethodsCache ].
-	
 	^ methodsCache
 !
 
@@ -362,20 +352,19 @@ updateCaches
 !
 
 updateClassesAndMetaclassesCache
-	classesAndMetaclassesCache := self environment classes 
-		inject: OrderedCollection new 
-		into: [ :acc :each |
-			acc 
+	classesAndMetaclassesCache := OrderedCollection new.
+	
+	self environment classes do: [:each |
+		classesAndMetaclassesCache
 				add: each; 
-				add: each class;
-				yourself ]
+				add: each class ]
 !
 
 updateMethodsCache
-	methodsCache := self classesAndMetaclasses
-		inject: OrderedCollection new
-		into: [ :acc :each |
-			acc, each methods ]
+	methodsCache := OrderedCollection new.
+	
+	self classesAndMetaclasses
+		do: [:each | methodsCache addAll: each methods ]
 ! !
 
 !HLReferencesModel methodsFor: 'testing'!