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,1376 +1,1376 @@
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
  category: 'accessing',
8
8
  fn: function (){
9
9
  var self=this;
10
- return (($receiver = self['@chapters']) == nil || $receiver == undefined) ? (function(){return (self['@chapters']=smalltalk.send(self, "_buildChapters", []));})() : $receiver;
10
+ return self['@id'];
11
11
  return self;},
12
12
  args: [],
13
- source: unescape('chapters%0A%09%5Echapters%20ifNil%3A%20%5Bchapters%20%3A%3D%20self%20buildChapters%5D'),
14
- messageSends: ["ifNil:", "buildChapters"],
13
+ source: "id\x0a\x09^id",
14
+ messageSends: [],
15
15
  referencedClasses: []
16
16
  }),
17
- smalltalk.DocumentationBuilder);
17
+ smalltalk.ChapterSelectionAnnouncement);
18
18
 
19
19
  smalltalk.addMethod(
20
- unescape('_announcer'),
20
+ "_id_",
21
21
  smalltalk.method({
22
- selector: unescape('announcer'),
22
+ selector: "id:",
23
23
  category: 'accessing',
24
- fn: function (){
24
+ fn: function (aString){
25
25
  var self=this;
26
- return (($receiver = self['@announcer']) == nil || $receiver == undefined) ? (function(){return (self['@announcer']=smalltalk.send((smalltalk.Announcer || Announcer), "_new", []));})() : $receiver;
26
+ (self['@id']=aString);
27
27
  return self;},
28
- args: [],
29
- source: unescape('announcer%0A%09%5Eannouncer%20ifNil%3A%20%5Bannouncer%20%3A%3D%20Announcer%20new%5D'),
30
- messageSends: ["ifNil:", "new"],
31
- referencedClasses: ["Announcer"]
28
+ args: ["aString"],
29
+ source: "id: aString\x0a\x09id := aString",
30
+ messageSends: [],
31
+ referencedClasses: []
32
32
  }),
33
- smalltalk.DocumentationBuilder);
33
+ smalltalk.ChapterSelectionAnnouncement);
34
34
 
35
- smalltalk.addMethod(
36
- unescape('_widget'),
37
- smalltalk.method({
38
- selector: unescape('widget'),
39
- category: 'accessing',
40
- fn: function (){
41
- var self=this;
42
- return (($receiver = self['@widget']) == nil || $receiver == undefined) ? (function(){return (self['@widget']=smalltalk.send((smalltalk.DocumentationWidget || DocumentationWidget), "_on_", [self]));})() : $receiver;
43
- return self;},
44
- args: [],
45
- source: unescape('widget%0A%09%5Ewidget%20ifNil%3A%20%5Bwidget%20%3A%3D%20DocumentationWidget%20on%3A%20self%5D'),
46
- messageSends: ["ifNil:", "on:"],
47
- referencedClasses: ["DocumentationWidget"]
48
- }),
49
- smalltalk.DocumentationBuilder);
50
35
 
36
+
37
+ smalltalk.addClass('ClassSelectionAnnouncement', smalltalk.Object, ['theClass'], 'Documentation');
51
38
  smalltalk.addMethod(
52
- unescape('_buildChapters'),
39
+ "_theClass",
53
40
  smalltalk.method({
54
- selector: unescape('buildChapters'),
55
- category: 'building',
41
+ selector: "theClass",
42
+ category: 'accessing',
56
43
  fn: function (){
57
44
  var self=this;
58
- 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", [])]);})]);
45
+ return self['@theClass'];
59
46
  return self;},
60
47
  args: [],
61
- source: unescape('buildChapters%0A%09%5E%28%28self%20class%20methodDictionary%20values%20sorted%3A%20%5B%3Aa%20%3Ab%20%7C%20a%20selector%20%3C%20b%20selector%5D%29%0A%09%09select%3A%20%5B%3Aeach%20%7C%20each%20category%20%3D%20%27chapters%27%5D%29%0A%09%09collect%3A%20%5B%3Aeach%20%7C%20self%20perform%3A%20each%20selector%5D'),
62
- messageSends: ["collect:", "select:", "sorted:", "values", "methodDictionary", "class", unescape("%3C"), "selector", unescape("%3D"), "category", "perform:"],
48
+ source: "theClass\x0a\x09^theClass",
49
+ messageSends: [],
63
50
  referencedClasses: []
64
51
  }),
65
- smalltalk.DocumentationBuilder);
52
+ smalltalk.ClassSelectionAnnouncement);
66
53
 
67
54
  smalltalk.addMethod(
68
- unescape('_buildOn_'),
55
+ "_theClass_",
69
56
  smalltalk.method({
70
- selector: unescape('buildOn%3A'),
71
- category: 'building',
72
- fn: function (aCanvas){
57
+ selector: "theClass:",
58
+ category: 'accessing',
59
+ fn: function (aClass){
73
60
  var self=this;
74
- smalltalk.send(aCanvas, "_with_", [smalltalk.send(self, "_widget", [])]);
75
- (function($rec){smalltalk.send($rec, "_checkHashChange", []);return smalltalk.send($rec, "_checkHash", []);})(self);
61
+ (self['@theClass']=aClass);
76
62
  return self;},
77
- args: ["aCanvas"],
78
- source: unescape('buildOn%3A%20aCanvas%0A%09aCanvas%20with%3A%20self%20widget.%0A%09self%20%0A%09%09checkHashChange%3B%0A%09%09checkHash'),
79
- messageSends: ["with:", "widget", "checkHashChange", "checkHash"],
63
+ args: ["aClass"],
64
+ source: "theClass: aClass\x0a\x09theClass := aClass",
65
+ messageSends: [],
80
66
  referencedClasses: []
81
67
  }),
82
- smalltalk.DocumentationBuilder);
68
+ smalltalk.ClassSelectionAnnouncement);
83
69
 
84
- smalltalk.addMethod(
85
- unescape('_buildOnJQuery_'),
86
- smalltalk.method({
87
- selector: unescape('buildOnJQuery%3A'),
88
- category: 'building',
89
- fn: function (aJQuery){
90
- var self=this;
91
- smalltalk.send(self, "_buildOn_", [smalltalk.send((smalltalk.HTMLCanvas || HTMLCanvas), "_onJQuery_", [aJQuery])]);
92
- return self;},
93
- args: ["aJQuery"],
94
- source: unescape('buildOnJQuery%3A%20aJQuery%0A%09self%20buildOn%3A%20%28HTMLCanvas%20onJQuery%3A%20aJQuery%29'),
95
- messageSends: ["buildOn:", "onJQuery:"],
96
- referencedClasses: ["HTMLCanvas"]
97
- }),
98
- smalltalk.DocumentationBuilder);
99
70
 
100
71
  smalltalk.addMethod(
101
- unescape('_build'),
72
+ "_on_",
102
73
  smalltalk.method({
103
- selector: unescape('build'),
104
- category: 'building',
105
- fn: function (){
74
+ selector: "on:",
75
+ category: 'instance creation',
76
+ fn: function (aClass){
106
77
  var self=this;
107
- smalltalk.send(self, "_buildOnJQuery_", [smalltalk.send("body", "_asJQuery", [])]);
78
+ return (function($rec){smalltalk.send($rec, "_theClass_", [aClass]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
108
79
  return self;},
109
- args: [],
110
- source: unescape('build%0A%09self%20buildOnJQuery%3A%20%28%27body%27%20asJQuery%29'),
111
- messageSends: ["buildOnJQuery:", "asJQuery"],
80
+ args: ["aClass"],
81
+ source: "on: aClass\x0a\x09^self new\x0a\x09\x09theClass: aClass;\x0a\x09\x09yourself",
82
+ messageSends: ["theClass:", "yourself", "new"],
112
83
  referencedClasses: []
113
84
  }),
114
- smalltalk.DocumentationBuilder);
85
+ smalltalk.ClassSelectionAnnouncement.klass);
115
86
 
87
+
88
+ smalltalk.addClass('DocChapter', smalltalk.Widget, ['title', 'contents', 'parent'], 'Documentation');
116
89
  smalltalk.addMethod(
117
- unescape('_ch1introduction'),
90
+ "_announcer",
118
91
  smalltalk.method({
119
- selector: unescape('ch1introduction'),
120
- category: 'chapters',
92
+ selector: "announcer",
93
+ category: 'accessing',
121
94
  fn: function (){
122
95
  var self=this;
123
- 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", []));
96
+ return smalltalk.send(smalltalk.send((smalltalk.DocumentationBuilder || DocumentationBuilder), "_current", []), "_announcer", []);
124
97
  return self;},
125
98
  args: [],
126
- source: unescape('ch1introduction%0A%09%5EDocChapter%20new%0A%09%09title%3A%20%27Introduction%27%3B%0A%09%09contents%3A%20%27%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%27%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%27%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%27'),
127
- messageSends: ["title:", "contents:", "new"],
128
- referencedClasses: ["DocChapter"]
99
+ source: "announcer\x0a\x09^DocumentationBuilder current announcer",
100
+ messageSends: ["announcer", "current"],
101
+ referencedClasses: ["DocumentationBuilder"]
129
102
  }),
130
- smalltalk.DocumentationBuilder);
103
+ smalltalk.DocChapter);
131
104
 
132
105
  smalltalk.addMethod(
133
- unescape('_ch2differencesWithOtherSmalltalks'),
106
+ "_chapters",
134
107
  smalltalk.method({
135
- selector: unescape('ch2differencesWithOtherSmalltalks'),
136
- category: 'chapters',
108
+ selector: "chapters",
109
+ category: 'accessing',
137
110
  fn: function (){
138
111
  var self=this;
139
- 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", []));
112
+ return [];
140
113
  return self;},
141
114
  args: [],
142
- source: unescape('ch2differencesWithOtherSmalltalks%0A%09%5EDocChapter%20new%0A%09%09title%3A%20%27Differences%20with%20other%20Smalltalks%27%3B%0A%09%09contents%3A%20%27%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%27%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%27'),
143
- messageSends: ["title:", "contents:", "new"],
144
- referencedClasses: ["DocChapter"]
115
+ source: "chapters\x0a\x09\x22A doc chapter can contain sub chapters\x22\x0a\x09^#()",
116
+ messageSends: [],
117
+ referencedClasses: []
145
118
  }),
146
- smalltalk.DocumentationBuilder);
119
+ smalltalk.DocChapter);
147
120
 
148
121
  smalltalk.addMethod(
149
- unescape('_ch3GettingStarted'),
122
+ "_contents",
150
123
  smalltalk.method({
151
- selector: unescape('ch3GettingStarted'),
152
- category: 'chapters',
124
+ selector: "contents",
125
+ category: 'accessing',
153
126
  fn: function (){
154
127
  var self=this;
155
- 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", []));
128
+ return (($receiver = self['@contents']) == nil || $receiver == undefined) ? (function(){return "";})() : $receiver;
156
129
  return self;},
157
130
  args: [],
158
- source: unescape('ch3GettingStarted%0A%09%5EDocChapter%20new%0A%09%09title%3A%20%27Getting%20started%27%3B%0A%09%09contents%3A%20%27%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%27%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%27%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%27%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%27%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%27'),
159
- messageSends: ["title:", "contents:", "new"],
160
- referencedClasses: ["DocChapter"]
131
+ source: "contents\x0a\x09^contents ifNil: ['']",
132
+ messageSends: ["ifNil:"],
133
+ referencedClasses: []
161
134
  }),
162
- smalltalk.DocumentationBuilder);
135
+ smalltalk.DocChapter);
163
136
 
164
137
  smalltalk.addMethod(
165
- unescape('_ch5Index'),
138
+ "_contents_",
166
139
  smalltalk.method({
167
- selector: unescape('ch5Index'),
168
- category: 'chapters',
169
- fn: function (){
140
+ selector: "contents:",
141
+ category: 'accessing',
142
+ fn: function (aString){
170
143
  var self=this;
171
- return smalltalk.send((smalltalk.ClassesIndexChapter || ClassesIndexChapter), "_new", []);
144
+ (self['@contents']=aString);
172
145
  return self;},
173
- args: [],
174
- source: unescape('ch5Index%0A%09%5EClassesIndexChapter%20new'),
175
- messageSends: ["new"],
176
- referencedClasses: ["ClassesIndexChapter"]
146
+ args: ["aString"],
147
+ source: "contents: aString\x0a\x09contents := aString",
148
+ messageSends: [],
149
+ referencedClasses: []
177
150
  }),
178
- smalltalk.DocumentationBuilder);
151
+ smalltalk.DocChapter);
179
152
 
180
153
  smalltalk.addMethod(
181
- unescape('_ch6KernelObjects'),
154
+ "_cssClass",
182
155
  smalltalk.method({
183
- selector: unescape('ch6KernelObjects'),
184
- category: 'chapters',
156
+ selector: "cssClass",
157
+ category: 'accessing',
185
158
  fn: function (){
186
159
  var self=this;
187
- return smalltalk.send((smalltalk.PackageDocChapter || PackageDocChapter), "_on_", [smalltalk.send((smalltalk.Package || Package), "_named_", [unescape("Kernel-Objects")])]);
160
+ return "doc_chapter";
188
161
  return self;},
189
162
  args: [],
190
- source: unescape('ch6KernelObjects%0A%09%5EPackageDocChapter%20on%3A%20%28Package%20named%3A%20%27Kernel-Objects%27%29'),
191
- messageSends: ["on:", "named:"],
192
- referencedClasses: ["PackageDocChapter", "Package"]
163
+ source: "cssClass\x0a\x09^'doc_chapter'",
164
+ messageSends: [],
165
+ referencedClasses: []
193
166
  }),
194
- smalltalk.DocumentationBuilder);
167
+ smalltalk.DocChapter);
195
168
 
196
169
  smalltalk.addMethod(
197
- unescape('_ch7KernelClasses'),
170
+ "_displayChapter_",
198
171
  smalltalk.method({
199
- selector: unescape('ch7KernelClasses'),
200
- category: 'chapters',
201
- fn: function (){
172
+ selector: "displayChapter:",
173
+ category: 'actions',
174
+ fn: function (aChapter){
202
175
  var self=this;
203
- return smalltalk.send((smalltalk.PackageDocChapter || PackageDocChapter), "_on_", [smalltalk.send((smalltalk.Package || Package), "_named_", [unescape("Kernel-Classes")])]);
176
+ smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.DocumentationBuilder || DocumentationBuilder), "_current", []), "_widget", []), "_displayChapter_", [aChapter]);
204
177
  return self;},
205
- args: [],
206
- source: unescape('ch7KernelClasses%0A%09%5EPackageDocChapter%20on%3A%20%28Package%20named%3A%20%27Kernel-Classes%27%29'),
207
- messageSends: ["on:", "named:"],
208
- referencedClasses: ["PackageDocChapter", "Package"]
178
+ args: ["aChapter"],
179
+ source: "displayChapter: aChapter\x0a\x09DocumentationBuilder current widget displayChapter: aChapter",
180
+ messageSends: ["displayChapter:", "widget", "current"],
181
+ referencedClasses: ["DocumentationBuilder"]
209
182
  }),
210
- smalltalk.DocumentationBuilder);
183
+ smalltalk.DocChapter);
211
184
 
212
185
  smalltalk.addMethod(
213
- unescape('_ch4Tutorials'),
186
+ "_htmlContents",
214
187
  smalltalk.method({
215
- selector: unescape('ch4Tutorials'),
216
- category: 'chapters',
188
+ selector: "htmlContents",
189
+ category: 'accessing',
217
190
  fn: function (){
218
191
  var self=this;
219
- return smalltalk.send((smalltalk.TutorialsChapter || TutorialsChapter), "_new", []);
192
+ return smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Showdown || Showdown), "_at_", [smalltalk.symbolFor("converter")]), "_new", []), "_makeHtml_", [smalltalk.send(self, "_contents", [])]);
220
193
  return self;},
221
194
  args: [],
222
- source: unescape('ch4Tutorials%0A%09%5ETutorialsChapter%20new'),
223
- messageSends: ["new"],
224
- referencedClasses: ["TutorialsChapter"]
195
+ source: "htmlContents\x0a\x09^(Showdown at: #converter) new makeHtml: self contents",
196
+ messageSends: ["makeHtml:", "new", "at:", "contents"],
197
+ referencedClasses: ["Showdown"]
225
198
  }),
226
- smalltalk.DocumentationBuilder);
199
+ smalltalk.DocChapter);
227
200
 
228
201
  smalltalk.addMethod(
229
- unescape('_checkHashChange'),
202
+ "_id",
230
203
  smalltalk.method({
231
- selector: unescape('checkHashChange'),
232
- category: 'routing',
204
+ selector: "id",
205
+ category: 'accessing',
233
206
  fn: function (){
234
207
  var self=this;
235
- smalltalk.send(smalltalk.send((typeof window == 'undefined' ? nil : window), "_jQuery_", [(typeof window == 'undefined' ? nil : window)]), "_bind_do_", ["hashchange", (function(){return smalltalk.send(self, "_checkHash", []);})]);
208
+ return smalltalk.send(smalltalk.send(self, "_title", []), "_replace_with_", [" ", "-"]);
236
209
  return self;},
237
210
  args: [],
238
- source: unescape('checkHashChange%0A%09%28window%20jQuery%3A%20window%29%20bind%3A%20%27hashchange%27%20do%3A%20%5Bself%20checkHash%5D'),
239
- messageSends: ["bind:do:", "jQuery:", "checkHash"],
211
+ source: "id\x0a\x09\x22The id is used in url fragments. \x0a\x09It must be unique amoung all chapters\x22\x0a\x09^self title replace: ' ' with: '-'",
212
+ messageSends: ["replace:with:", "title"],
240
213
  referencedClasses: []
241
214
  }),
242
- smalltalk.DocumentationBuilder);
215
+ smalltalk.DocChapter);
243
216
 
244
217
  smalltalk.addMethod(
245
- unescape('_checkHash'),
218
+ "_initialize",
246
219
  smalltalk.method({
247
- selector: unescape('checkHash'),
248
- category: 'routing',
220
+ selector: "initialize",
221
+ category: 'initialization',
249
222
  fn: function (){
250
223
  var self=this;
251
- var hash=nil;
252
- var presentation=nil;
253
- (hash=smalltalk.send(smalltalk.send(smalltalk.send((typeof document == 'undefined' ? nil : document), "_location", []), "_hash", []), "_replace_with_", [unescape("%5E%23"), ""]));
254
- 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", []))]);
224
+ smalltalk.send(self, "_initialize", [], smalltalk.DocChapter.superclass || nil);
225
+ smalltalk.send(self, "_subscribe", []);
255
226
  return self;},
256
227
  args: [],
257
- source: unescape('checkHash%0A%09%7C%20hash%20presentation%20%7C%0A%09hash%20%3A%3D%20document%20location%20hash%20%20replace%3A%20%27%5E%23%27%20with%3A%20%27%27.%0A%09self%20announcer%20announce%3A%20%28ChapterSelectionAnnouncement%20new%20%0A%09%09id%3A%20hash%3B%20%0A%09%09yourself%29'),
258
- messageSends: ["replace:with:", "hash", "location", "announce:", "announcer", "id:", "yourself", "new"],
259
- referencedClasses: ["ChapterSelectionAnnouncement"]
228
+ source: "initialize\x0a\x09super initialize.\x0a\x09self subscribe",
229
+ messageSends: ["initialize", "subscribe"],
230
+ referencedClasses: []
260
231
  }),
261
- smalltalk.DocumentationBuilder);
232
+ smalltalk.DocChapter);
262
233
 
263
234
  smalltalk.addMethod(
264
- unescape('_update'),
235
+ "_level",
265
236
  smalltalk.method({
266
- selector: unescape('update'),
267
- category: 'updating',
237
+ selector: "level",
238
+ category: 'accessing',
268
239
  fn: function (){
269
240
  var self=this;
270
- (self['@chapters']=nil);
271
- (self['@announcer']=nil);
272
- (self['@widget']=nil);
273
- smalltalk.send(smalltalk.send((typeof window == 'undefined' ? nil : window), "_jQuery_", [".documentation"]), "_remove", []);
274
- smalltalk.send(self, "_build", []);
241
+ 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)]));})();
275
242
  return self;},
276
243
  args: [],
277
- source: unescape('update%0A%09chapters%20%3A%3D%20nil.%0A%09announcer%20%3A%3D%20nil.%0A%09widget%20%3A%3D%20nil.%0A%09%28window%20jQuery%3A%20%27.documentation%27%29%20remove.%0A%09self%20build'),
278
- messageSends: ["remove", "jQuery:", "build"],
244
+ source: "level\x0a\x09^self parent ifNil: [1] ifNotNil: [self parent level +1]",
245
+ messageSends: ["ifNil:ifNotNil:", "parent", "+", "level"],
279
246
  referencedClasses: []
280
247
  }),
281
- smalltalk.DocumentationBuilder);
248
+ smalltalk.DocChapter);
282
249
 
283
250
  smalltalk.addMethod(
284
- unescape('_ch8KernelCollection'),
251
+ "_level_",
285
252
  smalltalk.method({
286
- selector: unescape('ch8KernelCollection'),
287
- category: 'chapters',
288
- fn: function (){
253
+ selector: "level:",
254
+ category: 'accessing',
255
+ fn: function (anInteger){
289
256
  var self=this;
290
- return smalltalk.send((smalltalk.PackageDocChapter || PackageDocChapter), "_on_", [smalltalk.send((smalltalk.Package || Package), "_named_", [unescape("Kernel-Collections")])]);
257
+ (level=anInteger);
291
258
  return self;},
292
- args: [],
293
- source: unescape('ch8KernelCollection%0A%09%5EPackageDocChapter%20on%3A%20%28Package%20named%3A%20%27Kernel-Collections%27%29'),
294
- messageSends: ["on:", "named:"],
295
- referencedClasses: ["PackageDocChapter", "Package"]
259
+ args: ["anInteger"],
260
+ source: "level: anInteger\x0a\x09level := anInteger",
261
+ messageSends: [],
262
+ referencedClasses: []
296
263
  }),
297
- smalltalk.DocumentationBuilder);
264
+ smalltalk.DocChapter);
298
265
 
299
266
  smalltalk.addMethod(
300
- unescape('_ch9KernelMethods'),
267
+ "_parent",
301
268
  smalltalk.method({
302
- selector: unescape('ch9KernelMethods'),
303
- category: 'chapters',
269
+ selector: "parent",
270
+ category: 'accessing',
304
271
  fn: function (){
305
272
  var self=this;
306
- return smalltalk.send((smalltalk.PackageDocChapter || PackageDocChapter), "_on_", [smalltalk.send((smalltalk.Package || Package), "_named_", [unescape("Kernel-Methods")])]);
273
+ return self['@parent'];
307
274
  return self;},
308
275
  args: [],
309
- source: unescape('ch9KernelMethods%0A%09%5EPackageDocChapter%20on%3A%20%28Package%20named%3A%20%27Kernel-Methods%27%29'),
310
- messageSends: ["on:", "named:"],
311
- referencedClasses: ["PackageDocChapter", "Package"]
276
+ source: "parent\x0a\x09^parent",
277
+ messageSends: [],
278
+ referencedClasses: []
312
279
  }),
313
- smalltalk.DocumentationBuilder);
314
-
280
+ smalltalk.DocChapter);
315
281
 
316
- smalltalk.DocumentationBuilder.klass.iVarNames = ['current'];
317
282
  smalltalk.addMethod(
318
- unescape('_current'),
283
+ "_parent_",
319
284
  smalltalk.method({
320
- selector: unescape('current'),
285
+ selector: "parent:",
321
286
  category: 'accessing',
322
- fn: function (){
287
+ fn: function (aChapter){
323
288
  var self=this;
324
- return (($receiver = self['@current']) == nil || $receiver == undefined) ? (function(){return (self['@current']=smalltalk.send(self, "_new", []));})() : $receiver;
289
+ (self['@parent']=aChapter);
325
290
  return self;},
326
- args: [],
327
- source: unescape('current%0A%09%5Ecurrent%20ifNil%3A%20%5Bcurrent%20%3A%3D%20self%20new%5D'),
328
- messageSends: ["ifNil:", "new"],
291
+ args: ["aChapter"],
292
+ source: "parent: aChapter\x0a\x09parent := aChapter",
293
+ messageSends: [],
329
294
  referencedClasses: []
330
295
  }),
331
- smalltalk.DocumentationBuilder.klass);
296
+ smalltalk.DocChapter);
332
297
 
333
298
  smalltalk.addMethod(
334
- unescape('_initialize'),
299
+ "_renderDocOn_",
335
300
  smalltalk.method({
336
- selector: unescape('initialize'),
337
- category: 'initialization',
338
- fn: function (){
301
+ selector: "renderDocOn:",
302
+ category: 'rendering',
303
+ fn: function (html){
339
304
  var self=this;
340
- smalltalk.send(smalltalk.send(self, "_current", []), "_build", []);
305
+ var div=nil;
306
+ smalltalk.send(smalltalk.send(html, "_h1", []), "_with_", [smalltalk.send(self, "_title", [])]);
307
+ smalltalk.send(self, "_renderNavigationOn_", [html]);
308
+ (div=smalltalk.send(smalltalk.send(html, "_div", []), "_class_", ["contents"]));
309
+ smalltalk.send(smalltalk.send(div, "_asJQuery", []), "_html_", [smalltalk.send(self, "_htmlContents", [])]);
341
310
  return self;},
342
- args: [],
343
- source: unescape('initialize%0A%09self%20current%20build'),
344
- messageSends: ["build", "current"],
311
+ args: ["html"],
312
+ source: "renderDocOn: html\x0a\x09| div |\x0a\x09html h1 with: self title.\x0a\x09self renderNavigationOn: html.\x0a\x09div := html div class: 'contents'.\x0a\x09div asJQuery html: self htmlContents",
313
+ messageSends: ["with:", "h1", "title", "renderNavigationOn:", "class:", "div", "html:", "asJQuery", "htmlContents"],
345
314
  referencedClasses: []
346
315
  }),
347
- smalltalk.DocumentationBuilder.klass);
348
-
316
+ smalltalk.DocChapter);
349
317
 
350
- smalltalk.addClass('DocChapter', smalltalk.Widget, ['title', 'contents', 'parent'], 'Documentation');
351
318
  smalltalk.addMethod(
352
- unescape('_title'),
319
+ "_renderLinksOn_",
353
320
  smalltalk.method({
354
- selector: unescape('title'),
355
- category: 'accessing',
356
- fn: function (){
321
+ selector: "renderLinksOn:",
322
+ category: 'rendering',
323
+ fn: function (html){
357
324
  var self=this;
358
- return (($receiver = self['@title']) == nil || $receiver == undefined) ? (function(){return "";})() : $receiver;
325
+ (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", []));
359
326
  return self;},
360
- args: [],
361
- source: unescape('title%0A%09%5Etitle%20ifNil%3A%20%5B%27%27%5D'),
362
- messageSends: ["ifNil:"],
327
+ args: ["html"],
328
+ source: "renderLinksOn: html\x0a\x09html ul \x0a\x09\x09class: 'links';\x0a\x09\x09with: [\x0a\x09\x09\x09self chapters do: [:each |\x0a\x09\x09\x09\x09html li with: [\x0a\x09\x09\x09\x09\x09html a\x0a\x09\x09\x09\x09\x09\x09with: each title;\x0a\x09\x09\x09\x09\x09\x09onClick: [self selectChapter: each]]]]",
329
+ messageSends: ["class:", "with:", "do:", "chapters", "li", "title", "onClick:", "selectChapter:", "a", "ul"],
363
330
  referencedClasses: []
364
331
  }),
365
332
  smalltalk.DocChapter);
366
333
 
367
334
  smalltalk.addMethod(
368
- unescape('_title_'),
335
+ "_renderNavigationOn_",
369
336
  smalltalk.method({
370
- selector: unescape('title%3A'),
371
- category: 'accessing',
372
- fn: function (aString){
337
+ selector: "renderNavigationOn:",
338
+ category: 'rendering',
339
+ fn: function (html){
373
340
  var self=this;
374
- (self['@title']=aString);
341
+ (($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;
375
342
  return self;},
376
- args: ["aString"],
377
- source: unescape('title%3A%20aString%0A%09title%20%3A%3D%20aString'),
378
- messageSends: [],
343
+ args: ["html"],
344
+ source: "renderNavigationOn: html\x0a\x09self parent ifNotNil: [\x0a\x09\x09html div \x0a\x09\x09\x09class: 'navigation'; with: [\x0a\x09\x09\x09\x09html a\x0a\x09\x09\x09\x09\x09with: '← back to ', self parent title;\x0a\x09\x09\x09\x09\x09onClick: [self selectChapter: self parent]]]",
345
+ messageSends: ["ifNotNil:", "parent", "class:", "with:", ",", "title", "onClick:", "selectChapter:", "a", "div"],
379
346
  referencedClasses: []
380
347
  }),
381
348
  smalltalk.DocChapter);
382
349
 
383
350
  smalltalk.addMethod(
384
- unescape('_contents'),
351
+ "_renderOn_",
385
352
  smalltalk.method({
386
- selector: unescape('contents'),
387
- category: 'accessing',
388
- fn: function (){
389
- var self=this;
390
- return (($receiver = self['@contents']) == nil || $receiver == undefined) ? (function(){return "";})() : $receiver;
353
+ selector: "renderOn:",
354
+ category: 'rendering',
355
+ fn: function (html){
356
+ var self=this;
357
+ (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", []));
391
358
  return self;},
392
- args: [],
393
- source: unescape('contents%0A%09%5Econtents%20ifNil%3A%20%5B%27%27%5D'),
394
- messageSends: ["ifNil:"],
359
+ args: ["html"],
360
+ source: "renderOn: html\x0a\x09html div \x0a\x09\x09class: self cssClass;\x0a\x09\x09with: [\x0a\x09\x09\x09self renderDocOn: html.\x0a\x09\x09\x09self renderLinksOn: html]",
361
+ messageSends: ["class:", "cssClass", "with:", "renderDocOn:", "renderLinksOn:", "div"],
395
362
  referencedClasses: []
396
363
  }),
397
364
  smalltalk.DocChapter);
398
365
 
399
366
  smalltalk.addMethod(
400
- unescape('_contents_'),
367
+ "_selectChapter_",
401
368
  smalltalk.method({
402
- selector: unescape('contents%3A'),
403
- category: 'accessing',
404
- fn: function (aString){
369
+ selector: "selectChapter:",
370
+ category: 'actions',
371
+ fn: function (aChapter){
405
372
  var self=this;
406
- (self['@contents']=aString);
373
+ smalltalk.send(smalltalk.send((typeof document == 'undefined' ? nil : document), "_location", []), "_hash_", [smalltalk.send(aChapter, "_id", [])]);
407
374
  return self;},
408
- args: ["aString"],
409
- source: unescape('contents%3A%20aString%0A%09contents%20%3A%3D%20aString'),
410
- messageSends: [],
375
+ args: ["aChapter"],
376
+ source: "selectChapter: aChapter\x0a\x09document location hash: aChapter id",
377
+ messageSends: ["hash:", "location", "id"],
411
378
  referencedClasses: []
412
379
  }),
413
380
  smalltalk.DocChapter);
414
381
 
415
382
  smalltalk.addMethod(
416
- unescape('_htmlContents'),
383
+ "_selectClass_",
417
384
  smalltalk.method({
418
- selector: unescape('htmlContents'),
419
- category: 'accessing',
420
- fn: function (){
385
+ selector: "selectClass:",
386
+ category: 'actions',
387
+ fn: function (aClass){
421
388
  var self=this;
422
- return smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.Showdown || Showdown), "_at_", [smalltalk.symbolFor("converter")]), "_new", []), "_makeHtml_", [smalltalk.send(self, "_contents", [])]);
389
+ smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.DocumentationBuilder || DocumentationBuilder), "_current", []), "_announcer", []), "_announce_", [smalltalk.send((smalltalk.ClassSelectionAnnouncement || ClassSelectionAnnouncement), "_on_", [aClass])]);
423
390
  return self;},
424
- args: [],
425
- source: unescape('htmlContents%0A%09%5E%28Showdown%20at%3A%20%23converter%29%20new%20makeHtml%3A%20self%20contents'),
426
- messageSends: ["makeHtml:", "new", "at:", "contents"],
427
- referencedClasses: ["Showdown"]
391
+ args: ["aClass"],
392
+ source: "selectClass: aClass\x0a\x09DocumentationBuilder current announcer announce: (ClassSelectionAnnouncement on: aClass)",
393
+ messageSends: ["announce:", "announcer", "current", "on:"],
394
+ referencedClasses: ["DocumentationBuilder", "ClassSelectionAnnouncement"]
428
395
  }),
429
396
  smalltalk.DocChapter);
430
397
 
431
398
  smalltalk.addMethod(
432
- unescape('_chapters'),
399
+ "_subscribe",
433
400
  smalltalk.method({
434
- selector: unescape('chapters'),
435
- category: 'accessing',
401
+ selector: "subscribe",
402
+ category: 'subscriptions',
436
403
  fn: function (){
437
404
  var self=this;
438
- return [];
405
+ 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]);})]));})]);
439
406
  return self;},
440
407
  args: [],
441
- source: unescape('chapters%0A%09%22A%20doc%20chapter%20can%20contain%20sub%20chapters%22%0A%09%5E%23%28%29'),
442
- messageSends: [],
443
- referencedClasses: []
408
+ source: "subscribe\x0a\x09self announcer on: ChapterSelectionAnnouncement do: [:ann |\x0a\x09\x09ann id = self id ifTrue: [self displayChapter: self]]",
409
+ messageSends: ["on:do:", "announcer", "ifTrue:", "=", "id", "displayChapter:"],
410
+ referencedClasses: ["ChapterSelectionAnnouncement"]
444
411
  }),
445
412
  smalltalk.DocChapter);
446
413
 
447
414
  smalltalk.addMethod(
448
- unescape('_cssClass'),
415
+ "_title",
449
416
  smalltalk.method({
450
- selector: unescape('cssClass'),
417
+ selector: "title",
451
418
  category: 'accessing',
452
419
  fn: function (){
453
420
  var self=this;
454
- return "doc_chapter";
421
+ return (($receiver = self['@title']) == nil || $receiver == undefined) ? (function(){return "";})() : $receiver;
455
422
  return self;},
456
423
  args: [],
457
- source: unescape('cssClass%0A%09%5E%27doc_chapter%27'),
458
- messageSends: [],
424
+ source: "title\x0a\x09^title ifNil: ['']",
425
+ messageSends: ["ifNil:"],
459
426
  referencedClasses: []
460
427
  }),
461
428
  smalltalk.DocChapter);
462
429
 
463
430
  smalltalk.addMethod(
464
- unescape('_level'),
431
+ "_title_",
465
432
  smalltalk.method({
466
- selector: unescape('level'),
433
+ selector: "title:",
467
434
  category: 'accessing',
468
- fn: function (){
435
+ fn: function (aString){
469
436
  var self=this;
470
- 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)]));})();
437
+ (self['@title']=aString);
471
438
  return self;},
472
- args: [],
473
- source: unescape('level%0A%09%5Eself%20parent%20ifNil%3A%20%5B1%5D%20ifNotNil%3A%20%5Bself%20parent%20level%20+1%5D'),
474
- messageSends: ["ifNil:ifNotNil:", "parent", unescape("+"), "level"],
439
+ args: ["aString"],
440
+ source: "title: aString\x0a\x09title := aString",
441
+ messageSends: [],
475
442
  referencedClasses: []
476
443
  }),
477
444
  smalltalk.DocChapter);
478
445
 
446
+
447
+
448
+ smalltalk.addClass('ClassDocChapter', smalltalk.DocChapter, ['theClass'], 'Documentation');
479
449
  smalltalk.addMethod(
480
- unescape('_level_'),
450
+ "_contents",
481
451
  smalltalk.method({
482
- selector: unescape('level%3A'),
452
+ selector: "contents",
483
453
  category: 'accessing',
484
- fn: function (anInteger){
454
+ fn: function (){
485
455
  var self=this;
486
- (level=anInteger);
456
+ 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", []);})]));
487
457
  return self;},
488
- args: ["anInteger"],
489
- source: unescape('level%3A%20anInteger%0A%09level%20%3A%3D%20anInteger'),
490
- messageSends: [],
458
+ args: [],
459
+ source: "contents\x0a\x09^self theClass comment isEmpty\x0a\x09\x09ifTrue: [self theClass name, ' is not documented yet.']\x0a\x09\x09ifFalse: [self theClass comment]",
460
+ messageSends: ["ifTrue:ifFalse:", "isEmpty", "comment", "theClass", ",", "name"],
491
461
  referencedClasses: []
492
462
  }),
493
- smalltalk.DocChapter);
463
+ smalltalk.ClassDocChapter);
494
464
 
495
465
  smalltalk.addMethod(
496
- unescape('_parent'),
466
+ "_cssClass",
497
467
  smalltalk.method({
498
- selector: unescape('parent'),
468
+ selector: "cssClass",
499
469
  category: 'accessing',
500
470
  fn: function (){
501
471
  var self=this;
502
- return self['@parent'];
472
+ return smalltalk.send("doc_class ", "__comma", [smalltalk.send(self, "_cssClass", [], smalltalk.ClassDocChapter.superclass || nil)]);
503
473
  return self;},
504
474
  args: [],
505
- source: unescape('parent%0A%09%5Eparent'),
506
- messageSends: [],
475
+ source: "cssClass\x0a\x09^'doc_class ', super cssClass",
476
+ messageSends: [",", "cssClass"],
507
477
  referencedClasses: []
508
478
  }),
509
- smalltalk.DocChapter);
479
+ smalltalk.ClassDocChapter);
510
480
 
511
481
  smalltalk.addMethod(
512
- unescape('_parent_'),
482
+ "_initializeWithClass_",
513
483
  smalltalk.method({
514
- selector: unescape('parent%3A'),
484
+ selector: "initializeWithClass:",
515
485
  category: 'accessing',
516
- fn: function (aChapter){
486
+ fn: function (aClass){
517
487
  var self=this;
518
- (self['@parent']=aChapter);
488
+ (self['@theClass']=aClass);
519
489
  return self;},
520
- args: ["aChapter"],
521
- source: unescape('parent%3A%20aChapter%0A%09parent%20%3A%3D%20aChapter'),
490
+ args: ["aClass"],
491
+ source: "initializeWithClass: aClass\x0a\x09theClass := aClass",
522
492
  messageSends: [],
523
493
  referencedClasses: []
524
494
  }),
525
- smalltalk.DocChapter);
495
+ smalltalk.ClassDocChapter);
526
496
 
527
497
  smalltalk.addMethod(
528
- unescape('_id'),
498
+ "_renderLinksOn_",
529
499
  smalltalk.method({
530
- selector: unescape('id'),
531
- category: 'accessing',
532
- fn: function (){
500
+ selector: "renderLinksOn:",
501
+ category: 'rendering',
502
+ fn: function (html){
533
503
  var self=this;
534
- return smalltalk.send(smalltalk.send(self, "_title", []), "_replace_with_", [" ", unescape("-")]);
504
+ (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", []));
535
505
  return self;},
536
- args: [],
537
- source: unescape('id%0A%09%22The%20id%20is%20used%20in%20url%20fragments.%20%0A%09It%20must%20be%20unique%20amoung%20all%20chapters%22%0A%09%5Eself%20title%20replace%3A%20%27%20%27%20with%3A%20%27-%27'),
538
- messageSends: ["replace:with:", "title"],
539
- referencedClasses: []
506
+ args: ["html"],
507
+ source: "renderLinksOn: html\x0a\x09html ul \x0a\x09\x09class: 'links';\x0a\x09\x09with: [\x0a\x09\x09\x09html li with: [html a\x0a\x09\x09\x09\x09with: 'Browse this class';\x0a\x09\x09\x09\x09onClick: [Browser openOn: self theClass]]]",
508
+ messageSends: ["class:", "with:", "li", "onClick:", "openOn:", "theClass", "a", "ul"],
509
+ referencedClasses: ["Browser"]
540
510
  }),
541
- smalltalk.DocChapter);
511
+ smalltalk.ClassDocChapter);
542
512
 
543
513
  smalltalk.addMethod(
544
- unescape('_announcer'),
514
+ "_subscribe",
545
515
  smalltalk.method({
546
- selector: unescape('announcer'),
547
- category: 'accessing',
516
+ selector: "subscribe",
517
+ category: 'subscriptions',
548
518
  fn: function (){
549
519
  var self=this;
550
- return smalltalk.send(smalltalk.send((smalltalk.DocumentationBuilder || DocumentationBuilder), "_current", []), "_announcer", []);
520
+ smalltalk.send(self, "_subscribe", [], smalltalk.ClassDocChapter.superclass || nil);
521
+ 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]);})]));})]);
551
522
  return self;},
552
523
  args: [],
553
- source: unescape('announcer%0A%09%5EDocumentationBuilder%20current%20announcer'),
554
- messageSends: ["announcer", "current"],
555
- referencedClasses: ["DocumentationBuilder"]
556
- }),
557
- smalltalk.DocChapter);
558
-
559
- smalltalk.addMethod(
560
- unescape('_selectClass_'),
561
- smalltalk.method({
562
- selector: unescape('selectClass%3A'),
563
- category: 'actions',
564
- fn: function (aClass){
565
- var self=this;
566
- smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.DocumentationBuilder || DocumentationBuilder), "_current", []), "_announcer", []), "_announce_", [smalltalk.send((smalltalk.ClassSelectionAnnouncement || ClassSelectionAnnouncement), "_on_", [aClass])]);
567
- return self;},
568
- args: ["aClass"],
569
- source: unescape('selectClass%3A%20aClass%0A%09DocumentationBuilder%20current%20announcer%20announce%3A%20%28ClassSelectionAnnouncement%20on%3A%20aClass%29'),
570
- messageSends: ["announce:", "announcer", "current", "on:"],
571
- referencedClasses: ["DocumentationBuilder", "ClassSelectionAnnouncement"]
524
+ source: "subscribe\x0a\x09super subscribe.\x0a\x09self announcer \x0a\x09\x09on: ClassSelectionAnnouncement do: [:ann |\x0a\x09\x09\x09ann theClass = self theClass ifTrue: [\x0a\x09\x09\x09\x09self selectChapter: self]]",
525
+ messageSends: ["subscribe", "on:do:", "announcer", "ifTrue:", "=", "theClass", "selectChapter:"],
526
+ referencedClasses: ["ClassSelectionAnnouncement"]
572
527
  }),
573
- smalltalk.DocChapter);
528
+ smalltalk.ClassDocChapter);
574
529
 
575
530
  smalltalk.addMethod(
576
- unescape('_selectChapter_'),
531
+ "_theClass",
577
532
  smalltalk.method({
578
- selector: unescape('selectChapter%3A'),
579
- category: 'actions',
580
- fn: function (aChapter){
533
+ selector: "theClass",
534
+ category: 'accessing',
535
+ fn: function (){
581
536
  var self=this;
582
- smalltalk.send(smalltalk.send((typeof document == 'undefined' ? nil : document), "_location", []), "_hash_", [smalltalk.send(aChapter, "_id", [])]);
537
+ return self['@theClass'];
583
538
  return self;},
584
- args: ["aChapter"],
585
- source: unescape('selectChapter%3A%20aChapter%0A%09document%20location%20hash%3A%20aChapter%20id'),
586
- messageSends: ["hash:", "location", "id"],
539
+ args: [],
540
+ source: "theClass\x0a\x09^theClass",
541
+ messageSends: [],
587
542
  referencedClasses: []
588
543
  }),
589
- smalltalk.DocChapter);
590
-
591
- smalltalk.addMethod(
592
- unescape('_displayChapter_'),
593
- smalltalk.method({
594
- selector: unescape('displayChapter%3A'),
595
- category: 'actions',
596
- fn: function (aChapter){
597
- var self=this;
598
- smalltalk.send(smalltalk.send(smalltalk.send((smalltalk.DocumentationBuilder || DocumentationBuilder), "_current", []), "_widget", []), "_displayChapter_", [aChapter]);
599
- return self;},
600
- args: ["aChapter"],
601
- source: unescape('displayChapter%3A%20aChapter%0A%09DocumentationBuilder%20current%20widget%20displayChapter%3A%20aChapter'),
602
- messageSends: ["displayChapter:", "widget", "current"],
603
- referencedClasses: ["DocumentationBuilder"]
604
- }),
605
- smalltalk.DocChapter);
544
+ smalltalk.ClassDocChapter);
606
545
 
607
546
  smalltalk.addMethod(
608
- unescape('_initialize'),
547
+ "_title",
609
548
  smalltalk.method({
610
- selector: unescape('initialize'),
611
- category: 'initialization',
549
+ selector: "title",
550
+ category: 'accessing',
612
551
  fn: function (){
613
552
  var self=this;
614
- smalltalk.send(self, "_initialize", [], smalltalk.Widget);
615
- smalltalk.send(self, "_subscribe", []);
553
+ return smalltalk.send(smalltalk.send(self, "_theClass", []), "_name", []);
616
554
  return self;},
617
555
  args: [],
618
- source: unescape('initialize%0A%09super%20initialize.%0A%09self%20subscribe'),
619
- messageSends: ["initialize", "subscribe"],
556
+ source: "title\x0a\x09^self theClass name",
557
+ messageSends: ["name", "theClass"],
620
558
  referencedClasses: []
621
559
  }),
622
- smalltalk.DocChapter);
560
+ smalltalk.ClassDocChapter);
561
+
623
562
 
624
563
  smalltalk.addMethod(
625
- unescape('_renderOn_'),
564
+ "_on_",
626
565
  smalltalk.method({
627
- selector: unescape('renderOn%3A'),
628
- category: 'rendering',
629
- fn: function (html){
566
+ selector: "on:",
567
+ category: 'accessing',
568
+ fn: function (aClass){
630
569
  var self=this;
631
- (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", []));
570
+ return (function($rec){smalltalk.send($rec, "_initializeWithClass_", [aClass]);smalltalk.send($rec, "_initialize", []);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_basicNew", []));
632
571
  return self;},
633
- args: ["html"],
634
- source: unescape('renderOn%3A%20html%0A%09html%20div%20%0A%09%09class%3A%20self%20cssClass%3B%0A%09%09with%3A%20%5B%0A%09%09%09self%20renderDocOn%3A%20html.%0A%09%09%09self%20renderLinksOn%3A%20html%5D'),
635
- messageSends: ["class:", "cssClass", "with:", "renderDocOn:", "renderLinksOn:", "div"],
572
+ args: ["aClass"],
573
+ source: "on: aClass\x0a\x09^self basicNew\x0a\x09\x09initializeWithClass: aClass;\x0a\x09\x09initialize;\x0a\x09\x09yourself",
574
+ messageSends: ["initializeWithClass:", "initialize", "yourself", "basicNew"],
636
575
  referencedClasses: []
637
576
  }),
638
- smalltalk.DocChapter);
577
+ smalltalk.ClassDocChapter.klass);
639
578
 
579
+
580
+ smalltalk.addClass('ClassesIndexChapter', smalltalk.DocChapter, [], 'Documentation');
640
581
  smalltalk.addMethod(
641
- unescape('_renderDocOn_'),
582
+ "_alphabet",
642
583
  smalltalk.method({
643
- selector: unescape('renderDocOn%3A'),
644
- category: 'rendering',
645
- fn: function (html){
584
+ selector: "alphabet",
585
+ category: 'accessing',
586
+ fn: function (){
646
587
  var self=this;
647
- var div=nil;
648
- smalltalk.send(smalltalk.send(html, "_h1", []), "_with_", [smalltalk.send(self, "_title", [])]);
649
- smalltalk.send(self, "_renderNavigationOn_", [html]);
650
- (div=smalltalk.send(smalltalk.send(html, "_div", []), "_class_", ["contents"]));
651
- smalltalk.send(smalltalk.send(div, "_asJQuery", []), "_html_", [smalltalk.send(self, "_htmlContents", [])]);
588
+ return "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
652
589
  return self;},
653
- args: ["html"],
654
- source: unescape('renderDocOn%3A%20html%0A%09%7C%20div%20%7C%0A%09html%20h1%20with%3A%20self%20title.%0A%09self%20renderNavigationOn%3A%20html.%0A%09div%20%3A%3D%20html%20div%20class%3A%20%27contents%27.%0A%09div%20asJQuery%20html%3A%20self%20htmlContents'),
655
- messageSends: ["with:", "h1", "title", "renderNavigationOn:", "class:", "div", "html:", "asJQuery", "htmlContents"],
590
+ args: [],
591
+ source: "alphabet\x0a\x09^'ABCDEFGHIJKLMNOPQRSTUVWXYZ'",
592
+ messageSends: [],
656
593
  referencedClasses: []
657
594
  }),
658
- smalltalk.DocChapter);
595
+ smalltalk.ClassesIndexChapter);
659
596
 
660
597
  smalltalk.addMethod(
661
- unescape('_renderNavigationOn_'),
598
+ "_cssClass",
662
599
  smalltalk.method({
663
- selector: unescape('renderNavigationOn%3A'),
664
- category: 'rendering',
665
- fn: function (html){
600
+ selector: "cssClass",
601
+ category: 'accessing',
602
+ fn: function (){
666
603
  var self=this;
667
- (($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;
604
+ return smalltalk.send("index_doc ", "__comma", [smalltalk.send(self, "_cssClass", [], smalltalk.ClassesIndexChapter.superclass || nil)]);
668
605
  return self;},
669
- args: ["html"],
670
- source: unescape('renderNavigationOn%3A%20html%0A%09self%20parent%20ifNotNil%3A%20%5B%0A%09%09html%20div%20%0A%09%09%09class%3A%20%27navigation%27%3B%20with%3A%20%5B%0A%09%09%09%09html%20a%0A%09%09%09%09%09with%3A%20%27%u2190%20back%20to%20%27%2C%20self%20parent%20title%3B%0A%09%09%09%09%09onClick%3A%20%5Bself%20selectChapter%3A%20self%20parent%5D%5D%5D'),
671
- messageSends: ["ifNotNil:", "parent", "class:", "with:", unescape("%2C"), "title", "onClick:", "selectChapter:", "a", "div"],
606
+ args: [],
607
+ source: "cssClass\x0a\x09^'index_doc ', super cssClass",
608
+ messageSends: [",", "cssClass"],
672
609
  referencedClasses: []
673
610
  }),
674
- smalltalk.DocChapter);
611
+ smalltalk.ClassesIndexChapter);
675
612
 
676
613
  smalltalk.addMethod(
677
- unescape('_renderLinksOn_'),
614
+ "_renderDocOn_",
678
615
  smalltalk.method({
679
- selector: unescape('renderLinksOn%3A'),
616
+ selector: "renderDocOn:",
680
617
  category: 'rendering',
681
618
  fn: function (html){
682
619
  var self=this;
683
- (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", []));
620
+ smalltalk.send(smalltalk.send(html, "_h1", []), "_with_", [smalltalk.send(self, "_title", [])]);
621
+ smalltalk.send(smalltalk.send(self, "_alphabet", []), "_do_", [(function(letter){var classes=nil;
622
+ (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", []));})]);})]);})]);})]);
684
623
  return self;},
685
624
  args: ["html"],
686
- source: unescape('renderLinksOn%3A%20html%0A%09html%20ul%20%0A%09%09class%3A%20%27links%27%3B%0A%09%09with%3A%20%5B%0A%09%09%09self%20chapters%20do%3A%20%5B%3Aeach%20%7C%0A%09%09%09%09html%20li%20with%3A%20%5B%0A%09%09%09%09%09html%20a%0A%09%09%09%09%09%09with%3A%20each%20title%3B%0A%09%09%09%09%09%09onClick%3A%20%5Bself%20selectChapter%3A%20each%5D%5D%5D%5D'),
687
- messageSends: ["class:", "with:", "do:", "chapters", "li", "title", "onClick:", "selectChapter:", "a", "ul"],
688
- referencedClasses: []
625
+ source: "renderDocOn: html\x0a\x09html h1 with: self title.\x0a\x09self alphabet do: [:letter || classes |\x0a\x09\x09classes := Smalltalk current classes select: [:each | each name first = letter].\x0a\x09\x09classes ifNotEmpty: [html h2 with: letter].\x0a\x09\x09html ul with: [\x0a\x09\x09\x09(classes sorted: [:a :b | a name < b name]) \x0a\x09\x09\x09\x09do: [:each |\x0a\x09\x09\x09\x09\x09html li with: [html a \x0a\x09\x09\x09\x09\x09\x09with: each name;\x0a\x09\x09\x09\x09\x09\x09onClick: [self selectClass: each]]]]]",
626
+ messageSends: ["with:", "h1", "title", "do:", "alphabet", "select:", "classes", "current", "=", "first", "name", "ifNotEmpty:", "h2", "ul", "sorted:", "<", "li", "onClick:", "selectClass:", "a"],
627
+ referencedClasses: ["Smalltalk"]
689
628
  }),
690
- smalltalk.DocChapter);
629
+ smalltalk.ClassesIndexChapter);
691
630
 
692
631
  smalltalk.addMethod(
693
- unescape('_subscribe'),
632
+ "_title",
694
633
  smalltalk.method({
695
- selector: unescape('subscribe'),
696
- category: 'subscriptions',
634
+ selector: "title",
635
+ category: 'accessing',
697
636
  fn: function (){
698
637
  var self=this;
699
- 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]);})]));})]);
638
+ return "Smalltalk classes by index";
700
639
  return self;},
701
640
  args: [],
702
- source: unescape('subscribe%0A%09self%20announcer%20on%3A%20ChapterSelectionAnnouncement%20do%3A%20%5B%3Aann%20%7C%0A%09%09ann%20id%20%3D%20self%20id%20ifTrue%3A%20%5Bself%20displayChapter%3A%20self%5D%5D'),
703
- messageSends: ["on:do:", "announcer", "ifTrue:", unescape("%3D"), "id", "displayChapter:"],
704
- referencedClasses: ["ChapterSelectionAnnouncement"]
641
+ source: "title\x0a\x09^'Smalltalk classes by index'",
642
+ messageSends: [],
643
+ referencedClasses: []
705
644
  }),
706
- smalltalk.DocChapter);
645
+ smalltalk.ClassesIndexChapter);
707
646
 
708
647
 
709
648
 
710
649
  smalltalk.addClass('PackageDocChapter', smalltalk.DocChapter, ['package', 'chapters'], 'Documentation');
711
650
  smalltalk.addMethod(
712
- unescape('_package'),
651
+ "_chapters",
713
652
  smalltalk.method({
714
- selector: unescape('package'),
653
+ selector: "chapters",
715
654
  category: 'accessing',
716
655
  fn: function (){
717
656
  var self=this;
718
- return self['@package'];
657
+ return self['@chapters'];
719
658
  return self;},
720
659
  args: [],
721
- source: unescape('package%0A%09%5Epackage'),
660
+ source: "chapters\x0a\x09^chapters",
722
661
  messageSends: [],
723
662
  referencedClasses: []
724
663
  }),
725
664
  smalltalk.PackageDocChapter);
726
665
 
727
666
  smalltalk.addMethod(
728
- unescape('_title'),
667
+ "_contents",
729
668
  smalltalk.method({
730
- selector: unescape('title'),
669
+ selector: "contents",
731
670
  category: 'accessing',
732
671
  fn: function (){
733
672
  var self=this;
734
- return smalltalk.send("Package ", "__comma", [smalltalk.send(smalltalk.send(self, "_package", []), "_name", [])]);
673
+ return smalltalk.send(smalltalk.send("Classes in package ", "__comma", [smalltalk.send(smalltalk.send(self, "_package", []), "_name", [])]), "__comma", [":"]);
735
674
  return self;},
736
675
  args: [],
737
- source: unescape('title%0A%09%5E%27Package%20%27%2C%20self%20package%20name'),
738
- messageSends: [unescape("%2C"), "name", "package"],
676
+ source: "contents\x0a\x09^'Classes in package ', self package name, ':'",
677
+ messageSends: [",", "name", "package"],
739
678
  referencedClasses: []
740
679
  }),
741
680
  smalltalk.PackageDocChapter);
742
681
 
743
682
  smalltalk.addMethod(
744
- unescape('_chapters'),
683
+ "_initializeWithPackage_",
745
684
  smalltalk.method({
746
- selector: unescape('chapters'),
747
- category: 'accessing',
748
- fn: function (){
685
+ selector: "initializeWithPackage:",
686
+ category: 'initialization',
687
+ fn: function (aPackage){
749
688
  var self=this;
750
- return self['@chapters'];
689
+ (self['@package']=aPackage);
690
+ (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]));})]));
751
691
  return self;},
752
- args: [],
753
- source: unescape('chapters%0A%09%5Echapters'),
754
- messageSends: [],
755
- referencedClasses: []
692
+ args: ["aPackage"],
693
+ source: "initializeWithPackage: aPackage\x0a\x09package := aPackage.\x0a\x09chapters := (aPackage classes sorted: [:a :b | a name < b name]) collect: [:each |\x0a\x09\x09(ClassDocChapter on: each)\x0a\x09\x09\x09parent: self;\x0a\x09\x09\x09yourself]",
694
+ messageSends: ["collect:", "sorted:", "classes", "<", "name", "parent:", "yourself", "on:"],
695
+ referencedClasses: ["ClassDocChapter"]
756
696
  }),
757
697
  smalltalk.PackageDocChapter);
758
698
 
759
699
  smalltalk.addMethod(
760
- unescape('_contents'),
700
+ "_package",
761
701
  smalltalk.method({
762
- selector: unescape('contents'),
702
+ selector: "package",
763
703
  category: 'accessing',
764
704
  fn: function (){
765
705
  var self=this;
766
- return smalltalk.send(smalltalk.send("Classes in package ", "__comma", [smalltalk.send(smalltalk.send(self, "_package", []), "_name", [])]), "__comma", [":"]);
706
+ return self['@package'];
767
707
  return self;},
768
708
  args: [],
769
- source: unescape('contents%0A%09%5E%27Classes%20in%20package%20%27%2C%20self%20package%20name%2C%20%27%3A%27'),
770
- messageSends: [unescape("%2C"), "name", "package"],
709
+ source: "package\x0a\x09^package",
710
+ messageSends: [],
771
711
  referencedClasses: []
772
712
  }),
773
713
  smalltalk.PackageDocChapter);
774
714
 
775
715
  smalltalk.addMethod(
776
- unescape('_initializeWithPackage_'),
716
+ "_title",
777
717
  smalltalk.method({
778
- selector: unescape('initializeWithPackage%3A'),
779
- category: 'initialization',
780
- fn: function (aPackage){
718
+ selector: "title",
719
+ category: 'accessing',
720
+ fn: function (){
781
721
  var self=this;
782
- (self['@package']=aPackage);
783
- (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]));})]));
722
+ return smalltalk.send("Package ", "__comma", [smalltalk.send(smalltalk.send(self, "_package", []), "_name", [])]);
784
723
  return self;},
785
- args: ["aPackage"],
786
- source: unescape('initializeWithPackage%3A%20aPackage%0A%09package%20%3A%3D%20aPackage.%0A%09chapters%20%3A%3D%20%28aPackage%20classes%20sorted%3A%20%5B%3Aa%20%3Ab%20%7C%20a%20name%20%3C%20b%20name%5D%29%20collect%3A%20%5B%3Aeach%20%7C%0A%09%09%28ClassDocChapter%20on%3A%20each%29%0A%09%09%09parent%3A%20self%3B%0A%09%09%09yourself%5D'),
787
- messageSends: ["collect:", "sorted:", "classes", unescape("%3C"), "name", "parent:", "yourself", "on:"],
788
- referencedClasses: ["ClassDocChapter"]
724
+ args: [],
725
+ source: "title\x0a\x09^'Package ', self package name",
726
+ messageSends: [",", "name", "package"],
727
+ referencedClasses: []
789
728
  }),
790
729
  smalltalk.PackageDocChapter);
791
730
 
792
731
 
793
732
  smalltalk.addMethod(
794
- unescape('_on_'),
733
+ "_on_",
795
734
  smalltalk.method({
796
- selector: unescape('on%3A'),
735
+ selector: "on:",
797
736
  category: 'instance creation',
798
737
  fn: function (aPackage){
799
738
  var self=this;
800
739
  return (function($rec){smalltalk.send($rec, "_initializeWithPackage_", [aPackage]);smalltalk.send($rec, "_initialize", []);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_basicNew", []));
801
740
  return self;},
802
741
  args: ["aPackage"],
803
- source: unescape('on%3A%20aPackage%0A%09%5Eself%20basicNew%0A%09%09initializeWithPackage%3A%20aPackage%3B%0A%09%09initialize%3B%0A%09%09yourself'),
742
+ source: "on: aPackage\x0a\x09^self basicNew\x0a\x09\x09initializeWithPackage: aPackage;\x0a\x09\x09initialize;\x0a\x09\x09yourself",
804
743
  messageSends: ["initializeWithPackage:", "initialize", "yourself", "basicNew"],
805
744
  referencedClasses: []
806
745
  }),
807
746
  smalltalk.PackageDocChapter.klass);
808
747
 
809
748
 
810
- smalltalk.addClass('ClassDocChapter', smalltalk.DocChapter, ['theClass'], 'Documentation');
749
+ smalltalk.addClass('TutorialsChapter', smalltalk.DocChapter, [], 'Documentation');
811
750
  smalltalk.addMethod(
812
- unescape('_theClass'),
751
+ "_chapters",
813
752
  smalltalk.method({
814
- selector: unescape('theClass'),
753
+ selector: "chapters",
815
754
  category: 'accessing',
816
755
  fn: function (){
817
756
  var self=this;
818
- return self['@theClass'];
757
+ return [smalltalk.send(self, "_firstAppChapter", []),smalltalk.send(self, "_counterChapter", [])];
819
758
  return self;},
820
759
  args: [],
821
- source: unescape('theClass%0A%09%5EtheClass'),
822
- messageSends: [],
760
+ source: "chapters\x0a\x09^{ self firstAppChapter. self counterChapter }",
761
+ messageSends: ["firstAppChapter", "counterChapter"],
823
762
  referencedClasses: []
824
763
  }),
825
- smalltalk.ClassDocChapter);
764
+ smalltalk.TutorialsChapter);
826
765
 
827
766
  smalltalk.addMethod(
828
- unescape('_contents'),
767
+ "_contents",
829
768
  smalltalk.method({
830
- selector: unescape('contents'),
769
+ selector: "contents",
831
770
  category: 'accessing',
832
771
  fn: function (){
833
772
  var self=this;
834
- 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", []);})]));
773
+ 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)";
835
774
  return self;},
836
775
  args: [],
837
- source: unescape('contents%0A%09%5Eself%20theClass%20comment%20isEmpty%0A%09%09ifTrue%3A%20%5Bself%20theClass%20name%2C%20%27%20is%20not%20documented%20yet.%27%5D%0A%09%09ifFalse%3A%20%5Bself%20theClass%20comment%5D'),
838
- messageSends: ["ifTrue:ifFalse:", "isEmpty", "comment", "theClass", unescape("%2C"), "name"],
776
+ source: "contents\x0a\x09^'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)'",
777
+ messageSends: [],
839
778
  referencedClasses: []
840
779
  }),
841
- smalltalk.ClassDocChapter);
780
+ smalltalk.TutorialsChapter);
842
781
 
843
782
  smalltalk.addMethod(
844
- unescape('_cssClass'),
783
+ "_counterChapter",
845
784
  smalltalk.method({
846
- selector: unescape('cssClass'),
785
+ selector: "counterChapter",
847
786
  category: 'accessing',
848
787
  fn: function (){
849
788
  var self=this;
850
- return smalltalk.send("doc_class ", "__comma", [smalltalk.send(self, "_cssClass", [], smalltalk.DocChapter)]);
789
+ 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", []));
851
790
  return self;},
852
791
  args: [],
853
- source: unescape('cssClass%0A%09%5E%27doc_class%20%27%2C%20super%20cssClass'),
854
- messageSends: [unescape("%2C"), "cssClass"],
855
- referencedClasses: []
792
+ source: "counterChapter\x0a\x09^DocChapter new\x0a\x09\x09title: 'The counter application';\x0a\x09\x09contents: '\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'",
793
+ messageSends: ["title:", "contents:", "new"],
794
+ referencedClasses: ["DocChapter"]
856
795
  }),
857
- smalltalk.ClassDocChapter);
796
+ smalltalk.TutorialsChapter);
858
797
 
859
798
  smalltalk.addMethod(
860
- unescape('_title'),
799
+ "_firstAppChapter",
861
800
  smalltalk.method({
862
- selector: unescape('title'),
801
+ selector: "firstAppChapter",
863
802
  category: 'accessing',
864
803
  fn: function (){
865
804
  var self=this;
866
- return smalltalk.send(smalltalk.send(self, "_theClass", []), "_name", []);
805
+ 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", []));
867
806
  return self;},
868
807
  args: [],
869
- source: unescape('title%0A%09%5Eself%20theClass%20name'),
870
- messageSends: ["name", "theClass"],
871
- referencedClasses: []
808
+ source: "firstAppChapter\x0a\x09^DocChapter new\x0a\x09\x09title: 'A first application';\x0a\x09\x09contents: '\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'",
809
+ messageSends: ["title:", "contents:", "new"],
810
+ referencedClasses: ["DocChapter"]
872
811
  }),
873
- smalltalk.ClassDocChapter);
812
+ smalltalk.TutorialsChapter);
874
813
 
875
814
  smalltalk.addMethod(
876
- unescape('_initializeWithClass_'),
815
+ "_title",
877
816
  smalltalk.method({
878
- selector: unescape('initializeWithClass%3A'),
817
+ selector: "title",
879
818
  category: 'accessing',
880
- fn: function (aClass){
819
+ fn: function (){
881
820
  var self=this;
882
- (self['@theClass']=aClass);
821
+ return "Tutorials";
883
822
  return self;},
884
- args: ["aClass"],
885
- source: unescape('initializeWithClass%3A%20aClass%0A%09theClass%20%3A%3D%20aClass'),
823
+ args: [],
824
+ source: "title\x0a\x09^'Tutorials'",
886
825
  messageSends: [],
887
826
  referencedClasses: []
888
827
  }),
889
- smalltalk.ClassDocChapter);
828
+ smalltalk.TutorialsChapter);
890
829
 
830
+
831
+
832
+ smalltalk.addClass('DocumentationBuilder', smalltalk.Object, ['chapters', 'announcer', 'widget'], 'Documentation');
891
833
  smalltalk.addMethod(
892
- unescape('_renderLinksOn_'),
834
+ "_announcer",
893
835
  smalltalk.method({
894
- selector: unescape('renderLinksOn%3A'),
895
- category: 'rendering',
896
- fn: function (html){
836
+ selector: "announcer",
837
+ category: 'accessing',
838
+ fn: function (){
897
839
  var self=this;
898
- (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", []));
840
+ return (($receiver = self['@announcer']) == nil || $receiver == undefined) ? (function(){return (self['@announcer']=smalltalk.send((smalltalk.Announcer || Announcer), "_new", []));})() : $receiver;
899
841
  return self;},
900
- args: ["html"],
901
- source: unescape('renderLinksOn%3A%20html%0A%09html%20ul%20%0A%09%09class%3A%20%27links%27%3B%0A%09%09with%3A%20%5B%0A%09%09%09html%20li%20with%3A%20%5Bhtml%20a%0A%09%09%09%09with%3A%20%27Browse%20this%20class%27%3B%0A%09%09%09%09onClick%3A%20%5BBrowser%20openOn%3A%20self%20theClass%5D%5D%5D'),
902
- messageSends: ["class:", "with:", "li", "onClick:", "openOn:", "theClass", "a", "ul"],
903
- referencedClasses: ["Browser"]
842
+ args: [],
843
+ source: "announcer\x0a\x09^announcer ifNil: [announcer := Announcer new]",
844
+ messageSends: ["ifNil:", "new"],
845
+ referencedClasses: ["Announcer"]
904
846
  }),
905
- smalltalk.ClassDocChapter);
847
+ smalltalk.DocumentationBuilder);
906
848
 
907
849
  smalltalk.addMethod(
908
- unescape('_subscribe'),
850
+ "_build",
909
851
  smalltalk.method({
910
- selector: unescape('subscribe'),
911
- category: 'subscriptions',
852
+ selector: "build",
853
+ category: 'building',
912
854
  fn: function (){
913
855
  var self=this;
914
- smalltalk.send(self, "_subscribe", [], smalltalk.DocChapter);
915
- 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]);})]));})]);
856
+ smalltalk.send(self, "_buildOnJQuery_", [smalltalk.send("body", "_asJQuery", [])]);
916
857
  return self;},
917
858
  args: [],
918
- source: unescape('subscribe%0A%09super%20subscribe.%0A%09self%20announcer%20%0A%09%09on%3A%20ClassSelectionAnnouncement%20do%3A%20%5B%3Aann%20%7C%0A%09%09%09ann%20theClass%20%3D%20self%20theClass%20ifTrue%3A%20%5B%0A%09%09%09%09self%20selectChapter%3A%20self%5D%5D'),
919
- messageSends: ["subscribe", "on:do:", "announcer", "ifTrue:", unescape("%3D"), "theClass", "selectChapter:"],
920
- referencedClasses: ["ClassSelectionAnnouncement"]
859
+ source: "build\x0a\x09self buildOnJQuery: ('body' asJQuery)",
860
+ messageSends: ["buildOnJQuery:", "asJQuery"],
861
+ referencedClasses: []
921
862
  }),
922
- smalltalk.ClassDocChapter);
863
+ smalltalk.DocumentationBuilder);
923
864
 
865
+ smalltalk.addMethod(
866
+ "_buildChapters",
867
+ smalltalk.method({
868
+ selector: "buildChapters",
869
+ category: 'building',
870
+ fn: function (){
871
+ var self=this;
872
+ 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", [])]);})]);
873
+ return self;},
874
+ args: [],
875
+ source: "buildChapters\x0a\x09^((self class methodDictionary values sorted: [:a :b | a selector < b selector])\x0a\x09\x09select: [:each | each category = 'chapters'])\x0a\x09\x09collect: [:each | self perform: each selector]",
876
+ messageSends: ["collect:", "select:", "sorted:", "values", "methodDictionary", "class", "<", "selector", "=", "category", "perform:"],
877
+ referencedClasses: []
878
+ }),
879
+ smalltalk.DocumentationBuilder);
924
880
 
925
881
  smalltalk.addMethod(
926
- unescape('_on_'),
882
+ "_buildOn_",
927
883
  smalltalk.method({
928
- selector: unescape('on%3A'),
929
- category: 'accessing',
930
- fn: function (aClass){
884
+ selector: "buildOn:",
885
+ category: 'building',
886
+ fn: function (aCanvas){
931
887
  var self=this;
932
- return (function($rec){smalltalk.send($rec, "_initializeWithClass_", [aClass]);smalltalk.send($rec, "_initialize", []);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_basicNew", []));
888
+ smalltalk.send(aCanvas, "_with_", [smalltalk.send(self, "_widget", [])]);
889
+ (function($rec){smalltalk.send($rec, "_checkHashChange", []);return smalltalk.send($rec, "_checkHash", []);})(self);
933
890
  return self;},
934
- args: ["aClass"],
935
- source: unescape('on%3A%20aClass%0A%09%5Eself%20basicNew%0A%09%09initializeWithClass%3A%20aClass%3B%0A%09%09initialize%3B%0A%09%09yourself'),
936
- messageSends: ["initializeWithClass:", "initialize", "yourself", "basicNew"],
891
+ args: ["aCanvas"],
892
+ source: "buildOn: aCanvas\x0a\x09aCanvas with: self widget.\x0a\x09self \x0a\x09\x09checkHashChange;\x0a\x09\x09checkHash",
893
+ messageSends: ["with:", "widget", "checkHashChange", "checkHash"],
937
894
  referencedClasses: []
938
895
  }),
939
- smalltalk.ClassDocChapter.klass);
896
+ smalltalk.DocumentationBuilder);
940
897
 
898
+ smalltalk.addMethod(
899
+ "_buildOnJQuery_",
900
+ smalltalk.method({
901
+ selector: "buildOnJQuery:",
902
+ category: 'building',
903
+ fn: function (aJQuery){
904
+ var self=this;
905
+ smalltalk.send(self, "_buildOn_", [smalltalk.send((smalltalk.HTMLCanvas || HTMLCanvas), "_onJQuery_", [aJQuery])]);
906
+ return self;},
907
+ args: ["aJQuery"],
908
+ source: "buildOnJQuery: aJQuery\x0a\x09self buildOn: (HTMLCanvas onJQuery: aJQuery)",
909
+ messageSends: ["buildOn:", "onJQuery:"],
910
+ referencedClasses: ["HTMLCanvas"]
911
+ }),
912
+ smalltalk.DocumentationBuilder);
941
913
 
942
- smalltalk.addClass('DocumentationWidget', smalltalk.Widget, ['builder', 'selectedChapter', 'chapterDiv'], 'Documentation');
943
914
  smalltalk.addMethod(
944
- unescape('_builder'),
915
+ "_ch1introduction",
945
916
  smalltalk.method({
946
- selector: unescape('builder'),
947
- category: 'accessing',
917
+ selector: "ch1introduction",
918
+ category: 'chapters',
948
919
  fn: function (){
949
920
  var self=this;
950
- return self['@builder'];
921
+ 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", []));
951
922
  return self;},
952
923
  args: [],
953
- source: unescape('builder%0A%09%5Ebuilder'),
954
- messageSends: [],
955
- referencedClasses: []
924
+ source: "ch1introduction\x0a\x09^DocChapter new\x0a\x09\x09title: 'Introduction';\x0a\x09\x09contents: '\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'",
925
+ messageSends: ["title:", "contents:", "new"],
926
+ referencedClasses: ["DocChapter"]
956
927
  }),
957
- smalltalk.DocumentationWidget);
928
+ smalltalk.DocumentationBuilder);
958
929
 
959
930
  smalltalk.addMethod(
960
- unescape('_builder_'),
931
+ "_ch2differencesWithOtherSmalltalks",
961
932
  smalltalk.method({
962
- selector: unescape('builder%3A'),
963
- category: 'accessing',
964
- fn: function (aDocumentationBuilder){
933
+ selector: "ch2differencesWithOtherSmalltalks",
934
+ category: 'chapters',
935
+ fn: function (){
965
936
  var self=this;
966
- (self['@builder']=aDocumentationBuilder);
937
+ 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", []));
967
938
  return self;},
968
- args: ["aDocumentationBuilder"],
969
- source: unescape('builder%3A%20aDocumentationBuilder%0A%09builder%20%3A%3D%20aDocumentationBuilder'),
970
- messageSends: [],
971
- referencedClasses: []
939
+ args: [],
940
+ source: "ch2differencesWithOtherSmalltalks\x0a\x09^DocChapter new\x0a\x09\x09title: 'Differences with other Smalltalks';\x0a\x09\x09contents: '\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'",
941
+ messageSends: ["title:", "contents:", "new"],
942
+ referencedClasses: ["DocChapter"]
972
943
  }),
973
- smalltalk.DocumentationWidget);
944
+ smalltalk.DocumentationBuilder);
974
945
 
975
946
  smalltalk.addMethod(
976
- unescape('_chapters'),
947
+ "_ch3GettingStarted",
977
948
  smalltalk.method({
978
- selector: unescape('chapters'),
979
- category: 'accessing',
949
+ selector: "ch3GettingStarted",
950
+ category: 'chapters',
980
951
  fn: function (){
981
952
  var self=this;
982
- return smalltalk.send(smalltalk.send(self, "_builder", []), "_chapters", []);
953
+ 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", []));
983
954
  return self;},
984
955
  args: [],
985
- source: unescape('chapters%0A%09%5Eself%20builder%20chapters'),
986
- messageSends: ["chapters", "builder"],
987
- referencedClasses: []
956
+ source: "ch3GettingStarted\x0a\x09^DocChapter new\x0a\x09\x09title: 'Getting started';\x0a\x09\x09contents: '\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'",
957
+ messageSends: ["title:", "contents:", "new"],
958
+ referencedClasses: ["DocChapter"]
988
959
  }),
989
- smalltalk.DocumentationWidget);
960
+ smalltalk.DocumentationBuilder);
990
961
 
991
962
  smalltalk.addMethod(
992
- unescape('_selectedChapter'),
963
+ "_ch4Tutorials",
993
964
  smalltalk.method({
994
- selector: unescape('selectedChapter'),
995
- category: 'accessing',
965
+ selector: "ch4Tutorials",
966
+ category: 'chapters',
996
967
  fn: function (){
997
968
  var self=this;
998
- return (($receiver = self['@selectedChapter']) == nil || $receiver == undefined) ? (function(){return (self['@selectedChapter']=smalltalk.send(smalltalk.send(self, "_chapters", []), "_first", []));})() : $receiver;
969
+ return smalltalk.send((smalltalk.TutorialsChapter || TutorialsChapter), "_new", []);
999
970
  return self;},
1000
971
  args: [],
1001
- source: unescape('selectedChapter%0A%09%5EselectedChapter%20ifNil%3A%20%5BselectedChapter%20%3A%3D%20self%20chapters%20first%5D'),
1002
- messageSends: ["ifNil:", "first", "chapters"],
1003
- referencedClasses: []
972
+ source: "ch4Tutorials\x0a\x09^TutorialsChapter new",
973
+ messageSends: ["new"],
974
+ referencedClasses: ["TutorialsChapter"]
1004
975
  }),
1005
- smalltalk.DocumentationWidget);
976
+ smalltalk.DocumentationBuilder);
1006
977
 
1007
978
  smalltalk.addMethod(
1008
- unescape('_selectedChapter_'),
979
+ "_ch5Index",
1009
980
  smalltalk.method({
1010
- selector: unescape('selectedChapter%3A'),
1011
- category: 'accessing',
1012
- fn: function (aChapter){
981
+ selector: "ch5Index",
982
+ category: 'chapters',
983
+ fn: function (){
1013
984
  var self=this;
1014
- return (self['@selectedChapter']=aChapter);
985
+ return smalltalk.send((smalltalk.ClassesIndexChapter || ClassesIndexChapter), "_new", []);
1015
986
  return self;},
1016
- args: ["aChapter"],
1017
- source: unescape('selectedChapter%3A%20aChapter%0A%09%5EselectedChapter%20%3A%3D%20aChapter'),
1018
- messageSends: [],
1019
- referencedClasses: []
987
+ args: [],
988
+ source: "ch5Index\x0a\x09^ClassesIndexChapter new",
989
+ messageSends: ["new"],
990
+ referencedClasses: ["ClassesIndexChapter"]
1020
991
  }),
1021
- smalltalk.DocumentationWidget);
992
+ smalltalk.DocumentationBuilder);
1022
993
 
1023
994
  smalltalk.addMethod(
1024
- unescape('_displayChapter_'),
995
+ "_ch6KernelObjects",
1025
996
  smalltalk.method({
1026
- selector: unescape('displayChapter%3A'),
1027
- category: 'actions',
1028
- fn: function (aChapter){
997
+ selector: "ch6KernelObjects",
998
+ category: 'chapters',
999
+ fn: function (){
1029
1000
  var self=this;
1030
- smalltalk.send(self, "_selectedChapter_", [aChapter]);
1031
- smalltalk.send(self, "_updateChapterDiv", []);
1001
+ return smalltalk.send((smalltalk.PackageDocChapter || PackageDocChapter), "_on_", [smalltalk.send((smalltalk.Package || Package), "_named_", ["Kernel-Objects"])]);
1032
1002
  return self;},
1033
- args: ["aChapter"],
1034
- source: unescape('displayChapter%3A%20aChapter%0A%09self%20selectedChapter%3A%20aChapter.%0A%09self%20updateChapterDiv'),
1035
- messageSends: ["selectedChapter:", "updateChapterDiv"],
1036
- referencedClasses: []
1003
+ args: [],
1004
+ source: "ch6KernelObjects\x0a\x09^PackageDocChapter on: (Package named: 'Kernel-Objects')",
1005
+ messageSends: ["on:", "named:"],
1006
+ referencedClasses: ["PackageDocChapter", "Package"]
1037
1007
  }),
1038
- smalltalk.DocumentationWidget);
1008
+ smalltalk.DocumentationBuilder);
1039
1009
 
1040
1010
  smalltalk.addMethod(
1041
- unescape('_selectChapter_'),
1011
+ "_ch7KernelClasses",
1042
1012
  smalltalk.method({
1043
- selector: unescape('selectChapter%3A'),
1044
- category: 'actions',
1045
- fn: function (aChapter){
1013
+ selector: "ch7KernelClasses",
1014
+ category: 'chapters',
1015
+ fn: function (){
1046
1016
  var self=this;
1047
- smalltalk.send(smalltalk.send((typeof document == 'undefined' ? nil : document), "_location", []), "_hash_", [smalltalk.send(aChapter, "_id", [])]);
1017
+ return smalltalk.send((smalltalk.PackageDocChapter || PackageDocChapter), "_on_", [smalltalk.send((smalltalk.Package || Package), "_named_", ["Kernel-Classes"])]);
1048
1018
  return self;},
1049
- args: ["aChapter"],
1050
- source: unescape('selectChapter%3A%20aChapter%0A%09document%20location%20hash%3A%20aChapter%20id'),
1051
- messageSends: ["hash:", "location", "id"],
1052
- referencedClasses: []
1019
+ args: [],
1020
+ source: "ch7KernelClasses\x0a\x09^PackageDocChapter on: (Package named: 'Kernel-Classes')",
1021
+ messageSends: ["on:", "named:"],
1022
+ referencedClasses: ["PackageDocChapter", "Package"]
1053
1023
  }),
1054
- smalltalk.DocumentationWidget);
1024
+ smalltalk.DocumentationBuilder);
1055
1025
 
1056
1026
  smalltalk.addMethod(
1057
- unescape('_renderOn_'),
1027
+ "_ch8KernelCollection",
1058
1028
  smalltalk.method({
1059
- selector: unescape('renderOn%3A'),
1060
- category: 'rendering',
1061
- fn: function (html){
1029
+ selector: "ch8KernelCollection",
1030
+ category: 'chapters',
1031
+ fn: function (){
1062
1032
  var self=this;
1063
- (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", []));
1033
+ return smalltalk.send((smalltalk.PackageDocChapter || PackageDocChapter), "_on_", [smalltalk.send((smalltalk.Package || Package), "_named_", ["Kernel-Collections"])]);
1064
1034
  return self;},
1065
- args: ["html"],
1066
- source: unescape('renderOn%3A%20html%0A%09html%20div%20%0A%09%09class%3A%20%27documentation%27%3B%0A%09%09with%3A%20%5B%0A%09%09%09self%20renderMenuOn%3A%20html.%0A%09%09%09chapterDiv%20%3A%3D%20html%20div.%0A%09%09%09self%20updateChapterDiv%5D'),
1067
- messageSends: ["class:", "with:", "renderMenuOn:", "div", "updateChapterDiv"],
1068
- referencedClasses: []
1035
+ args: [],
1036
+ source: "ch8KernelCollection\x0a\x09^PackageDocChapter on: (Package named: 'Kernel-Collections')",
1037
+ messageSends: ["on:", "named:"],
1038
+ referencedClasses: ["PackageDocChapter", "Package"]
1069
1039
  }),
1070
- smalltalk.DocumentationWidget);
1040
+ smalltalk.DocumentationBuilder);
1071
1041
 
1072
1042
  smalltalk.addMethod(
1073
- unescape('_renderMenuOn_'),
1043
+ "_ch9KernelMethods",
1074
1044
  smalltalk.method({
1075
- selector: unescape('renderMenuOn%3A'),
1076
- category: 'rendering',
1077
- fn: function (html){
1045
+ selector: "ch9KernelMethods",
1046
+ category: 'chapters',
1047
+ fn: function (){
1078
1048
  var self=this;
1079
- (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", []));
1049
+ return smalltalk.send((smalltalk.PackageDocChapter || PackageDocChapter), "_on_", [smalltalk.send((smalltalk.Package || Package), "_named_", ["Kernel-Methods"])]);
1080
1050
  return self;},
1081
- args: ["html"],
1082
- source: unescape('renderMenuOn%3A%20html%0A%09html%20div%20%0A%09%09class%3A%20%27menu%27%3B%0A%09%09with%3A%20%5B%0A%09%09%09html%20ol%20with%3A%20%5B%0A%09%09%09%09self%20chapters%20do%3A%20%5B%3Aeach%20%7C%0A%09%09%09%09%09html%20li%20with%3A%20%5B%0A%09%09%09%09%09%09self%20renderChapterMenu%3A%20each%20on%3A%20html%5D%5D%5D%5D'),
1083
- messageSends: ["class:", "with:", "ol", "do:", "chapters", "li", "renderChapterMenu:on:", "div"],
1084
- referencedClasses: []
1051
+ args: [],
1052
+ source: "ch9KernelMethods\x0a\x09^PackageDocChapter on: (Package named: 'Kernel-Methods')",
1053
+ messageSends: ["on:", "named:"],
1054
+ referencedClasses: ["PackageDocChapter", "Package"]
1085
1055
  }),
1086
- smalltalk.DocumentationWidget);
1056
+ smalltalk.DocumentationBuilder);
1087
1057
 
1088
1058
  smalltalk.addMethod(
1089
- unescape('_renderChapterMenu_on_'),
1059
+ "_chapters",
1090
1060
  smalltalk.method({
1091
- selector: unescape('renderChapterMenu%3Aon%3A'),
1092
- category: 'rendering',
1093
- fn: function (aChapter, html){
1061
+ selector: "chapters",
1062
+ category: 'accessing',
1063
+ fn: function (){
1094
1064
  var self=this;
1095
- (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", []));
1096
- 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]);})]);})]);})]);
1065
+ return (($receiver = self['@chapters']) == nil || $receiver == undefined) ? (function(){return (self['@chapters']=smalltalk.send(self, "_buildChapters", []));})() : $receiver;
1097
1066
  return self;},
1098
- args: ["aChapter", "html"],
1099
- source: unescape('renderChapterMenu%3A%20aChapter%20on%3A%20html%0A%09html%20a%0A%09%09with%3A%20aChapter%20title%3B%0A%09%09onClick%3A%20%5B%0A%09%09%09self%20selectChapter%3A%20aChapter%5D.%0A%09html%20ol%20with%3A%20%5B%0A%09%09%09aChapter%20chapters%20do%3A%20%5B%3Aeach%20%7C%0A%09%09%09%09html%20li%20with%3A%20%5B%0A%09%09%09%09%09self%20renderChapterMenu%3A%20each%20on%3A%20html%5D%5D%5D'),
1100
- messageSends: ["with:", "title", "onClick:", "selectChapter:", "a", "ol", "do:", "chapters", "li", "renderChapterMenu:on:"],
1067
+ args: [],
1068
+ source: "chapters\x0a\x09^chapters ifNil: [chapters := self buildChapters]",
1069
+ messageSends: ["ifNil:", "buildChapters"],
1101
1070
  referencedClasses: []
1102
1071
  }),
1103
- smalltalk.DocumentationWidget);
1072
+ smalltalk.DocumentationBuilder);
1104
1073
 
1105
1074
  smalltalk.addMethod(
1106
- unescape('_updateChapterDiv'),
1075
+ "_checkHash",
1107
1076
  smalltalk.method({
1108
- selector: unescape('updateChapterDiv'),
1109
- category: 'updating',
1077
+ selector: "checkHash",
1078
+ category: 'routing',
1110
1079
  fn: function (){
1111
1080
  var self=this;
1112
- smalltalk.send(self['@chapterDiv'], "_contents_", [(function(html){return smalltalk.send(html, "_with_", [smalltalk.send(self, "_selectedChapter", [])]);})]);
1081
+ var hash=nil;
1082
+ var presentation=nil;
1083
+ (hash=smalltalk.send(smalltalk.send(smalltalk.send((typeof document == 'undefined' ? nil : document), "_location", []), "_hash", []), "_replace_with_", ["^#", ""]));
1084
+ 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", []))]);
1113
1085
  return self;},
1114
1086
  args: [],
1115
- source: unescape('updateChapterDiv%0A%09chapterDiv%20contents%3A%20%5B%3Ahtml%20%7C%0A%09%09html%20with%3A%20self%20selectedChapter%5D'),
1116
- messageSends: ["contents:", "with:", "selectedChapter"],
1117
- referencedClasses: []
1087
+ source: "checkHash\x0a\x09| hash presentation |\x0a\x09hash := document location hash replace: '^#' with: ''.\x0a\x09self announcer announce: (ChapterSelectionAnnouncement new \x0a\x09\x09id: hash; \x0a\x09\x09yourself)",
1088
+ messageSends: ["replace:with:", "hash", "location", "announce:", "announcer", "id:", "yourself", "new"],
1089
+ referencedClasses: ["ChapterSelectionAnnouncement"]
1118
1090
  }),
1119
- smalltalk.DocumentationWidget);
1120
-
1091
+ smalltalk.DocumentationBuilder);
1121
1092
 
1122
1093
  smalltalk.addMethod(
1123
- unescape('_on_'),
1094
+ "_checkHashChange",
1124
1095
  smalltalk.method({
1125
- selector: unescape('on%3A'),
1126
- category: 'instance creation',
1127
- fn: function (aBuilder){
1096
+ selector: "checkHashChange",
1097
+ category: 'routing',
1098
+ fn: function (){
1128
1099
  var self=this;
1129
- return (function($rec){smalltalk.send($rec, "_builder_", [aBuilder]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
1100
+ smalltalk.send(smalltalk.send((typeof window == 'undefined' ? nil : window), "_jQuery_", [(typeof window == 'undefined' ? nil : window)]), "_bind_do_", ["hashchange", (function(){return smalltalk.send(self, "_checkHash", []);})]);
1130
1101
  return self;},
1131
- args: ["aBuilder"],
1132
- source: unescape('on%3A%20aBuilder%0A%09%5Eself%20new%0A%09%09builder%3A%20aBuilder%3B%0A%09%09yourself'),
1133
- messageSends: ["builder:", "yourself", "new"],
1102
+ args: [],
1103
+ source: "checkHashChange\x0a\x09(window jQuery: window) bind: 'hashchange' do: [self checkHash]",
1104
+ messageSends: ["bind:do:", "jQuery:", "checkHash"],
1134
1105
  referencedClasses: []
1135
1106
  }),
1136
- smalltalk.DocumentationWidget.klass);
1137
-
1107
+ smalltalk.DocumentationBuilder);
1138
1108
 
1139
- smalltalk.addClass('ClassesIndexChapter', smalltalk.DocChapter, [], 'Documentation');
1140
1109
  smalltalk.addMethod(
1141
- unescape('_cssClass'),
1110
+ "_update",
1142
1111
  smalltalk.method({
1143
- selector: unescape('cssClass'),
1144
- category: 'accessing',
1112
+ selector: "update",
1113
+ category: 'updating',
1145
1114
  fn: function (){
1146
1115
  var self=this;
1147
- return smalltalk.send("index_doc ", "__comma", [smalltalk.send(self, "_cssClass", [], smalltalk.DocChapter)]);
1116
+ (self['@chapters']=nil);
1117
+ (self['@announcer']=nil);
1118
+ (self['@widget']=nil);
1119
+ smalltalk.send(smalltalk.send((typeof window == 'undefined' ? nil : window), "_jQuery_", [".documentation"]), "_remove", []);
1120
+ smalltalk.send(self, "_build", []);
1148
1121
  return self;},
1149
1122
  args: [],
1150
- source: unescape('cssClass%0A%09%5E%27index_doc%20%27%2C%20super%20cssClass'),
1151
- messageSends: [unescape("%2C"), "cssClass"],
1123
+ source: "update\x0a\x09chapters := nil.\x0a\x09announcer := nil.\x0a\x09widget := nil.\x0a\x09(window jQuery: '.documentation') remove.\x0a\x09self build",
1124
+ messageSends: ["remove", "jQuery:", "build"],
1152
1125
  referencedClasses: []
1153
1126
  }),
1154
- smalltalk.ClassesIndexChapter);
1127
+ smalltalk.DocumentationBuilder);
1155
1128
 
1156
1129
  smalltalk.addMethod(
1157
- unescape('_title'),
1130
+ "_widget",
1158
1131
  smalltalk.method({
1159
- selector: unescape('title'),
1132
+ selector: "widget",
1160
1133
  category: 'accessing',
1161
1134
  fn: function (){
1162
1135
  var self=this;
1163
- return "Smalltalk classes by index";
1136
+ return (($receiver = self['@widget']) == nil || $receiver == undefined) ? (function(){return (self['@widget']=smalltalk.send((smalltalk.DocumentationWidget || DocumentationWidget), "_on_", [self]));})() : $receiver;
1164
1137
  return self;},
1165
1138
  args: [],
1166
- source: unescape('title%0A%09%5E%27Smalltalk%20classes%20by%20index%27'),
1167
- messageSends: [],
1168
- referencedClasses: []
1139
+ source: "widget\x0a\x09^widget ifNil: [widget := DocumentationWidget on: self]",
1140
+ messageSends: ["ifNil:", "on:"],
1141
+ referencedClasses: ["DocumentationWidget"]
1169
1142
  }),
1170
- smalltalk.ClassesIndexChapter);
1143
+ smalltalk.DocumentationBuilder);
1144
+
1171
1145
 
1146
+ smalltalk.DocumentationBuilder.klass.iVarNames = ['current'];
1172
1147
  smalltalk.addMethod(
1173
- unescape('_alphabet'),
1148
+ "_current",
1174
1149
  smalltalk.method({
1175
- selector: unescape('alphabet'),
1150
+ selector: "current",
1176
1151
  category: 'accessing',
1177
1152
  fn: function (){
1178
1153
  var self=this;
1179
- return "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
1154
+ return (($receiver = self['@current']) == nil || $receiver == undefined) ? (function(){return (self['@current']=smalltalk.send(self, "_new", []));})() : $receiver;
1180
1155
  return self;},
1181
1156
  args: [],
1182
- source: unescape('alphabet%0A%09%5E%27ABCDEFGHIJKLMNOPQRSTUVWXYZ%27'),
1183
- messageSends: [],
1157
+ source: "current\x0a\x09^current ifNil: [current := self new]",
1158
+ messageSends: ["ifNil:", "new"],
1184
1159
  referencedClasses: []
1185
1160
  }),
1186
- smalltalk.ClassesIndexChapter);
1161
+ smalltalk.DocumentationBuilder.klass);
1187
1162
 
1188
1163
  smalltalk.addMethod(
1189
- unescape('_renderDocOn_'),
1164
+ "_initialize",
1190
1165
  smalltalk.method({
1191
- selector: unescape('renderDocOn%3A'),
1192
- category: 'rendering',
1193
- fn: function (html){
1166
+ selector: "initialize",
1167
+ category: 'initialization',
1168
+ fn: function (){
1194
1169
  var self=this;
1195
- smalltalk.send(smalltalk.send(html, "_h1", []), "_with_", [smalltalk.send(self, "_title", [])]);
1196
- smalltalk.send(smalltalk.send(self, "_alphabet", []), "_do_", [(function(letter){var classes=nil;
1197
- (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", []));})]);})]);})]);})]);
1170
+ smalltalk.send(smalltalk.send(self, "_current", []), "_build", []);
1198
1171
  return self;},
1199
- args: ["html"],
1200
- source: unescape('renderDocOn%3A%20html%0A%09html%20h1%20with%3A%20self%20title.%0A%09self%20alphabet%20do%3A%20%5B%3Aletter%20%7C%7C%20classes%20%7C%0A%09%09classes%20%3A%3D%20Smalltalk%20current%20classes%20select%3A%20%5B%3Aeach%20%7C%20each%20name%20first%20%3D%20letter%5D.%0A%09%09classes%20ifNotEmpty%3A%20%5Bhtml%20h2%20with%3A%20letter%5D.%0A%09%09html%20ul%20with%3A%20%5B%0A%09%09%09%28classes%20sorted%3A%20%5B%3Aa%20%3Ab%20%7C%20a%20name%20%3C%20b%20name%5D%29%20%0A%09%09%09%09do%3A%20%5B%3Aeach%20%7C%0A%09%09%09%09%09html%20li%20with%3A%20%5Bhtml%20a%20%0A%09%09%09%09%09%09with%3A%20each%20name%3B%0A%09%09%09%09%09%09onClick%3A%20%5Bself%20selectClass%3A%20each%5D%5D%5D%5D%5D'),
1201
- messageSends: ["with:", "h1", "title", "do:", "alphabet", "select:", "classes", "current", unescape("%3D"), "first", "name", "ifNotEmpty:", "h2", "ul", "sorted:", unescape("%3C"), "li", "onClick:", "selectClass:", "a"],
1202
- referencedClasses: ["Smalltalk"]
1172
+ args: [],
1173
+ source: "initialize\x0a\x09self current build",
1174
+ messageSends: ["build", "current"],
1175
+ referencedClasses: []
1203
1176
  }),
1204
- smalltalk.ClassesIndexChapter);
1205
-
1177
+ smalltalk.DocumentationBuilder.klass);
1206
1178
 
1207
1179
 
1208
- smalltalk.addClass('ClassSelectionAnnouncement', smalltalk.Object, ['theClass'], 'Documentation');
1180
+ smalltalk.addClass('DocumentationWidget', smalltalk.Widget, ['builder', 'selectedChapter', 'chapterDiv'], 'Documentation');
1209
1181
  smalltalk.addMethod(
1210
- unescape('_theClass'),
1182
+ "_builder",
1211
1183
  smalltalk.method({
1212
- selector: unescape('theClass'),
1184
+ selector: "builder",
1213
1185
  category: 'accessing',
1214
1186
  fn: function (){
1215
1187
  var self=this;
1216
- return self['@theClass'];
1188
+ return self['@builder'];
1217
1189
  return self;},
1218
1190
  args: [],
1219
- source: unescape('theClass%0A%09%5EtheClass'),
1191
+ source: "builder\x0a\x09^builder",
1220
1192
  messageSends: [],
1221
1193
  referencedClasses: []
1222
1194
  }),
1223
- smalltalk.ClassSelectionAnnouncement);
1195
+ smalltalk.DocumentationWidget);
1224
1196
 
1225
1197
  smalltalk.addMethod(
1226
- unescape('_theClass_'),
1198
+ "_builder_",
1227
1199
  smalltalk.method({
1228
- selector: unescape('theClass%3A'),
1200
+ selector: "builder:",
1229
1201
  category: 'accessing',
1230
- fn: function (aClass){
1202
+ fn: function (aDocumentationBuilder){
1231
1203
  var self=this;
1232
- (self['@theClass']=aClass);
1204
+ (self['@builder']=aDocumentationBuilder);
1233
1205
  return self;},
1234
- args: ["aClass"],
1235
- source: unescape('theClass%3A%20aClass%0A%09theClass%20%3A%3D%20aClass'),
1206
+ args: ["aDocumentationBuilder"],
1207
+ source: "builder: aDocumentationBuilder\x0a\x09builder := aDocumentationBuilder",
1236
1208
  messageSends: [],
1237
1209
  referencedClasses: []
1238
1210
  }),
1239
- smalltalk.ClassSelectionAnnouncement);
1240
-
1211
+ smalltalk.DocumentationWidget);
1241
1212
 
1242
1213
  smalltalk.addMethod(
1243
- unescape('_on_'),
1214
+ "_chapters",
1244
1215
  smalltalk.method({
1245
- selector: unescape('on%3A'),
1246
- category: 'instance creation',
1247
- fn: function (aClass){
1216
+ selector: "chapters",
1217
+ category: 'accessing',
1218
+ fn: function (){
1248
1219
  var self=this;
1249
- return (function($rec){smalltalk.send($rec, "_theClass_", [aClass]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
1220
+ return smalltalk.send(smalltalk.send(self, "_builder", []), "_chapters", []);
1250
1221
  return self;},
1251
- args: ["aClass"],
1252
- source: unescape('on%3A%20aClass%0A%09%5Eself%20new%0A%09%09theClass%3A%20aClass%3B%0A%09%09yourself'),
1253
- messageSends: ["theClass:", "yourself", "new"],
1222
+ args: [],
1223
+ source: "chapters\x0a\x09^self builder chapters",
1224
+ messageSends: ["chapters", "builder"],
1254
1225
  referencedClasses: []
1255
1226
  }),
1256
- smalltalk.ClassSelectionAnnouncement.klass);
1257
-
1227
+ smalltalk.DocumentationWidget);
1258
1228
 
1259
- smalltalk.addClass('ChapterSelectionAnnouncement', smalltalk.Object, ['id'], 'Documentation');
1260
1229
  smalltalk.addMethod(
1261
- unescape('_id'),
1230
+ "_displayChapter_",
1262
1231
  smalltalk.method({
1263
- selector: unescape('id'),
1264
- category: 'accessing',
1265
- fn: function (){
1232
+ selector: "displayChapter:",
1233
+ category: 'actions',
1234
+ fn: function (aChapter){
1266
1235
  var self=this;
1267
- return self['@id'];
1236
+ smalltalk.send(self, "_selectedChapter_", [aChapter]);
1237
+ smalltalk.send(self, "_updateChapterDiv", []);
1268
1238
  return self;},
1269
- args: [],
1270
- source: unescape('id%0A%09%5Eid'),
1271
- messageSends: [],
1239
+ args: ["aChapter"],
1240
+ source: "displayChapter: aChapter\x0a\x09self selectedChapter: aChapter.\x0a\x09self updateChapterDiv",
1241
+ messageSends: ["selectedChapter:", "updateChapterDiv"],
1272
1242
  referencedClasses: []
1273
1243
  }),
1274
- smalltalk.ChapterSelectionAnnouncement);
1244
+ smalltalk.DocumentationWidget);
1275
1245
 
1276
1246
  smalltalk.addMethod(
1277
- unescape('_id_'),
1247
+ "_renderChapterMenu_on_",
1278
1248
  smalltalk.method({
1279
- selector: unescape('id%3A'),
1280
- category: 'accessing',
1281
- fn: function (aString){
1249
+ selector: "renderChapterMenu:on:",
1250
+ category: 'rendering',
1251
+ fn: function (aChapter, html){
1282
1252
  var self=this;
1283
- (self['@id']=aString);
1253
+ (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", []));
1254
+ 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]);})]);})]);})]);
1284
1255
  return self;},
1285
- args: ["aString"],
1286
- source: unescape('id%3A%20aString%0A%09id%20%3A%3D%20aString'),
1287
- messageSends: [],
1256
+ args: ["aChapter", "html"],
1257
+ source: "renderChapterMenu: aChapter on: html\x0a\x09html a\x0a\x09\x09with: aChapter title;\x0a\x09\x09onClick: [\x0a\x09\x09\x09self selectChapter: aChapter].\x0a\x09html ol with: [\x0a\x09\x09\x09aChapter chapters do: [:each |\x0a\x09\x09\x09\x09html li with: [\x0a\x09\x09\x09\x09\x09self renderChapterMenu: each on: html]]]",
1258
+ messageSends: ["with:", "title", "onClick:", "selectChapter:", "a", "ol", "do:", "chapters", "li", "renderChapterMenu:on:"],
1288
1259
  referencedClasses: []
1289
1260
  }),
1290
- smalltalk.ChapterSelectionAnnouncement);
1291
-
1261
+ smalltalk.DocumentationWidget);
1292
1262
 
1263
+ smalltalk.addMethod(
1264
+ "_renderMenuOn_",
1265
+ smalltalk.method({
1266
+ selector: "renderMenuOn:",
1267
+ category: 'rendering',
1268
+ fn: function (html){
1269
+ var self=this;
1270
+ (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", []));
1271
+ return self;},
1272
+ args: ["html"],
1273
+ source: "renderMenuOn: html\x0a\x09html div \x0a\x09\x09class: 'menu';\x0a\x09\x09with: [\x0a\x09\x09\x09html ol with: [\x0a\x09\x09\x09\x09self chapters do: [:each |\x0a\x09\x09\x09\x09\x09html li with: [\x0a\x09\x09\x09\x09\x09\x09self renderChapterMenu: each on: html]]]]",
1274
+ messageSends: ["class:", "with:", "ol", "do:", "chapters", "li", "renderChapterMenu:on:", "div"],
1275
+ referencedClasses: []
1276
+ }),
1277
+ smalltalk.DocumentationWidget);
1293
1278
 
1294
- smalltalk.addClass('TutorialsChapter', smalltalk.DocChapter, [], 'Documentation');
1295
1279
  smalltalk.addMethod(
1296
- unescape('_title'),
1280
+ "_renderOn_",
1297
1281
  smalltalk.method({
1298
- selector: unescape('title'),
1299
- category: 'accessing',
1300
- fn: function (){
1282
+ selector: "renderOn:",
1283
+ category: 'rendering',
1284
+ fn: function (html){
1301
1285
  var self=this;
1302
- return "Tutorials";
1286
+ (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", []));
1303
1287
  return self;},
1304
- args: [],
1305
- source: unescape('title%0A%09%5E%27Tutorials%27'),
1306
- messageSends: [],
1288
+ args: ["html"],
1289
+ source: "renderOn: html\x0a\x09html div \x0a\x09\x09class: 'documentation';\x0a\x09\x09with: [\x0a\x09\x09\x09self renderMenuOn: html.\x0a\x09\x09\x09chapterDiv := html div.\x0a\x09\x09\x09self updateChapterDiv]",
1290
+ messageSends: ["class:", "with:", "renderMenuOn:", "div", "updateChapterDiv"],
1307
1291
  referencedClasses: []
1308
1292
  }),
1309
- smalltalk.TutorialsChapter);
1293
+ smalltalk.DocumentationWidget);
1310
1294
 
1311
1295
  smalltalk.addMethod(
1312
- unescape('_contents'),
1296
+ "_selectChapter_",
1313
1297
  smalltalk.method({
1314
- selector: unescape('contents'),
1315
- category: 'accessing',
1316
- fn: function (){
1298
+ selector: "selectChapter:",
1299
+ category: 'actions',
1300
+ fn: function (aChapter){
1317
1301
  var self=this;
1318
- 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");
1302
+ smalltalk.send(smalltalk.send((typeof document == 'undefined' ? nil : document), "_location", []), "_hash_", [smalltalk.send(aChapter, "_id", [])]);
1319
1303
  return self;},
1320
- args: [],
1321
- source: unescape('contents%0A%09%5E%27Here%27%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%27'),
1322
- messageSends: [],
1304
+ args: ["aChapter"],
1305
+ source: "selectChapter: aChapter\x0a\x09document location hash: aChapter id",
1306
+ messageSends: ["hash:", "location", "id"],
1323
1307
  referencedClasses: []
1324
1308
  }),
1325
- smalltalk.TutorialsChapter);
1309
+ smalltalk.DocumentationWidget);
1326
1310
 
1327
1311
  smalltalk.addMethod(
1328
- unescape('_chapters'),
1312
+ "_selectedChapter",
1329
1313
  smalltalk.method({
1330
- selector: unescape('chapters'),
1314
+ selector: "selectedChapter",
1331
1315
  category: 'accessing',
1332
1316
  fn: function (){
1333
1317
  var self=this;
1334
- return [smalltalk.send(self, "_firstAppChapter", []),smalltalk.send(self, "_counterChapter", [])];
1318
+ return (($receiver = self['@selectedChapter']) == nil || $receiver == undefined) ? (function(){return (self['@selectedChapter']=smalltalk.send(smalltalk.send(self, "_chapters", []), "_first", []));})() : $receiver;
1335
1319
  return self;},
1336
1320
  args: [],
1337
- source: unescape('chapters%0A%09%5E%7B%20self%20firstAppChapter.%20self%20counterChapter%20%7D'),
1338
- messageSends: ["firstAppChapter", "counterChapter"],
1321
+ source: "selectedChapter\x0a\x09^selectedChapter ifNil: [selectedChapter := self chapters first]",
1322
+ messageSends: ["ifNil:", "first", "chapters"],
1339
1323
  referencedClasses: []
1340
1324
  }),
1341
- smalltalk.TutorialsChapter);
1325
+ smalltalk.DocumentationWidget);
1342
1326
 
1343
1327
  smalltalk.addMethod(
1344
- unescape('_firstAppChapter'),
1328
+ "_selectedChapter_",
1345
1329
  smalltalk.method({
1346
- selector: unescape('firstAppChapter'),
1330
+ selector: "selectedChapter:",
1347
1331
  category: 'accessing',
1348
- fn: function (){
1332
+ fn: function (aChapter){
1349
1333
  var self=this;
1350
- 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", []));
1334
+ return (self['@selectedChapter']=aChapter);
1351
1335
  return self;},
1352
- args: [],
1353
- source: unescape('firstAppChapter%0A%09%5EDocChapter%20new%0A%09%09title%3A%20%27A%20first%20application%27%3B%0A%09%09contents%3A%20%27%0A%0ALet%27%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%27%27projects/hello/js%27%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%27%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%27%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%27%27%0A%20%20%20%20%20%20%20%20package%3A%20%27%27HelloApp%27%27%0A%0ANow%20click%20save%20and%20navigate%20to%20your%20new%20class%20in%20its%20new%20package.%0A%20Then%20click%20%27%27commit%20package%27%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%27%27HelloApp.js%27%27%5D%2C%0A%20%20%20%20%20%20%20%20prefix%3A%20%27%27projects/hello/js%27%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%27%27s%20make%20this%20class%20do%20something.%20Create%20a%20new%20message%20in%20the%20class%20browser%20by%20navigating%20to%20your%20class%2C%20then%20clicking%20%27%27not%20yet%20classified%27%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%27%27Hello%20world%21%27%27.%0A%09button%20%3A%3D%20%27%27%23sayHello%27%27%20asJQuery.%0A%09button%20click%3A%20%5Bbutton%20after%3A%20%27%27%3Cp%3E%27%27%20%2C%20msg%20%2C%20%27%27%3C/p%3E%27%27%5D.%0A%0AYour%20message%20isn%27%27t%20too%20helpful%20if%20it%20doesn%27%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%27%27HelloApp.js%27%27%5D%2C%0A%20%20%20%20%20%20%20%20prefix%3A%20%27%27projects/hello/js%27%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%27'),
1354
- messageSends: ["title:", "contents:", "new"],
1355
- referencedClasses: ["DocChapter"]
1336
+ args: ["aChapter"],
1337
+ source: "selectedChapter: aChapter\x0a\x09^selectedChapter := aChapter",
1338
+ messageSends: [],
1339
+ referencedClasses: []
1356
1340
  }),
1357
- smalltalk.TutorialsChapter);
1341
+ smalltalk.DocumentationWidget);
1358
1342
 
1359
1343
  smalltalk.addMethod(
1360
- unescape('_counterChapter'),
1344
+ "_updateChapterDiv",
1361
1345
  smalltalk.method({
1362
- selector: unescape('counterChapter'),
1363
- category: 'accessing',
1346
+ selector: "updateChapterDiv",
1347
+ category: 'updating',
1364
1348
  fn: function (){
1365
1349
  var self=this;
1366
- 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", []));
1350
+ smalltalk.send(self['@chapterDiv'], "_contents_", [(function(html){return smalltalk.send(html, "_with_", [smalltalk.send(self, "_selectedChapter", [])]);})]);
1367
1351
  return self;},
1368
1352
  args: [],
1369
- source: unescape('counterChapter%0A%09%5EDocChapter%20new%0A%09%09title%3A%20%27The%20counter%20application%27%3B%0A%09%09contents%3A%20%27%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%27%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%27%27count%20header%27%27%0A%20%20%20%20%20%20%20%20package%3A%20%27%27Tutorials%27%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%27%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++%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--%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%27%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%27%27body%27%27%20asJQuery%0A%0A%27'),
1370
- messageSends: ["title:", "contents:", "new"],
1371
- referencedClasses: ["DocChapter"]
1353
+ source: "updateChapterDiv\x0a\x09chapterDiv contents: [:html |\x0a\x09\x09html with: self selectedChapter]",
1354
+ messageSends: ["contents:", "with:", "selectedChapter"],
1355
+ referencedClasses: []
1372
1356
  }),
1373
- smalltalk.TutorialsChapter);
1357
+ smalltalk.DocumentationWidget);
1358
+
1374
1359
 
1360
+ smalltalk.addMethod(
1361
+ "_on_",
1362
+ smalltalk.method({
1363
+ selector: "on:",
1364
+ category: 'instance creation',
1365
+ fn: function (aBuilder){
1366
+ var self=this;
1367
+ return (function($rec){smalltalk.send($rec, "_builder_", [aBuilder]);return smalltalk.send($rec, "_yourself", []);})(smalltalk.send(self, "_new", []));
1368
+ return self;},
1369
+ args: ["aBuilder"],
1370
+ source: "on: aBuilder\x0a\x09^self new\x0a\x09\x09builder: aBuilder;\x0a\x09\x09yourself",
1371
+ messageSends: ["builder:", "yourself", "new"],
1372
+ referencedClasses: []
1373
+ }),
1374
+ smalltalk.DocumentationWidget.klass);
1375
1375
 
1376
1376