resin 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/README.markdown +2 -0
  2. data/amber/bin/nodecompile.js +3 -3
  3. data/amber/css/amber.css +47 -23
  4. data/amber/images/off.amber.png +0 -0
  5. data/amber/images/offHover.amber.png +0 -0
  6. data/amber/images/sprite.amber.png +0 -0
  7. data/amber/images/tinylogo.amber.png +0 -0
  8. data/amber/js/Benchfib.deploy.js +34 -34
  9. data/amber/js/Benchfib.js +49 -49
  10. data/amber/js/Canvas.deploy.js +937 -937
  11. data/amber/js/Canvas.js +1622 -1622
  12. data/amber/js/Compiler-Tests.deploy.js +97 -0
  13. data/amber/js/Compiler-Tests.js +137 -0
  14. data/amber/js/Compiler.deploy.js +1030 -924
  15. data/amber/js/Compiler.js +1613 -1467
  16. data/amber/js/Documentation.deploy.js +417 -417
  17. data/amber/js/Documentation.js +728 -728
  18. data/amber/js/Examples.deploy.js +24 -13
  19. data/amber/js/Examples.js +36 -19
  20. data/amber/js/IDE.deploy.js +1583 -1527
  21. data/amber/js/IDE.js +2586 -2510
  22. data/amber/js/Kernel-Announcements.deploy.js +19 -19
  23. data/amber/js/Kernel-Announcements.js +28 -28
  24. data/amber/js/Kernel-Classes.deploy.js +332 -229
  25. data/amber/js/Kernel-Classes.js +532 -384
  26. data/amber/js/Kernel-Collections.deploy.js +1516 -1712
  27. data/amber/js/Kernel-Collections.js +2436 -2712
  28. data/amber/js/Kernel-Exceptions.deploy.js +85 -62
  29. data/amber/js/Kernel-Exceptions.js +131 -98
  30. data/amber/js/Kernel-Methods.deploy.js +326 -378
  31. data/amber/js/Kernel-Methods.js +473 -525
  32. data/amber/js/Kernel-Objects.deploy.js +1777 -2428
  33. data/amber/js/Kernel-Objects.js +2599 -3426
  34. data/amber/js/Kernel-Tests.deploy.js +871 -772
  35. data/amber/js/Kernel-Tests.js +1207 -1083
  36. data/amber/js/Kernel-Transcript.deploy.js +57 -57
  37. data/amber/js/Kernel-Transcript.js +94 -94
  38. data/amber/js/SUnit.deploy.js +116 -116
  39. data/amber/js/SUnit.js +211 -211
  40. data/amber/js/amber.js +10 -11
  41. data/amber/js/boot.js +132 -156
  42. data/amber/js/init.js +2 -2
  43. data/amber/js/parser.js +2095 -3014
  44. data/amber/js/parser.pegjs +1 -1
  45. data/amber/st/Benchfib.st +22 -22
  46. data/amber/st/Canvas.st +471 -471
  47. data/amber/st/Compiler-Tests.st +471 -0
  48. data/amber/st/Compiler.st +858 -794
  49. data/amber/st/Examples.st +22 -5
  50. data/amber/st/IDE.st +1326 -1291
  51. data/amber/st/Kernel-Announcements.st +2 -2
  52. data/amber/st/Kernel-Classes.st +148 -90
  53. data/amber/st/Kernel-Collections.st +950 -1061
  54. data/amber/st/Kernel-Exceptions.st +33 -25
  55. data/amber/st/Kernel-Methods.st +151 -151
  56. data/amber/st/Kernel-Objects.st +891 -1036
  57. data/amber/st/Kernel-Tests.st +622 -544
  58. data/amber/st/Kernel-Transcript.st +38 -38
  59. data/amber/st/SUnit.st +53 -53
  60. metadata +27 -20
@@ -1,502 +1,495 @@
1
1
  smalltalk.addPackage('Documentation', {});
2
- smalltalk.addClass('DocumentationBuilder', smalltalk.Object, ['chapters', 'announcer', 'widget'], 'Documentation');
2
+ smalltalk.addClass('ChapterSelectionAnnouncement', smalltalk.Object, ['id'], 'Documentation');
3
3
  smalltalk.addMethod(
4
- unescape('_chapters'),
4
+ "_id",
5
5
  smalltalk.method({
6
- selector: unescape('chapters'),
6
+ selector: "id",
7
7
  fn: function (){
8
8
  var self=this;
9
- return (($receiver = self['@chapters']) == nil || $receiver == undefined) ? (function(){return (self['@chapters']=smalltalk.send(self, "_buildChapters", []));})() : $receiver;
9
+ return self['@id'];
10
10
  return self;}
11
11
  }),
12
- smalltalk.DocumentationBuilder);
12
+ smalltalk.ChapterSelectionAnnouncement);
13
13
 
14
14
  smalltalk.addMethod(
15
- unescape('_announcer'),
15
+ "_id_",
16
16
  smalltalk.method({
17
- selector: unescape('announcer'),
18
- fn: function (){
17
+ selector: "id:",
18
+ fn: function (aString){
19
19
  var self=this;
20
- return (($receiver = self['@announcer']) == nil || $receiver == undefined) ? (function(){return (self['@announcer']=smalltalk.send((smalltalk.Announcer || Announcer), "_new", []));})() : $receiver;
20
+ (self['@id']=aString);
21
21
  return self;}
22
22
  }),
23
- smalltalk.DocumentationBuilder);
23
+ smalltalk.ChapterSelectionAnnouncement);
24
+
24
25
 
25
- smalltalk.addMethod(
26
- unescape('_widget'),
27
- smalltalk.method({
28
- selector: unescape('widget'),
29
- fn: function (){
30
- var self=this;
31
- return (($receiver = self['@widget']) == nil || $receiver == undefined) ? (function(){return (self['@widget']=smalltalk.send((smalltalk.DocumentationWidget || DocumentationWidget), "_on_", [self]));})() : $receiver;
32
- return self;}
33
- }),
34
- smalltalk.DocumentationBuilder);
35
26
 
27
+ smalltalk.addClass('ClassSelectionAnnouncement', smalltalk.Object, ['theClass'], 'Documentation');
36
28
  smalltalk.addMethod(
37
- unescape('_buildChapters'),
29
+ "_theClass",
38
30
  smalltalk.method({
39
- selector: unescape('buildChapters'),
31
+ selector: "theClass",
40
32
  fn: function (){
41
33
  var self=this;
42
- return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_class", []), "_methodDictionary", []), "_values", []), "_sorted_", [(function(a, b){return ((($receiver = smalltalk.send(a, "_selector", [])).klass === smalltalk.Number) ? $receiver <smalltalk.send(b, "_selector", []) : smalltalk.send($receiver, "__lt", [smalltalk.send(b, "_selector", [])]));})]), "_select_", [(function(each){return smalltalk.send(smalltalk.send(each, "_category", []), "__eq", ["chapters"]);})]), "_collect_", [(function(each){return smalltalk.send(self, "_perform_", [smalltalk.send(each, "_selector", [])]);})]);
34
+ return self['@theClass'];
43
35
  return self;}
44
36
  }),
45
- smalltalk.DocumentationBuilder);
37
+ smalltalk.ClassSelectionAnnouncement);
46
38
 
47
39
  smalltalk.addMethod(
48
- unescape('_buildOn_'),
40
+ "_theClass_",
49
41
  smalltalk.method({
50
- selector: unescape('buildOn%3A'),
51
- fn: function (aCanvas){
42
+ selector: "theClass:",
43
+ fn: function (aClass){
52
44
  var self=this;
53
- smalltalk.send(aCanvas, "_with_", [smalltalk.send(self, "_widget", [])]);
54
- (function($rec){smalltalk.send($rec, "_checkHashChange", []);return smalltalk.send($rec, "_checkHash", []);})(self);
45
+ (self['@theClass']=aClass);
55
46
  return self;}
56
47
  }),
57
- smalltalk.DocumentationBuilder);
48
+ smalltalk.ClassSelectionAnnouncement);
49
+
58
50
 
59
51
  smalltalk.addMethod(
60
- unescape('_buildOnJQuery_'),
52
+ "_on_",
61
53
  smalltalk.method({
62
- selector: unescape('buildOnJQuery%3A'),
63
- fn: function (aJQuery){
54
+ selector: "on:",
55
+ fn: function (aClass){
64
56
  var self=this;
65
- smalltalk.send(self, "_buildOn_", [smalltalk.send((smalltalk.HTMLCanvas || HTMLCanvas), "_onJQuery_", [aJQuery])]);
57
+ return (function($rec){smalltalk.send($rec, "_theClass_", [aClass]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
66
58
  return self;}
67
59
  }),
68
- smalltalk.DocumentationBuilder);
60
+ smalltalk.ClassSelectionAnnouncement.klass);
69
61
 
62
+
63
+ smalltalk.addClass('DocChapter', smalltalk.Widget, ['title', 'contents', 'parent'], 'Documentation');
70
64
  smalltalk.addMethod(
71
- unescape('_build'),
65
+ "_announcer",
72
66
  smalltalk.method({
73
- selector: unescape('build'),
67
+ selector: "announcer",
74
68
  fn: function (){
75
69
  var self=this;
76
- smalltalk.send(self, "_buildOnJQuery_", [smalltalk.send("body", "_asJQuery", [])]);
70
+ return smalltalk.send(smalltalk.send((smalltalk.DocumentationBuilder || DocumentationBuilder), "_current", []), "_announcer", []);
77
71
  return self;}
78
72
  }),
79
- smalltalk.DocumentationBuilder);
73
+ smalltalk.DocChapter);
80
74
 
81
75
  smalltalk.addMethod(
82
- unescape('_ch1introduction'),
76
+ "_chapters",
83
77
  smalltalk.method({
84
- selector: unescape('ch1introduction'),
78
+ selector: "chapters",
85
79
  fn: function (){
86
80
  var self=this;
87
- return (function($rec){smalltalk.send($rec, "_title_", ["Introduction"]);return smalltalk.send($rec, "_contents_", [unescape("%0A%0A%23%23Amber%20Smalltalk%20in%20a%20nutshell%0A%0AAmber%20is%20an%20implementation%20of%20the%20Smalltalk-80%20language.%20It%20is%20designed%20to%20make%20client-side%20web%20development%20**faster%2C%20easier%20and%20more%20fun**%20as%20it%20allows%20developers%20to%20write%20HTML5%20applications%20in%20a%20live%20Smalltalk%20environment%21%0A%0AAmber%20is%20written%20in%20itself%2C%20including%20the%20IDE%20and%20the%20compiler%20and%20it%20runs%20**directly%20inside%20your%20browser**.%20The%20IDE%20is%20fairly%20complete%20with%20a%20class%20browser%2C%20workspace%2C%20transcript%2C%20unit%20test%20runner%2C%20object%20inspectors%2C%20cross%20reference%20tools%20and%20even%20a%20debugger.%0A%0ANoteworthy%20features%3A%0A%0A-%20Amber%20is%20semantically%20and%20syntactically%20very%20close%20to%20%5BPharo%20Smalltalk%5D%28http%3A//www.pharo-project.org%29.%20Pharo%20is%20considered%20the%20reference%20implementation.%0A-%20Amber%20**seamlessly%20interacts%20with%20JavaScript**%20and%20can%20use%20its%20full%20eco%20system%20of%20libraries%20without%20any%20glue%20code%20needed.%0A-%20Amber%20**has%20no%20dependencies**%20and%20can%20be%20used%20in%20any%20JavaScript%20runtime%2C%20not%20only%20inside%20browsers.%20An%20important%20example%20is%20%5BNode.js%5D%28http%3A//nodejs.org%29.%0A-%20Amber%20is%20a%20live%20Smalltalk%20that%20**compiles%20incrementally%20into%20efficient%20JavaScript**%20often%20mapping%20one-to-one%20with%20JavaScript%20equivalents.%0A-%20Amber%20has%20a%20**Seaside%20influenced%20canvas%20library**%20to%20dynamically%20generate%20HTML.%0A%0A%23%23%20Arguments%20for%20using%20Amber%0AIn%20our%20humble%20opinion%20the%20main%20arguments%20for%20using%20Amber%20are%3A%0A%0A-%20JavaScript%20is%20quite%20a%20broken%20language%20with%20lots%20of%20traps%20and%20odd%20quirks.%20It%20is%20the%20assembler%20of%20the%20Internet%20which%20is%20cool%2C%20but%20we%20don%27t%20want%20to%20write%20in%20it.%0A-%20Smalltalk%20as%20a%20language%20is%20immensely%20cleaner%20and%20more%20mature%2C%20both%20syntactically%20and%20semantically.%0A-%20Smalltalk%20has%20a%20simple%20class%20model%20with%20a%20lightweight%20syntax%20for%20closures%2C%20it%20is%20in%20many%20ways%20a%20perfect%20match%20for%20the%20Good%20Parts%20of%20JavaScript.%0A-%20Having%20a%20true%20live%20interactive%20incremental%20development%20environment%20where%20you%20can%20build%20your%20application%20directly%20in%20the%20browser%20is%20unbeatable.%0A%0A%23%23%20Disclaimer%0A%0AThis%20documentation%20doesn%27t%20aim%20to%20teach%20Smalltalk.%20%0AKnowledge%20of%20Smalltalk%20is%20needed%20to%20understand%20the%20topics%20covered%20in%20this%20documentation.%20%0AIf%20you%20want%20to%20learn%20the%20Smalltalk%20language%2C%20you%20can%20read%20the%20excellent%20%5BPharo%20By%20Example%5D%28http%3A//www.pharobyexample.org%29%20book.%0A")]);})(smalltalk.send((smalltalk.DocChapter || DocChapter), "_new", []));
81
+ return [];
88
82
  return self;}
89
83
  }),
90
- smalltalk.DocumentationBuilder);
84
+ smalltalk.DocChapter);
91
85
 
92
86
  smalltalk.addMethod(
93
- unescape('_ch2differencesWithOtherSmalltalks'),
87
+ "_contents",
94
88
  smalltalk.method({
95
- selector: unescape('ch2differencesWithOtherSmalltalks'),
89
+ selector: "contents",
96
90
  fn: function (){
97
91
  var self=this;
98
- return (function($rec){smalltalk.send($rec, "_title_", ["Differences with other Smalltalks"]);return smalltalk.send($rec, "_contents_", [unescape("%0AAmber%20has%20some%20differences%20with%20other%20Smalltalk%20implementations.%20This%20makes%20porting%20code%20a%20non-trivial%20thing%2C%20but%20still%20quite%20manageable.%0ABecause%20it%20maps%20Smalltalk%20constructs%20one-to-one%20with%20the%20JavaScript%20equivalent%2C%20including%20Smalltalk%20classes%20to%20JavaScript%20constructors%2C%20the%20core%20class%20library%20is%20simplified%20compared%20to%20Pharo%20Smalltalk.%0AAnd%20since%20we%20want%20Amber%20to%20be%20useful%20in%20building%20lean%20browser%20apps%20we%20can%27t%20let%20it%20bloat%20too%20much.%0A%0ABut%20apart%20from%20missing%20things%20other%20Smalltalks%20may%20have%2C%20there%20are%20also%20things%20that%20are%20plain%20different%3A%0A%0A-%20The%20collection%20class%20hierarchy%20is%20much%20simpler%20compared%20to%20most%20Smalltalk%20implementations.%20In%20part%20this%20is%20because%20we%20want%20to%20map%20reasonably%20well%20with%20JavaScript%20counter%20parts.%0A-%20As%20of%20today%2C%20there%20is%20no%20SortedCollection.%20The%20size%20of%20arrays%20is%20dynamic%2C%20and%20they%20behave%20like%20an%20ordered%20collection.%20They%20can%20also%20be%20sorted%20with%20the%20%60%23sort*%60%20methods.%0A-%20The%20%60Date%60%20class%20behaves%20like%20the%20%60Date%60%20and%20%60TimeStamp%60%20classes%20in%20Pharo%20Smalltalk.%20Therefore%20both%20%60Date%20today%60%20and%20%60Date%20now%60%20are%20valid%20in%20Amber.%0A-%20Amber%20does%20not%20have%20class%20Character%2C%20but%20%60String%60%20does%20implement%20some%20of%20Character%20behavior%20so%20a%20single%20character%20String%20can%20work%20as%20a%20Character.%0A-%20Amber%20does%20support%20**class%20instance%20variables**%2C%20but%20not%20class%20variables.%0A-%20Amber%20only%20has%20global%20classes%20and%20packages%2C%20but%20not%20arbitrary%20objects.%20Use%20classes%20instead%20like%20%60Smalltalk%20current%60%20instead%20of%20%60Smalltalk%60%20etc.%0A-%20Amber%20does%20not%20support%20pool%20dictionaries.%0A-%20Amber%20uses%20**%3C%20...javascript%20code...%20%3E**%20to%20inline%20JavaScript%20code%20and%20does%20not%20have%20pragmas.%0A-%20Amber%20does%20not%20have%20class%20categories.%20The%20left%20side%20in%20the%20browser%20lists%20real%20Packages%2C%20but%20they%20feel%20much%20the%20same.%0A")]);})(smalltalk.send((smalltalk.DocChapter || DocChapter), "_new", []));
92
+ return (($receiver = self['@contents']) == nil || $receiver == undefined) ? (function(){return "";})() : $receiver;
99
93
  return self;}
100
94
  }),
101
- smalltalk.DocumentationBuilder);
95
+ smalltalk.DocChapter);
102
96
 
103
97
  smalltalk.addMethod(
104
- unescape('_ch3GettingStarted'),
98
+ "_contents_",
105
99
  smalltalk.method({
106
- selector: unescape('ch3GettingStarted'),
107
- fn: function (){
100
+ selector: "contents:",
101
+ fn: function (aString){
108
102
  var self=this;
109
- return (function($rec){smalltalk.send($rec, "_title_", ["Getting started"]);return smalltalk.send($rec, "_contents_", [unescape("%0ATo%20get%20started%20hacking%20in%20Amber%20you%20can%20basically%20take%20three%20routes%2C%20independent%20of%20your%20platform%3A%0A%0A1.%20Just%20**try%20it%20out%20directly**%20at%20%5Bwww.amber-lang.net%5D%28http%3A//www.amber-lang.net%29%20-%20click%20the%20**Class%20browser**%20button%20there.%20But%20you%20will%20**not%20be%20able%20to%20save%20any%20code%20you%20write**%21%20%0A%20%20%20%20Still%2C%20it%20works%20fine%20for%20looking%20at%20the%20IDE%20and%20playing%20around.%20Just%20**don%27t%20press%20F5/reload**%20-%20it%20will%20lose%20any%20code%20you%20have%20written.%0A2.%20Download%20an%20Amber%20zip-ball%2C%20install%20%5BNodejs%5D%28http%3A//www.nodejs.org%29%2C%20fire%20up%20the%20Amber%20server%20and%20then%20open%20Amber%20from%20localhost%20-%20then%20you%20**can%20save%20code**.%20Detailed%20instructions%20are%20below%21%0A3.%20Same%20as%20above%20but%20install%20git%20first%20and%20get%20a%20proper%20clone%20from%20%5Bhttp%3A//github.com/NicolasPetton/amber%5D%28http%3A//github.com/NicolasPetton/amber%29%20instead%20of%20a%20zip/tar-ball.%20%0A%20%20%20%20If%20you%20want%20to%20**contribute%20to%20Amber%20itself**%20this%20is%20really%20what%20you%20want%20to%20do.%20In%20fact%2C%20in%20most%20cases%20this%20is%20what%20you%20want%20to%20do.%20It%20requires%20installing%20git%20first%2C%20but%20it%20is%20quite%20simple%20-%20although%20we%20leave%20this%20bit%20as%20an%20%22exercise%20to%20the%20reader%22%20%3A%29%0A%0A**PLEASE%20NOTE%3A**%20Amber%20core%20developers%20use%20Linux.%20%0AWe%20do%20not%20want%20to%20introduce%20dependencies%20that%20aren%27t%20cross%20platform%20-%20but%20currently%20amberc%20%28the%20command%20line%20compiler%29%20is%20a%20bash%20script%20and%20we%20also%20use%20Makefiles%20%0A%28for%20building%20Amber%20itself%20and%20server%20side%20examples%29%20written%20on%20Linux/Unix.%20So%20using%20Windows%20is%20currently%20a%20bit%20limited%20-%20you%20can%27t%20run%20%22make%22%20in%20the%20.st%20directory%20to%20rebuild%20whole%20of%20Amber%20for%20example.%0A%20BUT...%20if%20you%20only%20want%20to%20use%20Amber%20to%20build%20web%20client%20apps%20and%20not%20really%20get%20involved%20in%20hacking%20Amber%20itself%20-%20then%20you%20should%20be%20fine%21%0A%0A%23%23%20Downloading%20Amber%0ACurrently%20you%20can%20download%20in%20zip%20or%20tar-ball%20format%2C%20either%20cutting%20edge%20or%20a%20release.%20%5BDownloads%20are%20available%20here%5D%28https%3A//github.com/NicolasPetton/amber/archives/amber%29.%20%0A%0AUnpack%20wherever%20you%20like%2C%20but%20I%20would%20rename%20the%20directory%20that%20is%20unpacked%20to%20something%20slightly%20shorter%20-%20like%20say%20%22amber%22.%20%3A%29%0AAnd%20yes%2C%20at%20this%20point%20you%20can%20double%20click%20the%20index.html%20file%20in%20the%20amber%20directory%20to%20get%20the%20IDE%20up%2C%20but%20again%2C%20**you%20will%20not%20be%20able%20to%20save%20code**.%20So%20please%20continue%20below%20%3A%29%0A%0A%23%23%20Installing%20Node.js%0A%5BNode%5D%28http%3A//www.nodejs.org%29%20%28for%20short%29%20is%20simply%20the%20V8%20Javascript%20VM%20from%20Google%20%28used%20in%20Chrome%29%20hooked%20together%20with%20some%20hard%20core%20C-libraries%20for%20doing%20%22evented%20I/O%22.%0ABasically%20it%27s%20JavaScript%20for%20the%20server%20-%20on%20asynch%20steroids.%20Amber%20runs%20fine%20in%20Node%20and%20we%20use%20it%20for%20several%20Amber%20tools%2C%20like%20amberc%20%28the%20command%20line%20Amber%20compiler%29%20or%20the%20Amber%20server%20%28see%20below%29.%20%0AThere%20are%20also%20several%20Amber-Node%20examples%20to%20look%20at%20if%20you%20want%20to%20play%20with%20running%20Amber%20programs%20server%20side.%20**In%20short%20-%20you%20really%20want%20to%20install%20Nodejs.%20%3A%29**%0A%0A-%20Installing%20Node%20on%20Linux%20can%20be%20done%20using%20your%20package%20tool%20of%20choice%20%28%60apt-get%20install%20nodejs%60%20for%20example%29%20or%20any%20other%20way%20described%20at%20%5Bthe%20download%20page%5D%28http%3A//nodejs.org/%23download%29.%0A-%20Installing%20Node%20on%20MacOS%20or%20Windows%20is%20probably%20done%20best%20by%20using%20the%20%5Binstallers%20available%20at%20Nodejs.org%5D%28http%3A//nodejs.org/%23download%29.%0A%0A%23%23%20Starting%20Amber%20server%0ANicolas%20has%20written%20a%20minimal%20webDAV%20server%20that%20is%20the%20easiest%20way%20to%20get%20up%20and%20running%20Amber%20with%20the%20ability%20to%20save%20code.%20This%20little%20server%20is%20written%20in...%20Amber%21%20%0AAnd%20it%20runs%20on%20top%20of%20Node.%20So%20to%20start%20it%20up%20serving%20your%20brand%20new%20directory%20tree%20of%20sweet%20Amber%20you%20do%3A%0A%0A%09cd%20amber%09%28or%20whatever%20you%20called%20the%20directory%20you%20unpackaged%29%0A%09./bin/server%09%28in%20windows%20you%20type%20%60node%20server%5Cserver.js%60%20instead%29%0A%0AIt%20should%20say%20it%20is%20listening%20on%20port%204000.%20If%20it%20does%2C%20hooray%21%20That%20means%20both%20Node%20and%20Amber%20are%20good.%20In%20Windows%20you%20might%20get%20a%20question%20about%20opening%20that%20port%20in%20the%20local%20firewall%20-%20yep%2C%20do%20it%21%0A%0A%23%23%20Firing%20up%20Amber%0AThe%20Amber%20IDE%20is%20written%20in...%20Amber.%20It%20uses%20%5BjQuery%5D%28http%3A//jquery.com%29%20and%20runs%20right%20in%20your%20browser%20as%20a%20...%20well%2C%20a%20web%20page.%20%0AWe%20could%20open%20it%20up%20just%20using%20a%20file%20url%20-%20but%20the%20reason%20we%20performed%20the%20previous%20steps%20is%20so%20that%20we%20can%20load%20the%20IDE%20web%20page%20from%20a%20server%20that%20can%20handle%20PUTs%20%28webDAV%29%20of%20source%20code.%20%0AAccording%20to%20web%20security%20Amber%20can%20only%20do%20PUT%20back%20to%20the%20same%20server%20it%20was%20loaded%20from.%20Thus%20we%20instead%20want%20to%20open%20it%20%5Bthrough%20our%20little%20server%20now%20listening%20on%20port%204000%5D%28http%3A//localhost%3A4000/index.html%29.%0AClicking%20that%20link%20and%20then%20pressing%20the%20**Class%20browser**%20should%20get%20your%20Amber%20IDE%20running%20with%20the%20ability%20to%20commit%20modified%20packages%20locally.%0A%0ATo%20verify%20that%20you%20can%20indeed%20commit%20now%20-%20just%20select%20a%20Package%20in%20the%20browser%2C%20like%20say%20%22Examples%22%20and%20press%20the%20**Commit**%20button%20below.%20**If%20all%20goes%20well%20nothing%20happens%20%3A%29**.%20%0ASo%20in%20order%20to%20really%20know%20if%20it%20worked%20we%20can%20check%20the%20modified%20date%20on%20the%20files%20**amber/st/Examples.st**%2C%20**amber/js/Examples.js**%20and%20**amber/js/Examples.deploy.js**%20-%20they%20should%20be%20brand%20new.%0A%0ANOTE%3A%20We%20can%20use%20any%20webDAV%20server%20and%20Apache2%20has%20been%20used%20earlier%20and%20works%20fine.%20But%20the%20Amber%20server%20is%20smaller%20and%20simpler%20to%20start.%0A")]);})(smalltalk.send((smalltalk.DocChapter || DocChapter), "_new", []));
103
+ (self['@contents']=aString);
110
104
  return self;}
111
105
  }),
112
- smalltalk.DocumentationBuilder);
106
+ smalltalk.DocChapter);
113
107
 
114
108
  smalltalk.addMethod(
115
- unescape('_ch5Index'),
109
+ "_cssClass",
116
110
  smalltalk.method({
117
- selector: unescape('ch5Index'),
111
+ selector: "cssClass",
118
112
  fn: function (){
119
113
  var self=this;
120
- return smalltalk.send((smalltalk.ClassesIndexChapter || ClassesIndexChapter), "_new", []);
114
+ return "doc_chapter";
121
115
  return self;}
122
116
  }),
123
- smalltalk.DocumentationBuilder);
117
+ smalltalk.DocChapter);
124
118
 
125
119
  smalltalk.addMethod(
126
- unescape('_ch6KernelObjects'),
120
+ "_displayChapter_",
127
121
  smalltalk.method({
128
- selector: unescape('ch6KernelObjects'),
129
- fn: function (){
122
+ selector: "displayChapter:",
123
+ fn: function (aChapter){
130
124
  var self=this;
131
- return smalltalk.send((smalltalk.PackageDocChapter || PackageDocChapter), "_on_", [smalltalk.send((smalltalk.Package || Package), "_named_", [unescape("Kernel-Objects")])]);
125
+ smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.DocumentationBuilder || DocumentationBuilder), "_current", []), "_widget", []), "_displayChapter_", [aChapter]);
132
126
  return self;}
133
127
  }),
134
- smalltalk.DocumentationBuilder);
128
+ smalltalk.DocChapter);
135
129
 
136
130
  smalltalk.addMethod(
137
- unescape('_ch7KernelClasses'),
131
+ "_htmlContents",
138
132
  smalltalk.method({
139
- selector: unescape('ch7KernelClasses'),
133
+ selector: "htmlContents",
140
134
  fn: function (){
141
135
  var self=this;
142
- return smalltalk.send((smalltalk.PackageDocChapter || PackageDocChapter), "_on_", [smalltalk.send((smalltalk.Package || Package), "_named_", [unescape("Kernel-Classes")])]);
136
+ return smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Showdown || Showdown), "_at_", [smalltalk.symbolFor("converter")]), "_new", []), "_makeHtml_", [smalltalk.send(self, "_contents", [])]);
143
137
  return self;}
144
138
  }),
145
- smalltalk.DocumentationBuilder);
139
+ smalltalk.DocChapter);
146
140
 
147
141
  smalltalk.addMethod(
148
- unescape('_ch4Tutorials'),
142
+ "_id",
149
143
  smalltalk.method({
150
- selector: unescape('ch4Tutorials'),
144
+ selector: "id",
151
145
  fn: function (){
152
146
  var self=this;
153
- return smalltalk.send((smalltalk.TutorialsChapter || TutorialsChapter), "_new", []);
147
+ return smalltalk.send(smalltalk.send(self, "_title", []), "_replace_with_", [" ", "-"]);
154
148
  return self;}
155
149
  }),
156
- smalltalk.DocumentationBuilder);
150
+ smalltalk.DocChapter);
157
151
 
158
152
  smalltalk.addMethod(
159
- unescape('_checkHashChange'),
153
+ "_initialize",
160
154
  smalltalk.method({
161
- selector: unescape('checkHashChange'),
155
+ selector: "initialize",
162
156
  fn: function (){
163
157
  var self=this;
164
- smalltalk.send(smalltalk.send((typeof window == 'undefined' ? nil : window), "_jQuery_", [(typeof window == 'undefined' ? nil : window)]), "_bind_do_", ["hashchange", (function(){return smalltalk.send(self, "_checkHash", []);})]);
158
+ smalltalk.send(self, "_initialize", [], smalltalk.DocChapter.superclass || nil);
159
+ smalltalk.send(self, "_subscribe", []);
165
160
  return self;}
166
161
  }),
167
- smalltalk.DocumentationBuilder);
162
+ smalltalk.DocChapter);
168
163
 
169
164
  smalltalk.addMethod(
170
- unescape('_checkHash'),
165
+ "_level",
171
166
  smalltalk.method({
172
- selector: unescape('checkHash'),
167
+ selector: "level",
173
168
  fn: function (){
174
169
  var self=this;
175
- var hash=nil;
176
- var presentation=nil;
177
- (hash=smalltalk.send(smalltalk.send(smalltalk.send((typeof document == 'undefined' ? nil : document), "_location", []), "_hash", []), "_replace_with_", [unescape("%5E%23"), ""]));
178
- smalltalk.send(smalltalk.send(self, "_announcer", []), "_announce_", [(function($rec){smalltalk.send($rec, "_id_", [hash]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.ChapterSelectionAnnouncement || ChapterSelectionAnnouncement), "_new", []))]);
170
+ return (($receiver = smalltalk.send(self, "_parent", [])) == nil || $receiver == undefined) ? (function(){return (1);})() : (function(){return ((($receiver = smalltalk.send(smalltalk.send(self, "_parent", []), "_level", [])).klass === smalltalk.Number) ? $receiver +(1) : smalltalk.send($receiver, "__plus", [(1)]));})();
179
171
  return self;}
180
172
  }),
181
- smalltalk.DocumentationBuilder);
173
+ smalltalk.DocChapter);
182
174
 
183
175
  smalltalk.addMethod(
184
- unescape('_update'),
176
+ "_level_",
185
177
  smalltalk.method({
186
- selector: unescape('update'),
187
- fn: function (){
178
+ selector: "level:",
179
+ fn: function (anInteger){
188
180
  var self=this;
189
- (self['@chapters']=nil);
190
- (self['@announcer']=nil);
191
- (self['@widget']=nil);
192
- smalltalk.send(smalltalk.send((typeof window == 'undefined' ? nil : window), "_jQuery_", [".documentation"]), "_remove", []);
193
- smalltalk.send(self, "_build", []);
181
+ (level=anInteger);
194
182
  return self;}
195
183
  }),
196
- smalltalk.DocumentationBuilder);
184
+ smalltalk.DocChapter);
197
185
 
198
186
  smalltalk.addMethod(
199
- unescape('_ch8KernelCollection'),
187
+ "_parent",
200
188
  smalltalk.method({
201
- selector: unescape('ch8KernelCollection'),
189
+ selector: "parent",
202
190
  fn: function (){
203
191
  var self=this;
204
- return smalltalk.send((smalltalk.PackageDocChapter || PackageDocChapter), "_on_", [smalltalk.send((smalltalk.Package || Package), "_named_", [unescape("Kernel-Collections")])]);
192
+ return self['@parent'];
205
193
  return self;}
206
194
  }),
207
- smalltalk.DocumentationBuilder);
195
+ smalltalk.DocChapter);
208
196
 
209
197
  smalltalk.addMethod(
210
- unescape('_ch9KernelMethods'),
198
+ "_parent_",
211
199
  smalltalk.method({
212
- selector: unescape('ch9KernelMethods'),
213
- fn: function (){
200
+ selector: "parent:",
201
+ fn: function (aChapter){
214
202
  var self=this;
215
- return smalltalk.send((smalltalk.PackageDocChapter || PackageDocChapter), "_on_", [smalltalk.send((smalltalk.Package || Package), "_named_", [unescape("Kernel-Methods")])]);
203
+ (self['@parent']=aChapter);
216
204
  return self;}
217
205
  }),
218
- smalltalk.DocumentationBuilder);
219
-
206
+ smalltalk.DocChapter);
220
207
 
221
- smalltalk.DocumentationBuilder.klass.iVarNames = ['current'];
222
208
  smalltalk.addMethod(
223
- unescape('_current'),
209
+ "_renderDocOn_",
224
210
  smalltalk.method({
225
- selector: unescape('current'),
226
- fn: function (){
211
+ selector: "renderDocOn:",
212
+ fn: function (html){
227
213
  var self=this;
228
- return (($receiver = self['@current']) == nil || $receiver == undefined) ? (function(){return (self['@current']=smalltalk.send(self, "_new", []));})() : $receiver;
214
+ var div=nil;
215
+ smalltalk.send(smalltalk.send(html, "_h1", []), "_with_", [smalltalk.send(self, "_title", [])]);
216
+ smalltalk.send(self, "_renderNavigationOn_", [html]);
217
+ (div=smalltalk.send(smalltalk.send(html, "_div", []), "_class_", ["contents"]));
218
+ smalltalk.send(smalltalk.send(div, "_asJQuery", []), "_html_", [smalltalk.send(self, "_htmlContents", [])]);
229
219
  return self;}
230
220
  }),
231
- smalltalk.DocumentationBuilder.klass);
221
+ smalltalk.DocChapter);
232
222
 
233
223
  smalltalk.addMethod(
234
- unescape('_initialize'),
224
+ "_renderLinksOn_",
235
225
  smalltalk.method({
236
- selector: unescape('initialize'),
237
- fn: function (){
226
+ selector: "renderLinksOn:",
227
+ fn: function (html){
238
228
  var self=this;
239
- smalltalk.send(smalltalk.send(self, "_current", []), "_build", []);
229
+ (function($rec){smalltalk.send($rec, "_class_", ["links"]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(smalltalk.send(self, "_chapters", []), "_do_", [(function(each){return smalltalk.send(smalltalk.send(html, "_li", []), "_with_", [(function(){return (function($rec){smalltalk.send($rec, "_with_", [smalltalk.send(each, "_title", [])]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_selectChapter_", [each]);})]);})(smalltalk.send(html, "_a", []));})]);})]);})]);})(smalltalk.send(html, "_ul", []));
240
230
  return self;}
241
231
  }),
242
- smalltalk.DocumentationBuilder.klass);
243
-
232
+ smalltalk.DocChapter);
244
233
 
245
- smalltalk.addClass('DocChapter', smalltalk.Widget, ['title', 'contents', 'parent'], 'Documentation');
246
234
  smalltalk.addMethod(
247
- unescape('_title'),
235
+ "_renderNavigationOn_",
248
236
  smalltalk.method({
249
- selector: unescape('title'),
250
- fn: function (){
237
+ selector: "renderNavigationOn:",
238
+ fn: function (html){
251
239
  var self=this;
252
- return (($receiver = self['@title']) == nil || $receiver == undefined) ? (function(){return "";})() : $receiver;
240
+ (($receiver = smalltalk.send(self, "_parent", [])) != nil && $receiver != undefined) ? (function(){return (function($rec){smalltalk.send($rec, "_class_", ["navigation"]);return smalltalk.send($rec, "_with_", [(function(){return (function($rec){smalltalk.send($rec, "_with_", [smalltalk.send("← back to ", "__comma", [smalltalk.send(smalltalk.send(self, "_parent", []), "_title", [])])]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_selectChapter_", [smalltalk.send(self, "_parent", [])]);})]);})(smalltalk.send(html, "_a", []));})]);})(smalltalk.send(html, "_div", []));})() : nil;
253
241
  return self;}
254
242
  }),
255
243
  smalltalk.DocChapter);
256
244
 
257
245
  smalltalk.addMethod(
258
- unescape('_title_'),
246
+ "_renderOn_",
259
247
  smalltalk.method({
260
- selector: unescape('title%3A'),
261
- fn: function (aString){
248
+ selector: "renderOn:",
249
+ fn: function (html){
262
250
  var self=this;
263
- (self['@title']=aString);
251
+ (function($rec){smalltalk.send($rec, "_class_", [smalltalk.send(self, "_cssClass", [])]);return smalltalk.send($rec, "_with_", [(function(){smalltalk.send(self, "_renderDocOn_", [html]);return smalltalk.send(self, "_renderLinksOn_", [html]);})]);})(smalltalk.send(html, "_div", []));
264
252
  return self;}
265
253
  }),
266
254
  smalltalk.DocChapter);
267
255
 
268
256
  smalltalk.addMethod(
269
- unescape('_contents'),
257
+ "_selectChapter_",
270
258
  smalltalk.method({
271
- selector: unescape('contents'),
272
- fn: function (){
259
+ selector: "selectChapter:",
260
+ fn: function (aChapter){
273
261
  var self=this;
274
- return (($receiver = self['@contents']) == nil || $receiver == undefined) ? (function(){return "";})() : $receiver;
262
+ smalltalk.send(smalltalk.send((typeof document == 'undefined' ? nil : document), "_location", []), "_hash_", [smalltalk.send(aChapter, "_id", [])]);
275
263
  return self;}
276
264
  }),
277
265
  smalltalk.DocChapter);
278
266
 
279
267
  smalltalk.addMethod(
280
- unescape('_contents_'),
268
+ "_selectClass_",
281
269
  smalltalk.method({
282
- selector: unescape('contents%3A'),
283
- fn: function (aString){
270
+ selector: "selectClass:",
271
+ fn: function (aClass){
284
272
  var self=this;
285
- (self['@contents']=aString);
273
+ smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.DocumentationBuilder || DocumentationBuilder), "_current", []), "_announcer", []), "_announce_", [smalltalk.send((smalltalk.ClassSelectionAnnouncement || ClassSelectionAnnouncement), "_on_", [aClass])]);
286
274
  return self;}
287
275
  }),
288
276
  smalltalk.DocChapter);
289
277
 
290
278
  smalltalk.addMethod(
291
- unescape('_htmlContents'),
279
+ "_subscribe",
292
280
  smalltalk.method({
293
- selector: unescape('htmlContents'),
281
+ selector: "subscribe",
294
282
  fn: function (){
295
283
  var self=this;
296
- return smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Showdown || Showdown), "_at_", [smalltalk.symbolFor("converter")]), "_new", []), "_makeHtml_", [smalltalk.send(self, "_contents", [])]);
284
+ smalltalk.send(smalltalk.send(self, "_announcer", []), "_on_do_", [(smalltalk.ChapterSelectionAnnouncement || ChapterSelectionAnnouncement), (function(ann){return ((($receiver = smalltalk.send(smalltalk.send(ann, "_id", []), "__eq", [smalltalk.send(self, "_id", [])])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_displayChapter_", [self]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_displayChapter_", [self]);})]));})]);
297
285
  return self;}
298
286
  }),
299
287
  smalltalk.DocChapter);
300
288
 
301
289
  smalltalk.addMethod(
302
- unescape('_chapters'),
290
+ "_title",
303
291
  smalltalk.method({
304
- selector: unescape('chapters'),
292
+ selector: "title",
305
293
  fn: function (){
306
294
  var self=this;
307
- return [];
295
+ return (($receiver = self['@title']) == nil || $receiver == undefined) ? (function(){return "";})() : $receiver;
308
296
  return self;}
309
297
  }),
310
298
  smalltalk.DocChapter);
311
299
 
312
300
  smalltalk.addMethod(
313
- unescape('_cssClass'),
301
+ "_title_",
314
302
  smalltalk.method({
315
- selector: unescape('cssClass'),
316
- fn: function (){
303
+ selector: "title:",
304
+ fn: function (aString){
317
305
  var self=this;
318
- return "doc_chapter";
306
+ (self['@title']=aString);
319
307
  return self;}
320
308
  }),
321
309
  smalltalk.DocChapter);
322
310
 
311
+
312
+
313
+ smalltalk.addClass('ClassDocChapter', smalltalk.DocChapter, ['theClass'], 'Documentation');
323
314
  smalltalk.addMethod(
324
- unescape('_level'),
315
+ "_contents",
325
316
  smalltalk.method({
326
- selector: unescape('level'),
317
+ selector: "contents",
327
318
  fn: function (){
328
319
  var self=this;
329
- return (($receiver = smalltalk.send(self, "_parent", [])) == nil || $receiver == undefined) ? (function(){return (1);})() : (function(){return ((($receiver = smalltalk.send(smalltalk.send(self, "_parent", []), "_level", [])).klass === smalltalk.Number) ? $receiver +(1) : smalltalk.send($receiver, "__plus", [(1)]));})();
320
+ return ((($receiver = smalltalk.send(smalltalk.send(smalltalk.send(self, "_theClass", []), "_comment", []), "_isEmpty", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(smalltalk.send(self, "_theClass", []), "_name", []), "__comma", [" is not documented yet."]);})() : (function(){return smalltalk.send(smalltalk.send(self, "_theClass", []), "_comment", []);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(smalltalk.send(self, "_theClass", []), "_name", []), "__comma", [" is not documented yet."]);}), (function(){return smalltalk.send(smalltalk.send(self, "_theClass", []), "_comment", []);})]));
330
321
  return self;}
331
322
  }),
332
- smalltalk.DocChapter);
323
+ smalltalk.ClassDocChapter);
333
324
 
334
325
  smalltalk.addMethod(
335
- unescape('_level_'),
326
+ "_cssClass",
336
327
  smalltalk.method({
337
- selector: unescape('level%3A'),
338
- fn: function (anInteger){
328
+ selector: "cssClass",
329
+ fn: function (){
339
330
  var self=this;
340
- (level=anInteger);
331
+ return smalltalk.send("doc_class ", "__comma", [smalltalk.send(self, "_cssClass", [], smalltalk.ClassDocChapter.superclass || nil)]);
341
332
  return self;}
342
333
  }),
343
- smalltalk.DocChapter);
334
+ smalltalk.ClassDocChapter);
344
335
 
345
336
  smalltalk.addMethod(
346
- unescape('_parent'),
337
+ "_initializeWithClass_",
347
338
  smalltalk.method({
348
- selector: unescape('parent'),
349
- fn: function (){
339
+ selector: "initializeWithClass:",
340
+ fn: function (aClass){
350
341
  var self=this;
351
- return self['@parent'];
342
+ (self['@theClass']=aClass);
352
343
  return self;}
353
344
  }),
354
- smalltalk.DocChapter);
345
+ smalltalk.ClassDocChapter);
355
346
 
356
347
  smalltalk.addMethod(
357
- unescape('_parent_'),
348
+ "_renderLinksOn_",
358
349
  smalltalk.method({
359
- selector: unescape('parent%3A'),
360
- fn: function (aChapter){
350
+ selector: "renderLinksOn:",
351
+ fn: function (html){
361
352
  var self=this;
362
- (self['@parent']=aChapter);
353
+ (function($rec){smalltalk.send($rec, "_class_", ["links"]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(smalltalk.send(html, "_li", []), "_with_", [(function(){return (function($rec){smalltalk.send($rec, "_with_", ["Browse this class"]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send((smalltalk.Browser || Browser), "_openOn_", [smalltalk.send(self, "_theClass", [])]);})]);})(smalltalk.send(html, "_a", []));})]);})]);})(smalltalk.send(html, "_ul", []));
363
354
  return self;}
364
355
  }),
365
- smalltalk.DocChapter);
356
+ smalltalk.ClassDocChapter);
366
357
 
367
358
  smalltalk.addMethod(
368
- unescape('_id'),
359
+ "_subscribe",
369
360
  smalltalk.method({
370
- selector: unescape('id'),
361
+ selector: "subscribe",
371
362
  fn: function (){
372
363
  var self=this;
373
- return smalltalk.send(smalltalk.send(self, "_title", []), "_replace_with_", [" ", unescape("-")]);
364
+ smalltalk.send(self, "_subscribe", [], smalltalk.ClassDocChapter.superclass || nil);
365
+ smalltalk.send(smalltalk.send(self, "_announcer", []), "_on_do_", [(smalltalk.ClassSelectionAnnouncement || ClassSelectionAnnouncement), (function(ann){return ((($receiver = smalltalk.send(smalltalk.send(ann, "_theClass", []), "__eq", [smalltalk.send(self, "_theClass", [])])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_selectChapter_", [self]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_selectChapter_", [self]);})]));})]);
374
366
  return self;}
375
367
  }),
376
- smalltalk.DocChapter);
368
+ smalltalk.ClassDocChapter);
377
369
 
378
370
  smalltalk.addMethod(
379
- unescape('_announcer'),
371
+ "_theClass",
380
372
  smalltalk.method({
381
- selector: unescape('announcer'),
373
+ selector: "theClass",
382
374
  fn: function (){
383
375
  var self=this;
384
- return smalltalk.send(smalltalk.send((smalltalk.DocumentationBuilder || DocumentationBuilder), "_current", []), "_announcer", []);
376
+ return self['@theClass'];
385
377
  return self;}
386
378
  }),
387
- smalltalk.DocChapter);
379
+ smalltalk.ClassDocChapter);
388
380
 
389
381
  smalltalk.addMethod(
390
- unescape('_selectClass_'),
382
+ "_title",
391
383
  smalltalk.method({
392
- selector: unescape('selectClass%3A'),
393
- fn: function (aClass){
384
+ selector: "title",
385
+ fn: function (){
394
386
  var self=this;
395
- smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.DocumentationBuilder || DocumentationBuilder), "_current", []), "_announcer", []), "_announce_", [smalltalk.send((smalltalk.ClassSelectionAnnouncement || ClassSelectionAnnouncement), "_on_", [aClass])]);
387
+ return smalltalk.send(smalltalk.send(self, "_theClass", []), "_name", []);
396
388
  return self;}
397
389
  }),
398
- smalltalk.DocChapter);
390
+ smalltalk.ClassDocChapter);
391
+
399
392
 
400
393
  smalltalk.addMethod(
401
- unescape('_selectChapter_'),
394
+ "_on_",
402
395
  smalltalk.method({
403
- selector: unescape('selectChapter%3A'),
404
- fn: function (aChapter){
396
+ selector: "on:",
397
+ fn: function (aClass){
405
398
  var self=this;
406
- smalltalk.send(smalltalk.send((typeof document == 'undefined' ? nil : document), "_location", []), "_hash_", [smalltalk.send(aChapter, "_id", [])]);
399
+ return (function($rec){smalltalk.send($rec, "_initializeWithClass_", [aClass]);smalltalk.send($rec, "_initialize", []);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_basicNew", []));
407
400
  return self;}
408
401
  }),
409
- smalltalk.DocChapter);
402
+ smalltalk.ClassDocChapter.klass);
403
+
410
404
 
405
+ smalltalk.addClass('ClassesIndexChapter', smalltalk.DocChapter, [], 'Documentation');
411
406
  smalltalk.addMethod(
412
- unescape('_displayChapter_'),
407
+ "_alphabet",
413
408
  smalltalk.method({
414
- selector: unescape('displayChapter%3A'),
415
- fn: function (aChapter){
409
+ selector: "alphabet",
410
+ fn: function (){
416
411
  var self=this;
417
- smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.DocumentationBuilder || DocumentationBuilder), "_current", []), "_widget", []), "_displayChapter_", [aChapter]);
412
+ return "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
418
413
  return self;}
419
414
  }),
420
- smalltalk.DocChapter);
415
+ smalltalk.ClassesIndexChapter);
421
416
 
422
417
  smalltalk.addMethod(
423
- unescape('_initialize'),
418
+ "_cssClass",
424
419
  smalltalk.method({
425
- selector: unescape('initialize'),
420
+ selector: "cssClass",
426
421
  fn: function (){
427
422
  var self=this;
428
- smalltalk.send(self, "_initialize", [], smalltalk.Widget);
429
- smalltalk.send(self, "_subscribe", []);
423
+ return smalltalk.send("index_doc ", "__comma", [smalltalk.send(self, "_cssClass", [], smalltalk.ClassesIndexChapter.superclass || nil)]);
430
424
  return self;}
431
425
  }),
432
- smalltalk.DocChapter);
426
+ smalltalk.ClassesIndexChapter);
433
427
 
434
428
  smalltalk.addMethod(
435
- unescape('_renderOn_'),
429
+ "_renderDocOn_",
436
430
  smalltalk.method({
437
- selector: unescape('renderOn%3A'),
431
+ selector: "renderDocOn:",
438
432
  fn: function (html){
439
433
  var self=this;
440
- (function($rec){smalltalk.send($rec, "_class_", [smalltalk.send(self, "_cssClass", [])]);return smalltalk.send($rec, "_with_", [(function(){smalltalk.send(self, "_renderDocOn_", [html]);return smalltalk.send(self, "_renderLinksOn_", [html]);})]);})(smalltalk.send(html, "_div", []));
434
+ smalltalk.send(smalltalk.send(html, "_h1", []), "_with_", [smalltalk.send(self, "_title", [])]);
435
+ smalltalk.send(smalltalk.send(self, "_alphabet", []), "_do_", [(function(letter){var classes=nil;
436
+ (classes=smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_classes", []), "_select_", [(function(each){return smalltalk.send(smalltalk.send(smalltalk.send(each, "_name", []), "_first", []), "__eq", [letter]);})]));smalltalk.send(classes, "_ifNotEmpty_", [(function(){return smalltalk.send(smalltalk.send(html, "_h2", []), "_with_", [letter]);})]);return smalltalk.send(smalltalk.send(html, "_ul", []), "_with_", [(function(){return smalltalk.send(smalltalk.send(classes, "_sorted_", [(function(a, b){return ((($receiver = smalltalk.send(a, "_name", [])).klass === smalltalk.Number) ? $receiver <smalltalk.send(b, "_name", []) : smalltalk.send($receiver, "__lt", [smalltalk.send(b, "_name", [])]));})]), "_do_", [(function(each){return smalltalk.send(smalltalk.send(html, "_li", []), "_with_", [(function(){return (function($rec){smalltalk.send($rec, "_with_", [smalltalk.send(each, "_name", [])]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_selectClass_", [each]);})]);})(smalltalk.send(html, "_a", []));})]);})]);})]);})]);
441
437
  return self;}
442
438
  }),
443
- smalltalk.DocChapter);
439
+ smalltalk.ClassesIndexChapter);
444
440
 
445
441
  smalltalk.addMethod(
446
- unescape('_renderDocOn_'),
442
+ "_title",
447
443
  smalltalk.method({
448
- selector: unescape('renderDocOn%3A'),
449
- fn: function (html){
444
+ selector: "title",
445
+ fn: function (){
450
446
  var self=this;
451
- var div=nil;
452
- smalltalk.send(smalltalk.send(html, "_h1", []), "_with_", [smalltalk.send(self, "_title", [])]);
453
- smalltalk.send(self, "_renderNavigationOn_", [html]);
454
- (div=smalltalk.send(smalltalk.send(html, "_div", []), "_class_", ["contents"]));
455
- smalltalk.send(smalltalk.send(div, "_asJQuery", []), "_html_", [smalltalk.send(self, "_htmlContents", [])]);
447
+ return "Smalltalk classes by index";
456
448
  return self;}
457
449
  }),
458
- smalltalk.DocChapter);
450
+ smalltalk.ClassesIndexChapter);
451
+
459
452
 
453
+
454
+ smalltalk.addClass('PackageDocChapter', smalltalk.DocChapter, ['package', 'chapters'], 'Documentation');
460
455
  smalltalk.addMethod(
461
- unescape('_renderNavigationOn_'),
456
+ "_chapters",
462
457
  smalltalk.method({
463
- selector: unescape('renderNavigationOn%3A'),
464
- fn: function (html){
458
+ selector: "chapters",
459
+ fn: function (){
465
460
  var self=this;
466
- (($receiver = smalltalk.send(self, "_parent", [])) != nil && $receiver != undefined) ? (function(){return (function($rec){smalltalk.send($rec, "_class_", ["navigation"]);return smalltalk.send($rec, "_with_", [(function(){return (function($rec){smalltalk.send($rec, "_with_", [smalltalk.send(unescape("%u2190%20back%20to%20"), "__comma", [smalltalk.send(smalltalk.send(self, "_parent", []), "_title", [])])]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_selectChapter_", [smalltalk.send(self, "_parent", [])]);})]);})(smalltalk.send(html, "_a", []));})]);})(smalltalk.send(html, "_div", []));})() : nil;
461
+ return self['@chapters'];
467
462
  return self;}
468
463
  }),
469
- smalltalk.DocChapter);
464
+ smalltalk.PackageDocChapter);
470
465
 
471
466
  smalltalk.addMethod(
472
- unescape('_renderLinksOn_'),
467
+ "_contents",
473
468
  smalltalk.method({
474
- selector: unescape('renderLinksOn%3A'),
475
- fn: function (html){
469
+ selector: "contents",
470
+ fn: function (){
476
471
  var self=this;
477
- (function($rec){smalltalk.send($rec, "_class_", ["links"]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(smalltalk.send(self, "_chapters", []), "_do_", [(function(each){return smalltalk.send(smalltalk.send(html, "_li", []), "_with_", [(function(){return (function($rec){smalltalk.send($rec, "_with_", [smalltalk.send(each, "_title", [])]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_selectChapter_", [each]);})]);})(smalltalk.send(html, "_a", []));})]);})]);})]);})(smalltalk.send(html, "_ul", []));
472
+ return smalltalk.send(smalltalk.send("Classes in package ", "__comma", [smalltalk.send(smalltalk.send(self, "_package", []), "_name", [])]), "__comma", [":"]);
478
473
  return self;}
479
474
  }),
480
- smalltalk.DocChapter);
475
+ smalltalk.PackageDocChapter);
481
476
 
482
477
  smalltalk.addMethod(
483
- unescape('_subscribe'),
478
+ "_initializeWithPackage_",
484
479
  smalltalk.method({
485
- selector: unescape('subscribe'),
486
- fn: function (){
480
+ selector: "initializeWithPackage:",
481
+ fn: function (aPackage){
487
482
  var self=this;
488
- smalltalk.send(smalltalk.send(self, "_announcer", []), "_on_do_", [(smalltalk.ChapterSelectionAnnouncement || ChapterSelectionAnnouncement), (function(ann){return ((($receiver = smalltalk.send(smalltalk.send(ann, "_id", []), "__eq", [smalltalk.send(self, "_id", [])])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_displayChapter_", [self]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_displayChapter_", [self]);})]));})]);
483
+ (self['@package']=aPackage);
484
+ (self['@chapters']=smalltalk.send(smalltalk.send(smalltalk.send(aPackage, "_classes", []), "_sorted_", [(function(a, b){return ((($receiver = smalltalk.send(a, "_name", [])).klass === smalltalk.Number) ? $receiver <smalltalk.send(b, "_name", []) : smalltalk.send($receiver, "__lt", [smalltalk.send(b, "_name", [])]));})]), "_collect_", [(function(each){return (function($rec){smalltalk.send($rec, "_parent_", [self]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.ClassDocChapter || ClassDocChapter), "_on_", [each]));})]));
489
485
  return self;}
490
486
  }),
491
- smalltalk.DocChapter);
492
-
493
-
487
+ smalltalk.PackageDocChapter);
494
488
 
495
- smalltalk.addClass('PackageDocChapter', smalltalk.DocChapter, ['package', 'chapters'], 'Documentation');
496
489
  smalltalk.addMethod(
497
- unescape('_package'),
490
+ "_package",
498
491
  smalltalk.method({
499
- selector: unescape('package'),
492
+ selector: "package",
500
493
  fn: function (){
501
494
  var self=this;
502
495
  return self['@package'];
@@ -505,9 +498,9 @@ return self;}
505
498
  smalltalk.PackageDocChapter);
506
499
 
507
500
  smalltalk.addMethod(
508
- unescape('_title'),
501
+ "_title",
509
502
  smalltalk.method({
510
- selector: unescape('title'),
503
+ selector: "title",
511
504
  fn: function (){
512
505
  var self=this;
513
506
  return smalltalk.send("Package ", "__comma", [smalltalk.send(smalltalk.send(self, "_package", []), "_name", [])]);
@@ -515,447 +508,454 @@ return self;}
515
508
  }),
516
509
  smalltalk.PackageDocChapter);
517
510
 
511
+
518
512
  smalltalk.addMethod(
519
- unescape('_chapters'),
513
+ "_on_",
520
514
  smalltalk.method({
521
- selector: unescape('chapters'),
522
- fn: function (){
515
+ selector: "on:",
516
+ fn: function (aPackage){
523
517
  var self=this;
524
- return self['@chapters'];
518
+ return (function($rec){smalltalk.send($rec, "_initializeWithPackage_", [aPackage]);smalltalk.send($rec, "_initialize", []);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_basicNew", []));
525
519
  return self;}
526
520
  }),
527
- smalltalk.PackageDocChapter);
521
+ smalltalk.PackageDocChapter.klass);
522
+
528
523
 
524
+ smalltalk.addClass('TutorialsChapter', smalltalk.DocChapter, [], 'Documentation');
529
525
  smalltalk.addMethod(
530
- unescape('_contents'),
526
+ "_chapters",
531
527
  smalltalk.method({
532
- selector: unescape('contents'),
528
+ selector: "chapters",
533
529
  fn: function (){
534
530
  var self=this;
535
- return smalltalk.send(smalltalk.send("Classes in package ", "__comma", [smalltalk.send(smalltalk.send(self, "_package", []), "_name", [])]), "__comma", [":"]);
531
+ return [smalltalk.send(self, "_firstAppChapter", []),smalltalk.send(self, "_counterChapter", [])];
536
532
  return self;}
537
533
  }),
538
- smalltalk.PackageDocChapter);
534
+ smalltalk.TutorialsChapter);
539
535
 
540
536
  smalltalk.addMethod(
541
- unescape('_initializeWithPackage_'),
537
+ "_contents",
542
538
  smalltalk.method({
543
- selector: unescape('initializeWithPackage%3A'),
544
- fn: function (aPackage){
539
+ selector: "contents",
540
+ fn: function (){
545
541
  var self=this;
546
- (self['@package']=aPackage);
547
- (self['@chapters']=smalltalk.send(smalltalk.send(smalltalk.send(aPackage, "_classes", []), "_sorted_", [(function(a, b){return ((($receiver = smalltalk.send(a, "_name", [])).klass === smalltalk.Number) ? $receiver <smalltalk.send(b, "_name", []) : smalltalk.send($receiver, "__lt", [smalltalk.send(b, "_name", [])]));})]), "_collect_", [(function(each){return (function($rec){smalltalk.send($rec, "_parent_", [self]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.ClassDocChapter || ClassDocChapter), "_on_", [each]));})]));
542
+ return "Here's a serie of tutorials. If you are new to Smalltalk, you can also learn Amber online with [ProfStef](http://www.amber-lang.net/learn.html)";
548
543
  return self;}
549
544
  }),
550
- smalltalk.PackageDocChapter);
551
-
545
+ smalltalk.TutorialsChapter);
552
546
 
553
547
  smalltalk.addMethod(
554
- unescape('_on_'),
548
+ "_counterChapter",
555
549
  smalltalk.method({
556
- selector: unescape('on%3A'),
557
- fn: function (aPackage){
550
+ selector: "counterChapter",
551
+ fn: function (){
558
552
  var self=this;
559
- return (function($rec){smalltalk.send($rec, "_initializeWithPackage_", [aPackage]);smalltalk.send($rec, "_initialize", []);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_basicNew", []));
553
+ return (function($rec){smalltalk.send($rec, "_title_", ["The counter application"]);return smalltalk.send($rec, "_contents_", ["\x0a\x0aThis tutorial will teach you how to build HTML with Amber using jQuery and the HTMLCanvas API. It is freely adapted from \x0athe [Seaside counter example](http://www.seaside.st/about/examples/counter)\x0a\x0a##The counter widget\x0a\x0aThe counter is the most basic example of a widget. It allows to increment and decrement a number by clicking a button.\x0a\x0aAmber already comes with a counter example in the `Examples` package. To avoid class name conflict, we'll name our counter class `TCounter`.\x0a\x0a Widget subclass: #TCounter\x0a instanceVariableNames: 'count header'\x0a package: 'Tutorials'\x0a\x0aThe first method is used to initialize the component with the default state, in this case we set the counter to 0:\x0a\x0a initialize\x0a super initialize.\x0a count := 0\x0a\x0aThe method used for rendering a widget is `#renderOn:`. It takes an instance of HTMLCanvas as parameter. \x0aThe `header` h1 kept as an instance variable, so when the count value change, we can update it's contents accordingly.\x0a\x0a renderOn: html\x0a header := html h1 \x0a with: count asString;\x0a yourself.\x0a html button\x0a with: '++';\x0a onClick: [self increase].\x0a html button\x0a with: '--';\x0a onClick: [self decrease]\x0a\x0aThe counter is almost ready. All we need now is to implement the two action methods `#increase` and `#decrease` to change the state \x0aof our counter and update its header.\x0a\x0a increase\x0a count := count + 1.\x0a header contents: [:html | html with: count asString]\x0a\x0a decrease\x0a count := count - 1.\x0a header contents: [:html | html with: count asString]\x0a\x0a\x0aThat's it! We can now display an instance of TCounter by rendering it on the page using jQuery:\x0a\x0a TCounter new appendToJQuery: 'body' asJQuery\x0a\x0a"]);})(smalltalk.send((smalltalk.DocChapter || DocChapter), "_new", []));
560
554
  return self;}
561
555
  }),
562
- smalltalk.PackageDocChapter.klass);
556
+ smalltalk.TutorialsChapter);
563
557
 
558
+ smalltalk.addMethod(
559
+ "_firstAppChapter",
560
+ smalltalk.method({
561
+ selector: "firstAppChapter",
562
+ fn: function (){
563
+ var self=this;
564
+ return (function($rec){smalltalk.send($rec, "_title_", ["A first application"]);return smalltalk.send($rec, "_contents_", ["\x0a\x0aLet's make Hello World in Amber.\x0a\x0aFirst, you need a place for your new project. I made a new directory under amber:\x0a\x0a amber/projects/hello\x0a\x0aThis will store your project files. To get started, add a new index.html file to this folder, as well as empty js and st folders.\x0a\x0aYour index.html can be really basic. The most important thing it does is include amber.js and run loadAmber. Here is a basic index.html you can use:\x0a\x0a\x0a <!DOCTYPE html>\x0a <html>\x0a <head>\x0a <title>My First Amber Project</title>\x0a <script src=\x22../../js/amber.js\x22 type=\x22text/javascript\x22></script>\x0a <script type=\x22text/javascript\x22>\x0a loadAmber({\x0a files: [],\x0a prefix: 'projects/hello/js',\x0a ready: function() {\x0a \x0a }}); \x0a </script>\x0a </head>\x0a <body>\x0a <article>\x0a <h1>My First Amber Project</h1>\x0a <button onclick=\x22smalltalk.Browser._open()\x22>class browser</button>\x0a <button id=\x22sayHello\x22>say hello</button>\x0a </article>\x0a </body>\x0a </html>\x0a\x0aNow start up amber with node.js and navigate to http://localhost:4000/projects/hello/index.html\x0a\x0aIt's boring so far, so lets write some code. Click the button to open the class browser. Find an existing class and change its name to Hello and its package to HelloApp. \x0aThen click save. This creates a new class and leaves the old one intact, it doesn't overwrite it. Your class will look like this:\x0a\x0a Object subclass: #Hello\x0a instanceVariableNames: ''\x0a package: 'HelloApp'\x0a\x0aNow click save and navigate to your new class in its new package.\x0a Then click 'commit package'. You just created a new class and saved your work. \x0aOn your file system check out your js and st folders. Your new class is now saved in both JavaScript and Smalltalk.\x0a\x0aNow, refresh your browser page and reopen the class browser. Oh no, your new class is gone! To load your new class automatically, you have to add it in index.html. Make your JavaScript look like this:\x0a\x0a\x0a loadAmber({\x0a files: ['HelloApp.js'],\x0a prefix: 'projects/hello/js',\x0a ready: function() { \x0a }}); \x0a\x0aSave and refresh again. Now your class is loaded and shows up in the class browser.\x0a\x0aNow, let's make this class do something. Create a new message in the class browser by navigating to your class, then clicking 'not yet classified' and fill in a simple message. Try this for example:\x0a\x0a begin\x0a\x09\x22Makes me say hello to the user.\x22\x0a\x0a\x09| msg button |\x0a\x09msg := 'Hello world!'.\x0a\x09button := '#sayHello' asJQuery.\x0a\x09button click: [button after: '<p>' , msg , '</p>'].\x0a\x0aYour message isn't too helpful if it doesn't get called. Save it, commit the package, then edit index.html again. You can write JavaScript code that sends a message to Smalltalk:\x0a\x0a loadAmber({\x0a files: ['HelloApp.js'],\x0a prefix: 'projects/hello/js', // path for js files i think\x0a ready: function() {\x0a $(function() {\x0a smalltalk.Hello._new()._begin();\x0a });\x0a }}); \x0a\x0aFrom there, you can create new Smalltalk classes and messages to build up your app. Enjoy!\x0a"]);})(smalltalk.send((smalltalk.DocChapter || DocChapter), "_new", []));
565
+ return self;}
566
+ }),
567
+ smalltalk.TutorialsChapter);
564
568
 
565
- smalltalk.addClass('ClassDocChapter', smalltalk.DocChapter, ['theClass'], 'Documentation');
566
569
  smalltalk.addMethod(
567
- unescape('_theClass'),
570
+ "_title",
568
571
  smalltalk.method({
569
- selector: unescape('theClass'),
572
+ selector: "title",
570
573
  fn: function (){
571
574
  var self=this;
572
- return self['@theClass'];
575
+ return "Tutorials";
573
576
  return self;}
574
577
  }),
575
- smalltalk.ClassDocChapter);
578
+ smalltalk.TutorialsChapter);
579
+
576
580
 
581
+
582
+ smalltalk.addClass('DocumentationBuilder', smalltalk.Object, ['chapters', 'announcer', 'widget'], 'Documentation');
577
583
  smalltalk.addMethod(
578
- unescape('_contents'),
584
+ "_announcer",
579
585
  smalltalk.method({
580
- selector: unescape('contents'),
586
+ selector: "announcer",
581
587
  fn: function (){
582
588
  var self=this;
583
- return ((($receiver = smalltalk.send(smalltalk.send(smalltalk.send(self, "_theClass", []), "_comment", []), "_isEmpty", [])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(smalltalk.send(smalltalk.send(self, "_theClass", []), "_name", []), "__comma", [" is not documented yet."]);})() : (function(){return smalltalk.send(smalltalk.send(self, "_theClass", []), "_comment", []);})()) : smalltalk.send($receiver, "_ifTrue_ifFalse_", [(function(){return smalltalk.send(smalltalk.send(smalltalk.send(self, "_theClass", []), "_name", []), "__comma", [" is not documented yet."]);}), (function(){return smalltalk.send(smalltalk.send(self, "_theClass", []), "_comment", []);})]));
589
+ return (($receiver = self['@announcer']) == nil || $receiver == undefined) ? (function(){return (self['@announcer']=smalltalk.send((smalltalk.Announcer || Announcer), "_new", []));})() : $receiver;
584
590
  return self;}
585
591
  }),
586
- smalltalk.ClassDocChapter);
592
+ smalltalk.DocumentationBuilder);
587
593
 
588
594
  smalltalk.addMethod(
589
- unescape('_cssClass'),
595
+ "_build",
590
596
  smalltalk.method({
591
- selector: unescape('cssClass'),
597
+ selector: "build",
592
598
  fn: function (){
593
599
  var self=this;
594
- return smalltalk.send("doc_class ", "__comma", [smalltalk.send(self, "_cssClass", [], smalltalk.DocChapter)]);
600
+ smalltalk.send(self, "_buildOnJQuery_", [smalltalk.send("body", "_asJQuery", [])]);
595
601
  return self;}
596
602
  }),
597
- smalltalk.ClassDocChapter);
603
+ smalltalk.DocumentationBuilder);
598
604
 
599
605
  smalltalk.addMethod(
600
- unescape('_title'),
606
+ "_buildChapters",
601
607
  smalltalk.method({
602
- selector: unescape('title'),
608
+ selector: "buildChapters",
603
609
  fn: function (){
604
610
  var self=this;
605
- return smalltalk.send(smalltalk.send(self, "_theClass", []), "_name", []);
611
+ return smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(smalltalk.send(self, "_class", []), "_methodDictionary", []), "_values", []), "_sorted_", [(function(a, b){return ((($receiver = smalltalk.send(a, "_selector", [])).klass === smalltalk.Number) ? $receiver <smalltalk.send(b, "_selector", []) : smalltalk.send($receiver, "__lt", [smalltalk.send(b, "_selector", [])]));})]), "_select_", [(function(each){return smalltalk.send(smalltalk.send(each, "_category", []), "__eq", ["chapters"]);})]), "_collect_", [(function(each){return smalltalk.send(self, "_perform_", [smalltalk.send(each, "_selector", [])]);})]);
606
612
  return self;}
607
613
  }),
608
- smalltalk.ClassDocChapter);
614
+ smalltalk.DocumentationBuilder);
609
615
 
610
616
  smalltalk.addMethod(
611
- unescape('_initializeWithClass_'),
617
+ "_buildOn_",
612
618
  smalltalk.method({
613
- selector: unescape('initializeWithClass%3A'),
614
- fn: function (aClass){
619
+ selector: "buildOn:",
620
+ fn: function (aCanvas){
615
621
  var self=this;
616
- (self['@theClass']=aClass);
622
+ smalltalk.send(aCanvas, "_with_", [smalltalk.send(self, "_widget", [])]);
623
+ (function($rec){smalltalk.send($rec, "_checkHashChange", []);return smalltalk.send($rec, "_checkHash", []);})(self);
617
624
  return self;}
618
625
  }),
619
- smalltalk.ClassDocChapter);
626
+ smalltalk.DocumentationBuilder);
620
627
 
621
628
  smalltalk.addMethod(
622
- unescape('_renderLinksOn_'),
629
+ "_buildOnJQuery_",
623
630
  smalltalk.method({
624
- selector: unescape('renderLinksOn%3A'),
625
- fn: function (html){
631
+ selector: "buildOnJQuery:",
632
+ fn: function (aJQuery){
626
633
  var self=this;
627
- (function($rec){smalltalk.send($rec, "_class_", ["links"]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(smalltalk.send(html, "_li", []), "_with_", [(function(){return (function($rec){smalltalk.send($rec, "_with_", ["Browse this class"]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send((smalltalk.Browser || Browser), "_openOn_", [smalltalk.send(self, "_theClass", [])]);})]);})(smalltalk.send(html, "_a", []));})]);})]);})(smalltalk.send(html, "_ul", []));
634
+ smalltalk.send(self, "_buildOn_", [smalltalk.send((smalltalk.HTMLCanvas || HTMLCanvas), "_onJQuery_", [aJQuery])]);
628
635
  return self;}
629
636
  }),
630
- smalltalk.ClassDocChapter);
637
+ smalltalk.DocumentationBuilder);
631
638
 
632
639
  smalltalk.addMethod(
633
- unescape('_subscribe'),
640
+ "_ch1introduction",
634
641
  smalltalk.method({
635
- selector: unescape('subscribe'),
642
+ selector: "ch1introduction",
636
643
  fn: function (){
637
644
  var self=this;
638
- smalltalk.send(self, "_subscribe", [], smalltalk.DocChapter);
639
- smalltalk.send(smalltalk.send(self, "_announcer", []), "_on_do_", [(smalltalk.ClassSelectionAnnouncement || ClassSelectionAnnouncement), (function(ann){return ((($receiver = smalltalk.send(smalltalk.send(ann, "_theClass", []), "__eq", [smalltalk.send(self, "_theClass", [])])).klass === smalltalk.Boolean) ? ($receiver ? (function(){return smalltalk.send(self, "_selectChapter_", [self]);})() : nil) : smalltalk.send($receiver, "_ifTrue_", [(function(){return smalltalk.send(self, "_selectChapter_", [self]);})]));})]);
645
+ return (function($rec){smalltalk.send($rec, "_title_", ["Introduction"]);return smalltalk.send($rec, "_contents_", ["\x0a\x0a##Amber Smalltalk in a nutshell\x0a\x0aAmber is an implementation of the Smalltalk-80 language. It is designed to make client-side web development **faster, easier and more fun** as it allows developers to write HTML5 applications in a live Smalltalk environment!\x0a\x0aAmber is written in itself, including the IDE and the compiler and it runs **directly inside your browser**. The IDE is fairly complete with a class browser, workspace, transcript, unit test runner, object inspectors, cross reference tools and even a debugger.\x0a\x0aNoteworthy features:\x0a\x0a- Amber is semantically and syntactically very close to [Pharo Smalltalk](http://www.pharo-project.org). Pharo is considered the reference implementation.\x0a- Amber **seamlessly interacts with JavaScript** and can use its full eco system of libraries without any glue code needed.\x0a- Amber **has no dependencies** and can be used in any JavaScript runtime, not only inside browsers. An important example is [Node.js](http://nodejs.org).\x0a- Amber is a live Smalltalk that **compiles incrementally into efficient JavaScript** often mapping one-to-one with JavaScript equivalents.\x0a- Amber has a **Seaside influenced canvas library** to dynamically generate HTML.\x0a\x0a## Arguments for using Amber\x0aIn our humble opinion the main arguments for using Amber are:\x0a\x0a- JavaScript is quite a broken language with lots of traps and odd quirks. It is the assembler of the Internet which is cool, but we don't want to write in it.\x0a- Smalltalk as a language is immensely cleaner and more mature, both syntactically and semantically.\x0a- Smalltalk has a simple class model with a lightweight syntax for closures, it is in many ways a perfect match for the Good Parts of JavaScript.\x0a- Having a true live interactive incremental development environment where you can build your application directly in the browser is unbeatable.\x0a\x0a## Disclaimer\x0a\x0aThis documentation doesn't aim to teach Smalltalk. \x0aKnowledge of Smalltalk is needed to understand the topics covered in this documentation. \x0aIf you want to learn the Smalltalk language, you can read the excellent [Pharo By Example](http://www.pharobyexample.org) book.\x0a"]);})(smalltalk.send((smalltalk.DocChapter || DocChapter), "_new", []));
640
646
  return self;}
641
647
  }),
642
- smalltalk.ClassDocChapter);
643
-
648
+ smalltalk.DocumentationBuilder);
644
649
 
645
650
  smalltalk.addMethod(
646
- unescape('_on_'),
651
+ "_ch2differencesWithOtherSmalltalks",
647
652
  smalltalk.method({
648
- selector: unescape('on%3A'),
649
- fn: function (aClass){
653
+ selector: "ch2differencesWithOtherSmalltalks",
654
+ fn: function (){
650
655
  var self=this;
651
- return (function($rec){smalltalk.send($rec, "_initializeWithClass_", [aClass]);smalltalk.send($rec, "_initialize", []);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_basicNew", []));
656
+ return (function($rec){smalltalk.send($rec, "_title_", ["Differences with other Smalltalks"]);return smalltalk.send($rec, "_contents_", ["\x0aAmber has some differences with other Smalltalk implementations. This makes porting code a non-trivial thing, but still quite manageable.\x0aBecause it maps Smalltalk constructs one-to-one with the JavaScript equivalent, including Smalltalk classes to JavaScript constructors, the core class library is simplified compared to Pharo Smalltalk.\x0aAnd since we want Amber to be useful in building lean browser apps we can't let it bloat too much.\x0a\x0aBut apart from missing things other Smalltalks may have, there are also things that are plain different:\x0a\x0a- The collection class hierarchy is much simpler compared to most Smalltalk implementations. In part this is because we want to map reasonably well with JavaScript counter parts.\x0a- As of today, there is no SortedCollection. The size of arrays is dynamic, and they behave like an ordered collection. They can also be sorted with the `#sort*` methods.\x0a- The `Date` class behaves like the `Date` and `TimeStamp` classes in Pharo Smalltalk. Therefore both `Date today` and `Date now` are valid in Amber.\x0a- Amber does not have class Character, but `String` does implement some of Character behavior so a single character String can work as a Character.\x0a- Amber does support **class instance variables**, but not class variables.\x0a- Amber only has global classes and packages, but not arbitrary objects. Use classes instead like `Smalltalk current` instead of `Smalltalk` etc.\x0a- Amber does not support pool dictionaries.\x0a- Amber uses **< ...javascript code... >** to inline JavaScript code and does not have pragmas.\x0a- Amber does not have class categories. The left side in the browser lists real Packages, but they feel much the same.\x0a"]);})(smalltalk.send((smalltalk.DocChapter || DocChapter), "_new", []));
652
657
  return self;}
653
658
  }),
654
- smalltalk.ClassDocChapter.klass);
655
-
659
+ smalltalk.DocumentationBuilder);
656
660
 
657
- smalltalk.addClass('DocumentationWidget', smalltalk.Widget, ['builder', 'selectedChapter', 'chapterDiv'], 'Documentation');
658
661
  smalltalk.addMethod(
659
- unescape('_builder'),
662
+ "_ch3GettingStarted",
660
663
  smalltalk.method({
661
- selector: unescape('builder'),
664
+ selector: "ch3GettingStarted",
662
665
  fn: function (){
663
666
  var self=this;
664
- return self['@builder'];
667
+ return (function($rec){smalltalk.send($rec, "_title_", ["Getting started"]);return smalltalk.send($rec, "_contents_", ["\x0aTo get started hacking in Amber you can basically take three routes, independent of your platform:\x0a\x0a1. Just **try it out directly** at [www.amber-lang.net](http://www.amber-lang.net) - click the **Class browser** button there. But you will **not be able to save any code you write**! \x0a Still, it works fine for looking at the IDE and playing around. Just **don't press F5/reload** - it will lose any code you have written.\x0a2. Download an Amber zip-ball, install [Nodejs](http://www.nodejs.org), fire up the Amber server and then open Amber from localhost - then you **can save code**. Detailed instructions are below!\x0a3. Same as above but install git first and get a proper clone from [http://github.com/NicolasPetton/amber](http://github.com/NicolasPetton/amber) instead of a zip/tar-ball. \x0a If you want to **contribute to Amber itself** this is really what you want to do. In fact, in most cases this is what you want to do. It requires installing git first, but it is quite simple - although we leave this bit as an \x22exercise to the reader\x22 :)\x0a\x0a**PLEASE NOTE:** Amber core developers use Linux. \x0aWe do not want to introduce dependencies that aren't cross platform - but currently amberc (the command line compiler) is a bash script and we also use Makefiles \x0a(for building Amber itself and server side examples) written on Linux/Unix. So using Windows is currently a bit limited - you can't run \x22make\x22 in the .st directory to rebuild whole of Amber for example.\x0a BUT... if you only want to use Amber to build web client apps and not really get involved in hacking Amber itself - then you should be fine!\x0a\x0a## Downloading Amber\x0aCurrently you can download in zip or tar-ball format, either cutting edge or a release. [Downloads are available here](https://github.com/NicolasPetton/amber/archives/amber). \x0a\x0aUnpack wherever you like, but I would rename the directory that is unpacked to something slightly shorter - like say \x22amber\x22. :)\x0aAnd yes, at this point you can double click the index.html file in the amber directory to get the IDE up, but again, **you will not be able to save code**. So please continue below :)\x0a\x0a## Installing Node.js\x0a[Node](http://www.nodejs.org) (for short) is simply the V8 Javascript VM from Google (used in Chrome) hooked together with some hard core C-libraries for doing \x22evented I/O\x22.\x0aBasically it's JavaScript for the server - on asynch steroids. Amber runs fine in Node and we use it for several Amber tools, like amberc (the command line Amber compiler) or the Amber server (see below). \x0aThere are also several Amber-Node examples to look at if you want to play with running Amber programs server side. **In short - you really want to install Nodejs. :)**\x0a\x0a- Installing Node on Linux can be done using your package tool of choice (`apt-get install nodejs` for example) or any other way described at [the download page](http://nodejs.org/#download).\x0a- Installing Node on MacOS or Windows is probably done best by using the [installers available at Nodejs.org](http://nodejs.org/#download).\x0a\x0a## Starting Amber server\x0aNicolas has written a minimal webDAV server that is the easiest way to get up and running Amber with the ability to save code. This little server is written in... Amber! \x0aAnd it runs on top of Node. So to start it up serving your brand new directory tree of sweet Amber you do:\x0a\x0a\x09cd amber\x09(or whatever you called the directory you unpackaged)\x0a\x09./bin/server\x09(in windows you type `node server\x5cserver.js` instead)\x0a\x0aIt should say it is listening on port 4000. If it does, hooray! That means both Node and Amber are good. In Windows you might get a question about opening that port in the local firewall - yep, do it!\x0a\x0a## Firing up Amber\x0aThe Amber IDE is written in... Amber. It uses [jQuery](http://jquery.com) and runs right in your browser as a ... well, a web page. \x0aWe could open it up just using a file url - but the reason we performed the previous steps is so that we can load the IDE web page from a server that can handle PUTs (webDAV) of source code. \x0aAccording to web security Amber can only do PUT back to the same server it was loaded from. Thus we instead want to open it [through our little server now listening on port 4000](http://localhost:4000/index.html).\x0aClicking that link and then pressing the **Class browser** should get your Amber IDE running with the ability to commit modified packages locally.\x0a\x0aTo verify that you can indeed commit now - just select a Package in the browser, like say \x22Examples\x22 and press the **Commit** button below. **If all goes well nothing happens :)**. \x0aSo in order to really know if it worked we can check the modified date on the files **amber/st/Examples.st**, **amber/js/Examples.js** and **amber/js/Examples.deploy.js** - they should be brand new.\x0a\x0aNOTE: We can use any webDAV server and Apache2 has been used earlier and works fine. But the Amber server is smaller and simpler to start.\x0a"]);})(smalltalk.send((smalltalk.DocChapter || DocChapter), "_new", []));
665
668
  return self;}
666
669
  }),
667
- smalltalk.DocumentationWidget);
670
+ smalltalk.DocumentationBuilder);
668
671
 
669
672
  smalltalk.addMethod(
670
- unescape('_builder_'),
673
+ "_ch4Tutorials",
671
674
  smalltalk.method({
672
- selector: unescape('builder%3A'),
673
- fn: function (aDocumentationBuilder){
675
+ selector: "ch4Tutorials",
676
+ fn: function (){
674
677
  var self=this;
675
- (self['@builder']=aDocumentationBuilder);
678
+ return smalltalk.send((smalltalk.TutorialsChapter || TutorialsChapter), "_new", []);
676
679
  return self;}
677
680
  }),
678
- smalltalk.DocumentationWidget);
681
+ smalltalk.DocumentationBuilder);
679
682
 
680
683
  smalltalk.addMethod(
681
- unescape('_chapters'),
684
+ "_ch5Index",
682
685
  smalltalk.method({
683
- selector: unescape('chapters'),
686
+ selector: "ch5Index",
684
687
  fn: function (){
685
688
  var self=this;
686
- return smalltalk.send(smalltalk.send(self, "_builder", []), "_chapters", []);
689
+ return smalltalk.send((smalltalk.ClassesIndexChapter || ClassesIndexChapter), "_new", []);
687
690
  return self;}
688
691
  }),
689
- smalltalk.DocumentationWidget);
692
+ smalltalk.DocumentationBuilder);
690
693
 
691
694
  smalltalk.addMethod(
692
- unescape('_selectedChapter'),
695
+ "_ch6KernelObjects",
693
696
  smalltalk.method({
694
- selector: unescape('selectedChapter'),
697
+ selector: "ch6KernelObjects",
695
698
  fn: function (){
696
699
  var self=this;
697
- return (($receiver = self['@selectedChapter']) == nil || $receiver == undefined) ? (function(){return (self['@selectedChapter']=smalltalk.send(smalltalk.send(self, "_chapters", []), "_first", []));})() : $receiver;
700
+ return smalltalk.send((smalltalk.PackageDocChapter || PackageDocChapter), "_on_", [smalltalk.send((smalltalk.Package || Package), "_named_", ["Kernel-Objects"])]);
698
701
  return self;}
699
702
  }),
700
- smalltalk.DocumentationWidget);
703
+ smalltalk.DocumentationBuilder);
701
704
 
702
705
  smalltalk.addMethod(
703
- unescape('_selectedChapter_'),
706
+ "_ch7KernelClasses",
704
707
  smalltalk.method({
705
- selector: unescape('selectedChapter%3A'),
706
- fn: function (aChapter){
708
+ selector: "ch7KernelClasses",
709
+ fn: function (){
707
710
  var self=this;
708
- return (self['@selectedChapter']=aChapter);
711
+ return smalltalk.send((smalltalk.PackageDocChapter || PackageDocChapter), "_on_", [smalltalk.send((smalltalk.Package || Package), "_named_", ["Kernel-Classes"])]);
709
712
  return self;}
710
713
  }),
711
- smalltalk.DocumentationWidget);
714
+ smalltalk.DocumentationBuilder);
712
715
 
713
716
  smalltalk.addMethod(
714
- unescape('_displayChapter_'),
717
+ "_ch8KernelCollection",
715
718
  smalltalk.method({
716
- selector: unescape('displayChapter%3A'),
717
- fn: function (aChapter){
719
+ selector: "ch8KernelCollection",
720
+ fn: function (){
718
721
  var self=this;
719
- smalltalk.send(self, "_selectedChapter_", [aChapter]);
720
- smalltalk.send(self, "_updateChapterDiv", []);
722
+ return smalltalk.send((smalltalk.PackageDocChapter || PackageDocChapter), "_on_", [smalltalk.send((smalltalk.Package || Package), "_named_", ["Kernel-Collections"])]);
721
723
  return self;}
722
724
  }),
723
- smalltalk.DocumentationWidget);
725
+ smalltalk.DocumentationBuilder);
724
726
 
725
727
  smalltalk.addMethod(
726
- unescape('_selectChapter_'),
728
+ "_ch9KernelMethods",
727
729
  smalltalk.method({
728
- selector: unescape('selectChapter%3A'),
729
- fn: function (aChapter){
730
+ selector: "ch9KernelMethods",
731
+ fn: function (){
730
732
  var self=this;
731
- smalltalk.send(smalltalk.send((typeof document == 'undefined' ? nil : document), "_location", []), "_hash_", [smalltalk.send(aChapter, "_id", [])]);
733
+ return smalltalk.send((smalltalk.PackageDocChapter || PackageDocChapter), "_on_", [smalltalk.send((smalltalk.Package || Package), "_named_", ["Kernel-Methods"])]);
732
734
  return self;}
733
735
  }),
734
- smalltalk.DocumentationWidget);
736
+ smalltalk.DocumentationBuilder);
735
737
 
736
738
  smalltalk.addMethod(
737
- unescape('_renderOn_'),
739
+ "_chapters",
738
740
  smalltalk.method({
739
- selector: unescape('renderOn%3A'),
740
- fn: function (html){
741
+ selector: "chapters",
742
+ fn: function (){
741
743
  var self=this;
742
- (function($rec){smalltalk.send($rec, "_class_", ["documentation"]);return smalltalk.send($rec, "_with_", [(function(){smalltalk.send(self, "_renderMenuOn_", [html]);(self['@chapterDiv']=smalltalk.send(html, "_div", []));return smalltalk.send(self, "_updateChapterDiv", []);})]);})(smalltalk.send(html, "_div", []));
744
+ return (($receiver = self['@chapters']) == nil || $receiver == undefined) ? (function(){return (self['@chapters']=smalltalk.send(self, "_buildChapters", []));})() : $receiver;
743
745
  return self;}
744
746
  }),
745
- smalltalk.DocumentationWidget);
747
+ smalltalk.DocumentationBuilder);
746
748
 
747
749
  smalltalk.addMethod(
748
- unescape('_renderMenuOn_'),
750
+ "_checkHash",
749
751
  smalltalk.method({
750
- selector: unescape('renderMenuOn%3A'),
751
- fn: function (html){
752
+ selector: "checkHash",
753
+ fn: function (){
752
754
  var self=this;
753
- (function($rec){smalltalk.send($rec, "_class_", ["menu"]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(smalltalk.send(html, "_ol", []), "_with_", [(function(){return smalltalk.send(smalltalk.send(self, "_chapters", []), "_do_", [(function(each){return smalltalk.send(smalltalk.send(html, "_li", []), "_with_", [(function(){return smalltalk.send(self, "_renderChapterMenu_on_", [each, html]);})]);})]);})]);})]);})(smalltalk.send(html, "_div", []));
755
+ var hash=nil;
756
+ var presentation=nil;
757
+ (hash=smalltalk.send(smalltalk.send(smalltalk.send((typeof document == 'undefined' ? nil : document), "_location", []), "_hash", []), "_replace_with_", ["^#", ""]));
758
+ smalltalk.send(smalltalk.send(self, "_announcer", []), "_announce_", [(function($rec){smalltalk.send($rec, "_id_", [hash]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send((smalltalk.ChapterSelectionAnnouncement || ChapterSelectionAnnouncement), "_new", []))]);
754
759
  return self;}
755
760
  }),
756
- smalltalk.DocumentationWidget);
761
+ smalltalk.DocumentationBuilder);
757
762
 
758
763
  smalltalk.addMethod(
759
- unescape('_renderChapterMenu_on_'),
764
+ "_checkHashChange",
760
765
  smalltalk.method({
761
- selector: unescape('renderChapterMenu%3Aon%3A'),
762
- fn: function (aChapter, html){
766
+ selector: "checkHashChange",
767
+ fn: function (){
763
768
  var self=this;
764
- (function($rec){smalltalk.send($rec, "_with_", [smalltalk.send(aChapter, "_title", [])]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_selectChapter_", [aChapter]);})]);})(smalltalk.send(html, "_a", []));
765
- smalltalk.send(smalltalk.send(html, "_ol", []), "_with_", [(function(){return smalltalk.send(smalltalk.send(aChapter, "_chapters", []), "_do_", [(function(each){return smalltalk.send(smalltalk.send(html, "_li", []), "_with_", [(function(){return smalltalk.send(self, "_renderChapterMenu_on_", [each, html]);})]);})]);})]);
769
+ smalltalk.send(smalltalk.send((typeof window == 'undefined' ? nil : window), "_jQuery_", [(typeof window == 'undefined' ? nil : window)]), "_bind_do_", ["hashchange", (function(){return smalltalk.send(self, "_checkHash", []);})]);
766
770
  return self;}
767
771
  }),
768
- smalltalk.DocumentationWidget);
772
+ smalltalk.DocumentationBuilder);
769
773
 
770
774
  smalltalk.addMethod(
771
- unescape('_updateChapterDiv'),
775
+ "_update",
772
776
  smalltalk.method({
773
- selector: unescape('updateChapterDiv'),
777
+ selector: "update",
774
778
  fn: function (){
775
779
  var self=this;
776
- smalltalk.send(self['@chapterDiv'], "_contents_", [(function(html){return smalltalk.send(html, "_with_", [smalltalk.send(self, "_selectedChapter", [])]);})]);
780
+ (self['@chapters']=nil);
781
+ (self['@announcer']=nil);
782
+ (self['@widget']=nil);
783
+ smalltalk.send(smalltalk.send((typeof window == 'undefined' ? nil : window), "_jQuery_", [".documentation"]), "_remove", []);
784
+ smalltalk.send(self, "_build", []);
777
785
  return self;}
778
786
  }),
779
- smalltalk.DocumentationWidget);
780
-
787
+ smalltalk.DocumentationBuilder);
781
788
 
782
789
  smalltalk.addMethod(
783
- unescape('_on_'),
790
+ "_widget",
784
791
  smalltalk.method({
785
- selector: unescape('on%3A'),
786
- fn: function (aBuilder){
792
+ selector: "widget",
793
+ fn: function (){
787
794
  var self=this;
788
- return (function($rec){smalltalk.send($rec, "_builder_", [aBuilder]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
795
+ return (($receiver = self['@widget']) == nil || $receiver == undefined) ? (function(){return (self['@widget']=smalltalk.send((smalltalk.DocumentationWidget || DocumentationWidget), "_on_", [self]));})() : $receiver;
789
796
  return self;}
790
797
  }),
791
- smalltalk.DocumentationWidget.klass);
798
+ smalltalk.DocumentationBuilder);
792
799
 
793
800
 
794
- smalltalk.addClass('ClassesIndexChapter', smalltalk.DocChapter, [], 'Documentation');
801
+ smalltalk.DocumentationBuilder.klass.iVarNames = ['current'];
795
802
  smalltalk.addMethod(
796
- unescape('_cssClass'),
803
+ "_current",
797
804
  smalltalk.method({
798
- selector: unescape('cssClass'),
805
+ selector: "current",
799
806
  fn: function (){
800
807
  var self=this;
801
- return smalltalk.send("index_doc ", "__comma", [smalltalk.send(self, "_cssClass", [], smalltalk.DocChapter)]);
808
+ return (($receiver = self['@current']) == nil || $receiver == undefined) ? (function(){return (self['@current']=smalltalk.send(self, "_new", []));})() : $receiver;
802
809
  return self;}
803
810
  }),
804
- smalltalk.ClassesIndexChapter);
811
+ smalltalk.DocumentationBuilder.klass);
805
812
 
806
813
  smalltalk.addMethod(
807
- unescape('_title'),
814
+ "_initialize",
808
815
  smalltalk.method({
809
- selector: unescape('title'),
816
+ selector: "initialize",
810
817
  fn: function (){
811
818
  var self=this;
812
- return "Smalltalk classes by index";
819
+ smalltalk.send(smalltalk.send(self, "_current", []), "_build", []);
813
820
  return self;}
814
821
  }),
815
- smalltalk.ClassesIndexChapter);
822
+ smalltalk.DocumentationBuilder.klass);
823
+
816
824
 
825
+ smalltalk.addClass('DocumentationWidget', smalltalk.Widget, ['builder', 'selectedChapter', 'chapterDiv'], 'Documentation');
817
826
  smalltalk.addMethod(
818
- unescape('_alphabet'),
827
+ "_builder",
819
828
  smalltalk.method({
820
- selector: unescape('alphabet'),
829
+ selector: "builder",
821
830
  fn: function (){
822
831
  var self=this;
823
- return "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
832
+ return self['@builder'];
824
833
  return self;}
825
834
  }),
826
- smalltalk.ClassesIndexChapter);
835
+ smalltalk.DocumentationWidget);
827
836
 
828
837
  smalltalk.addMethod(
829
- unescape('_renderDocOn_'),
838
+ "_builder_",
830
839
  smalltalk.method({
831
- selector: unescape('renderDocOn%3A'),
832
- fn: function (html){
840
+ selector: "builder:",
841
+ fn: function (aDocumentationBuilder){
833
842
  var self=this;
834
- smalltalk.send(smalltalk.send(html, "_h1", []), "_with_", [smalltalk.send(self, "_title", [])]);
835
- smalltalk.send(smalltalk.send(self, "_alphabet", []), "_do_", [(function(letter){var classes=nil;
836
- (classes=smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Smalltalk || Smalltalk), "_current", []), "_classes", []), "_select_", [(function(each){return smalltalk.send(smalltalk.send(smalltalk.send(each, "_name", []), "_first", []), "__eq", [letter]);})]));smalltalk.send(classes, "_ifNotEmpty_", [(function(){return smalltalk.send(smalltalk.send(html, "_h2", []), "_with_", [letter]);})]);return smalltalk.send(smalltalk.send(html, "_ul", []), "_with_", [(function(){return smalltalk.send(smalltalk.send(classes, "_sorted_", [(function(a, b){return ((($receiver = smalltalk.send(a, "_name", [])).klass === smalltalk.Number) ? $receiver <smalltalk.send(b, "_name", []) : smalltalk.send($receiver, "__lt", [smalltalk.send(b, "_name", [])]));})]), "_do_", [(function(each){return smalltalk.send(smalltalk.send(html, "_li", []), "_with_", [(function(){return (function($rec){smalltalk.send($rec, "_with_", [smalltalk.send(each, "_name", [])]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_selectClass_", [each]);})]);})(smalltalk.send(html, "_a", []));})]);})]);})]);})]);
843
+ (self['@builder']=aDocumentationBuilder);
837
844
  return self;}
838
845
  }),
839
- smalltalk.ClassesIndexChapter);
840
-
841
-
846
+ smalltalk.DocumentationWidget);
842
847
 
843
- smalltalk.addClass('ClassSelectionAnnouncement', smalltalk.Object, ['theClass'], 'Documentation');
844
848
  smalltalk.addMethod(
845
- unescape('_theClass'),
849
+ "_chapters",
846
850
  smalltalk.method({
847
- selector: unescape('theClass'),
851
+ selector: "chapters",
848
852
  fn: function (){
849
853
  var self=this;
850
- return self['@theClass'];
854
+ return smalltalk.send(smalltalk.send(self, "_builder", []), "_chapters", []);
851
855
  return self;}
852
856
  }),
853
- smalltalk.ClassSelectionAnnouncement);
857
+ smalltalk.DocumentationWidget);
854
858
 
855
859
  smalltalk.addMethod(
856
- unescape('_theClass_'),
860
+ "_displayChapter_",
857
861
  smalltalk.method({
858
- selector: unescape('theClass%3A'),
859
- fn: function (aClass){
862
+ selector: "displayChapter:",
863
+ fn: function (aChapter){
860
864
  var self=this;
861
- (self['@theClass']=aClass);
865
+ smalltalk.send(self, "_selectedChapter_", [aChapter]);
866
+ smalltalk.send(self, "_updateChapterDiv", []);
862
867
  return self;}
863
868
  }),
864
- smalltalk.ClassSelectionAnnouncement);
865
-
869
+ smalltalk.DocumentationWidget);
866
870
 
867
871
  smalltalk.addMethod(
868
- unescape('_on_'),
872
+ "_renderChapterMenu_on_",
869
873
  smalltalk.method({
870
- selector: unescape('on%3A'),
871
- fn: function (aClass){
874
+ selector: "renderChapterMenu:on:",
875
+ fn: function (aChapter, html){
872
876
  var self=this;
873
- return (function($rec){smalltalk.send($rec, "_theClass_", [aClass]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
877
+ (function($rec){smalltalk.send($rec, "_with_", [smalltalk.send(aChapter, "_title", [])]);return smalltalk.send($rec, "_onClick_", [(function(){return smalltalk.send(self, "_selectChapter_", [aChapter]);})]);})(smalltalk.send(html, "_a", []));
878
+ smalltalk.send(smalltalk.send(html, "_ol", []), "_with_", [(function(){return smalltalk.send(smalltalk.send(aChapter, "_chapters", []), "_do_", [(function(each){return smalltalk.send(smalltalk.send(html, "_li", []), "_with_", [(function(){return smalltalk.send(self, "_renderChapterMenu_on_", [each, html]);})]);})]);})]);
874
879
  return self;}
875
880
  }),
876
- smalltalk.ClassSelectionAnnouncement.klass);
877
-
881
+ smalltalk.DocumentationWidget);
878
882
 
879
- smalltalk.addClass('ChapterSelectionAnnouncement', smalltalk.Object, ['id'], 'Documentation');
880
883
  smalltalk.addMethod(
881
- unescape('_id'),
884
+ "_renderMenuOn_",
882
885
  smalltalk.method({
883
- selector: unescape('id'),
884
- fn: function (){
886
+ selector: "renderMenuOn:",
887
+ fn: function (html){
885
888
  var self=this;
886
- return self['@id'];
889
+ (function($rec){smalltalk.send($rec, "_class_", ["menu"]);return smalltalk.send($rec, "_with_", [(function(){return smalltalk.send(smalltalk.send(html, "_ol", []), "_with_", [(function(){return smalltalk.send(smalltalk.send(self, "_chapters", []), "_do_", [(function(each){return smalltalk.send(smalltalk.send(html, "_li", []), "_with_", [(function(){return smalltalk.send(self, "_renderChapterMenu_on_", [each, html]);})]);})]);})]);})]);})(smalltalk.send(html, "_div", []));
887
890
  return self;}
888
891
  }),
889
- smalltalk.ChapterSelectionAnnouncement);
892
+ smalltalk.DocumentationWidget);
890
893
 
891
894
  smalltalk.addMethod(
892
- unescape('_id_'),
895
+ "_renderOn_",
893
896
  smalltalk.method({
894
- selector: unescape('id%3A'),
895
- fn: function (aString){
897
+ selector: "renderOn:",
898
+ fn: function (html){
896
899
  var self=this;
897
- (self['@id']=aString);
900
+ (function($rec){smalltalk.send($rec, "_class_", ["documentation"]);return smalltalk.send($rec, "_with_", [(function(){smalltalk.send(self, "_renderMenuOn_", [html]);(self['@chapterDiv']=smalltalk.send(html, "_div", []));return smalltalk.send(self, "_updateChapterDiv", []);})]);})(smalltalk.send(html, "_div", []));
898
901
  return self;}
899
902
  }),
900
- smalltalk.ChapterSelectionAnnouncement);
901
-
902
-
903
+ smalltalk.DocumentationWidget);
903
904
 
904
- smalltalk.addClass('TutorialsChapter', smalltalk.DocChapter, [], 'Documentation');
905
905
  smalltalk.addMethod(
906
- unescape('_title'),
906
+ "_selectChapter_",
907
907
  smalltalk.method({
908
- selector: unescape('title'),
909
- fn: function (){
908
+ selector: "selectChapter:",
909
+ fn: function (aChapter){
910
910
  var self=this;
911
- return "Tutorials";
911
+ smalltalk.send(smalltalk.send((typeof document == 'undefined' ? nil : document), "_location", []), "_hash_", [smalltalk.send(aChapter, "_id", [])]);
912
912
  return self;}
913
913
  }),
914
- smalltalk.TutorialsChapter);
914
+ smalltalk.DocumentationWidget);
915
915
 
916
916
  smalltalk.addMethod(
917
- unescape('_contents'),
917
+ "_selectedChapter",
918
918
  smalltalk.method({
919
- selector: unescape('contents'),
919
+ selector: "selectedChapter",
920
920
  fn: function (){
921
921
  var self=this;
922
- return unescape("Here%27s%20a%20serie%20of%20tutorials.%20If%20you%20are%20new%20to%20Smalltalk%2C%20you%20can%20also%20learn%20Amber%20online%20with%20%5BProfStef%5D%28http%3A//www.amber-lang.net/learn.html%29");
922
+ return (($receiver = self['@selectedChapter']) == nil || $receiver == undefined) ? (function(){return (self['@selectedChapter']=smalltalk.send(smalltalk.send(self, "_chapters", []), "_first", []));})() : $receiver;
923
923
  return self;}
924
924
  }),
925
- smalltalk.TutorialsChapter);
925
+ smalltalk.DocumentationWidget);
926
926
 
927
927
  smalltalk.addMethod(
928
- unescape('_chapters'),
928
+ "_selectedChapter_",
929
929
  smalltalk.method({
930
- selector: unescape('chapters'),
931
- fn: function (){
930
+ selector: "selectedChapter:",
931
+ fn: function (aChapter){
932
932
  var self=this;
933
- return [smalltalk.send(self, "_firstAppChapter", []),smalltalk.send(self, "_counterChapter", [])];
933
+ return (self['@selectedChapter']=aChapter);
934
934
  return self;}
935
935
  }),
936
- smalltalk.TutorialsChapter);
936
+ smalltalk.DocumentationWidget);
937
937
 
938
938
  smalltalk.addMethod(
939
- unescape('_firstAppChapter'),
939
+ "_updateChapterDiv",
940
940
  smalltalk.method({
941
- selector: unescape('firstAppChapter'),
941
+ selector: "updateChapterDiv",
942
942
  fn: function (){
943
943
  var self=this;
944
- return (function($rec){smalltalk.send($rec, "_title_", ["A first application"]);return smalltalk.send($rec, "_contents_", [unescape("%0A%0ALet%27s%20make%20Hello%20World%20in%20Amber.%0A%0AFirst%2C%20you%20need%20a%20place%20for%20your%20new%20project.%20I%20made%20a%20new%20directory%20under%20amber%3A%0A%0A%20%20%20%20amber/projects/hello%0A%0AThis%20will%20store%20your%20project%20files.%20To%20get%20started%2C%20add%20a%20new%20index.html%20file%20to%20this%20folder%2C%20as%20well%20as%20empty%20js%20and%20st%20folders.%0A%0AYour%20index.html%20can%20be%20really%20basic.%20The%20most%20important%20thing%20it%20does%20is%20include%20amber.js%20and%20run%20loadAmber.%20Here%20is%20a%20basic%20index.html%20you%20can%20use%3A%0A%0A%0A%20%20%20%20%3C%21DOCTYPE%20html%3E%0A%20%20%20%20%3Chtml%3E%0A%20%20%20%20%20%20%3Chead%3E%0A%20%20%20%20%20%20%20%20%3Ctitle%3EMy%20First%20Amber%20Project%3C/title%3E%0A%20%20%20%20%20%20%20%20%3Cscript%20src%3D%22../../js/amber.js%22%20type%3D%22text/javascript%22%3E%3C/script%3E%0A%20%20%20%20%20%20%20%20%3Cscript%20type%3D%22text/javascript%22%3E%0A%20%20%20%20%20%20%20%20%20%20loadAmber%28%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20files%3A%20%5B%5D%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20prefix%3A%20%27projects/hello/js%27%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20ready%3A%20function%28%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%7D%29%3B%20%0A%20%20%20%20%20%20%20%20%3C/script%3E%0A%20%20%20%20%20%20%3C/head%3E%0A%20%20%20%20%20%20%3Cbody%3E%0A%20%20%20%20%20%20%20%20%3Carticle%3E%0A%20%20%20%20%20%20%20%20%20%20%3Ch1%3EMy%20First%20Amber%20Project%3C/h1%3E%0A%20%20%20%20%20%20%20%20%20%20%3Cbutton%20onclick%3D%22smalltalk.Browser._open%28%29%22%3Eclass%20browser%3C/button%3E%0A%20%20%20%20%20%20%20%20%20%20%3Cbutton%20id%3D%22sayHello%22%3Esay%20hello%3C/button%3E%0A%20%20%20%20%20%20%20%20%3C/article%3E%0A%20%20%20%20%20%20%3C/body%3E%0A%20%20%20%20%3C/html%3E%0A%0ANow%20start%20up%20amber%20with%20node.js%20and%20navigate%20to%20%20http%3A//localhost%3A4000/projects/hello/index.html%0A%0AIt%27s%20boring%20so%20far%2C%20so%20lets%20write%20some%20code.%20Click%20the%20button%20to%20open%20the%20class%20browser.%20Find%20an%20existing%20class%20and%20change%20its%20name%20to%20Hello%20and%20its%20package%20to%20HelloApp.%20%0AThen%20click%20save.%20This%20creates%20a%20new%20class%20and%20leaves%20the%20old%20one%20intact%2C%20it%20doesn%27t%20overwrite%20it.%20Your%20class%20will%20look%20like%20this%3A%0A%0A%20%20%20%20Object%20subclass%3A%20%23Hello%0A%20%20%20%20%20%20%20%20instanceVariableNames%3A%20%27%27%0A%20%20%20%20%20%20%20%20package%3A%20%27HelloApp%27%0A%0ANow%20click%20save%20and%20navigate%20to%20your%20new%20class%20in%20its%20new%20package.%0A%20Then%20click%20%27commit%20package%27.%20You%20just%20created%20a%20new%20class%20and%20saved%20your%20work.%20%0AOn%20your%20file%20system%20check%20out%20your%20js%20and%20st%20folders.%20Your%20new%20class%20is%20now%20saved%20in%20both%20JavaScript%20and%20Smalltalk.%0A%0ANow%2C%20refresh%20your%20browser%20page%20and%20reopen%20the%20class%20browser.%20Oh%20no%2C%20your%20new%20class%20is%20gone%21%20To%20load%20your%20new%20class%20automatically%2C%20you%20have%20to%20add%20it%20in%20index.html.%20Make%20your%20JavaScript%20look%20like%20this%3A%0A%0A%0A%20%20%20%20loadAmber%28%7B%0A%20%20%20%20%20%20%20%20files%3A%20%5B%27HelloApp.js%27%5D%2C%0A%20%20%20%20%20%20%20%20prefix%3A%20%27projects/hello/js%27%2C%0A%20%20%20%20%20%20%20%20ready%3A%20function%28%29%20%7B%20%20%20%20%20%20%0A%20%20%20%20%7D%7D%29%3B%20%0A%0ASave%20and%20refresh%20again.%20Now%20your%20class%20is%20loaded%20and%20shows%20up%20in%20the%20class%20browser.%0A%0ANow%2C%20let%27s%20make%20this%20class%20do%20something.%20Create%20a%20new%20message%20in%20the%20class%20browser%20by%20navigating%20to%20your%20class%2C%20then%20clicking%20%27not%20yet%20classified%27%20and%20fill%20in%20a%20simple%20message.%20Try%20this%20for%20example%3A%0A%0A%20%20%20%20begin%0A%09%22Makes%20me%20say%20hello%20to%20the%20user.%22%0A%0A%09%7C%20msg%20button%20%7C%0A%09msg%20%3A%3D%20%27Hello%20world%21%27.%0A%09button%20%3A%3D%20%27%23sayHello%27%20asJQuery.%0A%09button%20click%3A%20%5Bbutton%20after%3A%20%27%3Cp%3E%27%20%2C%20msg%20%2C%20%27%3C/p%3E%27%5D.%0A%0AYour%20message%20isn%27t%20too%20helpful%20if%20it%20doesn%27t%20get%20called.%20Save%20it%2C%20commit%20the%20package%2C%20then%20edit%20index.html%20again.%20You%20can%20write%20JavaScript%20code%20that%20sends%20a%20message%20to%20Smalltalk%3A%0A%0A%20%20%20%20loadAmber%28%7B%0A%20%20%20%20%20%20%20%20files%3A%20%5B%27HelloApp.js%27%5D%2C%0A%20%20%20%20%20%20%20%20prefix%3A%20%27projects/hello/js%27%2C%20//%20path%20for%20js%20files%20i%20think%0A%20%20%20%20%20%20%20%20ready%3A%20function%28%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%24%28function%28%29%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20smalltalk.Hello._new%28%29._begin%28%29%3B%0A%20%20%20%20%20%20%20%20%20%20%7D%29%3B%0A%20%20%20%20%7D%7D%29%3B%20%0A%0AFrom%20there%2C%20you%20can%20create%20new%20Smalltalk%20classes%20and%20messages%20to%20build%20up%20your%20app.%20Enjoy%21%0A")]);})(smalltalk.send((smalltalk.DocChapter || DocChapter), "_new", []));
944
+ smalltalk.send(self['@chapterDiv'], "_contents_", [(function(html){return smalltalk.send(html, "_with_", [smalltalk.send(self, "_selectedChapter", [])]);})]);
945
945
  return self;}
946
946
  }),
947
- smalltalk.TutorialsChapter);
947
+ smalltalk.DocumentationWidget);
948
+
948
949
 
949
950
  smalltalk.addMethod(
950
- unescape('_counterChapter'),
951
+ "_on_",
951
952
  smalltalk.method({
952
- selector: unescape('counterChapter'),
953
- fn: function (){
953
+ selector: "on:",
954
+ fn: function (aBuilder){
954
955
  var self=this;
955
- return (function($rec){smalltalk.send($rec, "_title_", ["The counter application"]);return smalltalk.send($rec, "_contents_", [unescape("%0A%0AThis%20tutorial%20will%20teach%20you%20how%20to%20build%20HTML%20with%20Amber%20using%20jQuery%20and%20the%20HTMLCanvas%20API.%20It%20is%20freely%20adapted%20from%20%0Athe%20%5BSeaside%20counter%20example%5D%28http%3A//www.seaside.st/about/examples/counter%29%0A%0A%23%23The%20counter%20widget%0A%0AThe%20counter%20is%20the%20most%20basic%20example%20of%20a%20widget.%20It%20allows%20to%20increment%20and%20decrement%20a%20number%20by%20clicking%20a%20button.%0A%0AAmber%20already%20comes%20with%20a%20counter%20example%20in%20the%20%60Examples%60%20package.%20To%20avoid%20class%20name%20conflict%2C%20we%27ll%20name%20our%20counter%20class%20%60TCounter%60.%0A%0A%20%20%20%20Widget%20subclass%3A%20%23TCounter%0A%20%20%20%20%20%20%20%20instanceVariableNames%3A%20%27count%20header%27%0A%20%20%20%20%20%20%20%20package%3A%20%27Tutorials%27%0A%0AThe%20first%20method%20is%20used%20to%20initialize%20the%20component%20with%20the%20default%20state%2C%20in%20this%20case%20we%20set%20the%20counter%20to%200%3A%0A%0A%20%20%20%20initialize%0A%20%20%20%20%20%20%20%20super%20initialize.%0A%20%20%20%20%20%20%20%20count%20%3A%3D%200%0A%0AThe%20method%20used%20for%20rendering%20a%20widget%20is%20%60%23renderOn%3A%60.%20It%20takes%20an%20instance%20of%20HTMLCanvas%20as%20parameter.%20%0AThe%20%60header%60%20h1%20kept%20as%20an%20instance%20variable%2C%20so%20when%20the%20count%20value%20change%2C%20we%20can%20update%20it%27s%20contents%20accordingly.%0A%0A%20%20%20%20renderOn%3A%20html%0A%20%20%20%20%20%20%20%20header%20%3A%3D%20html%20h1%20%0A%20%20%20%20%20%20%20%20%20%20%20%20with%3A%20count%20asString%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20yourself.%0A%20%20%20%20%20%20%20%20html%20button%0A%20%20%20%20%20%20%20%20%20%20%20%20with%3A%20%27++%27%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20onClick%3A%20%5Bself%20increase%5D.%0A%20%20%20%20%20%20%20%20html%20button%0A%20%20%20%20%20%20%20%20%20%20%20%20with%3A%20%27--%27%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20onClick%3A%20%5Bself%20decrease%5D%0A%0AThe%20counter%20is%20almost%20ready.%20All%20we%20need%20now%20is%20to%20implement%20the%20two%20action%20methods%20%60%23increase%60%20and%20%60%23decrease%60%20to%20change%20the%20state%20%0Aof%20our%20counter%20and%20update%20its%20header.%0A%0A%20%20%20%20increase%0A%20%20%20%20%20%20%20%20count%20%3A%3D%20count%20+%201.%0A%20%20%20%20%20%20%20%20header%20contents%3A%20%5B%3Ahtml%20%7C%20html%20with%3A%20count%20asString%5D%0A%0A%20%20%20%20decrease%0A%20%20%20%20%20%20%20%20count%20%3A%3D%20count%20-%201.%0A%20%20%20%20%20%20%20%20header%20contents%3A%20%5B%3Ahtml%20%7C%20html%20with%3A%20count%20asString%5D%0A%0A%0AThat%27s%20it%21%20We%20can%20now%20display%20an%20instance%20of%20TCounter%20by%20rendering%20it%20on%20the%20page%20using%20jQuery%3A%0A%0A%20%20%20%20TCounter%20new%20appendToJQuery%3A%20%27body%27%20asJQuery%0A%0A")]);})(smalltalk.send((smalltalk.DocChapter || DocChapter), "_new", []));
956
+ return (function($rec){smalltalk.send($rec, "_builder_", [aBuilder]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
956
957
  return self;}
957
958
  }),
958
- smalltalk.TutorialsChapter);
959
-
959
+ smalltalk.DocumentationWidget.klass);
960
960
 
961
961