resin 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.markdown +52 -0
- data/amber/css/amber.css +519 -0
- data/amber/css/documentation.css +84 -0
- data/amber/css/profstef.css +75 -0
- data/amber/css/style.css +313 -0
- data/amber/images/amber.png +0 -0
- data/amber/images/amber_small.png +0 -0
- data/amber/images/off.png +0 -0
- data/amber/images/offHover.png +0 -0
- data/amber/images/presentation.png +0 -0
- data/amber/images/profstef.png +0 -0
- data/amber/images/sprite.png +0 -0
- data/amber/images/tinylogo.png +0 -0
- data/amber/images/twitterwall.png +0 -0
- data/amber/js/Additional-Examples.deploy.js +15 -0
- data/amber/js/Additional-Examples.js +21 -0
- data/amber/js/Benchfib.deploy.js +132 -0
- data/amber/js/Benchfib.js +167 -0
- data/amber/js/Canvas.deploy.js +1304 -0
- data/amber/js/Canvas.js +1885 -0
- data/amber/js/Compiler.deploy.js +1871 -0
- data/amber/js/Compiler.js +2616 -0
- data/amber/js/Documentation.deploy.js +961 -0
- data/amber/js/Documentation.js +1376 -0
- data/amber/js/Examples.deploy.js +53 -0
- data/amber/js/Examples.js +73 -0
- data/amber/js/IDE.deploy.js +3468 -0
- data/amber/js/IDE.js +4883 -0
- data/amber/js/Kernel-Announcements.deploy.js +107 -0
- data/amber/js/Kernel-Announcements.js +152 -0
- data/amber/js/Kernel-Classes.deploy.js +675 -0
- data/amber/js/Kernel-Classes.js +956 -0
- data/amber/js/Kernel-Collections.deploy.js +3273 -0
- data/amber/js/Kernel-Collections.js +4644 -0
- data/amber/js/Kernel-Exceptions.deploy.js +244 -0
- data/amber/js/Kernel-Exceptions.js +349 -0
- data/amber/js/Kernel-Methods.deploy.js +510 -0
- data/amber/js/Kernel-Methods.js +739 -0
- data/amber/js/Kernel-Objects.deploy.js +2698 -0
- data/amber/js/Kernel-Objects.js +3858 -0
- data/amber/js/Kernel-Tests.deploy.js +1419 -0
- data/amber/js/Kernel-Tests.js +1929 -0
- data/amber/js/Kernel-Transcript.deploy.js +142 -0
- data/amber/js/Kernel-Transcript.js +202 -0
- data/amber/js/SUnit.deploy.js +351 -0
- data/amber/js/SUnit.js +501 -0
- data/amber/js/amber.js +250 -0
- data/amber/js/boot.js +587 -0
- data/amber/js/compat.js +22 -0
- data/amber/js/init.js +8 -0
- data/amber/js/lib/CodeMirror/LICENSE +19 -0
- data/amber/js/lib/CodeMirror/amber.css +21 -0
- data/amber/js/lib/CodeMirror/codemirror.css +67 -0
- data/amber/js/lib/CodeMirror/codemirror.js +2144 -0
- data/amber/js/lib/CodeMirror/smalltalk.js +134 -0
- data/amber/js/lib/jQuery/jquery-1.4.4.min.js +167 -0
- data/amber/js/lib/jQuery/jquery-1.6.4.min.js +4 -0
- data/amber/js/lib/jQuery/jquery-ui-1.8.16.custom.min.js +791 -0
- data/amber/js/lib/jQuery/jquery.textarea.js +267 -0
- data/amber/js/lib/peg-0.6.2.min.js +2 -0
- data/amber/js/lib/showdown.js +419 -0
- data/amber/js/parser.js +4005 -0
- data/amber/js/parser.pegjs +220 -0
- data/amber/st/Benchfib.st +124 -0
- data/amber/st/Canvas.st +556 -0
- data/amber/st/Compiler.st +1425 -0
- data/amber/st/Documentation.st +758 -0
- data/amber/st/Examples.st +38 -0
- data/amber/st/IDE.st +2336 -0
- data/amber/st/Kernel-Announcements.st +61 -0
- data/amber/st/Kernel-Classes.st +403 -0
- data/amber/st/Kernel-Collections.st +1673 -0
- data/amber/st/Kernel-Exceptions.st +124 -0
- data/amber/st/Kernel-Methods.st +287 -0
- data/amber/st/Kernel-Objects.st +1489 -0
- data/amber/st/Kernel-Tests.st +892 -0
- data/amber/st/Kernel-Transcript.st +70 -0
- data/amber/st/SUnit.st +172 -0
- data/bin/runresin +12 -0
- data/lib/resin.rb +0 -0
- data/lib/resin/app/app.rb +121 -0
- data/lib/resin/app/views/index.haml +10 -0
- metadata +216 -0
data/amber/js/amber.js
ADDED
@@ -0,0 +1,250 @@
|
|
1
|
+
/* Amber package loading
|
2
|
+
usage example:
|
3
|
+
amber.load({
|
4
|
+
files: ['MyCategory1.js', 'MyCategory2.js'],
|
5
|
+
ready: function() {smalltalk.Browser._open()}
|
6
|
+
})
|
7
|
+
*/
|
8
|
+
|
9
|
+
amber = (function() {
|
10
|
+
var that = {};
|
11
|
+
|
12
|
+
var scripts = document.getElementsByTagName("script");
|
13
|
+
var src = scripts[ scripts.length - 1 ].src;
|
14
|
+
var home = src.split("/").slice(0, -2).join("/") + "/";
|
15
|
+
var nocache = '?' + (new Date()).getTime();
|
16
|
+
|
17
|
+
var debug;
|
18
|
+
var deploy;
|
19
|
+
|
20
|
+
var spec;
|
21
|
+
var jsToLoad = [];
|
22
|
+
var loadJS;
|
23
|
+
|
24
|
+
that.toggleIDE = function() {
|
25
|
+
if ($('#jtalk').length == 0) {
|
26
|
+
smalltalk.Browser._open();
|
27
|
+
} else if ($('#jtalk').is(':visible')) {
|
28
|
+
smalltalk.TabManager._current()._close();
|
29
|
+
} else {
|
30
|
+
smalltalk.TabManager._current()._open();
|
31
|
+
}
|
32
|
+
return false;
|
33
|
+
}
|
34
|
+
|
35
|
+
that.load = function(obj) {
|
36
|
+
spec = obj || {};
|
37
|
+
|
38
|
+
// In deployment mode, only the compressed version of Kernel
|
39
|
+
// and Canvas are loaded
|
40
|
+
deploy = spec.deploy || false;
|
41
|
+
debug = spec.debug || false;
|
42
|
+
|
43
|
+
// When debug is turned on, logs are written to the console,
|
44
|
+
// and the user will be prompted before they leave the page.
|
45
|
+
if (debug) {
|
46
|
+
window.onbeforeunload = function(){ return 'You will loose all code that you have not committed'; }
|
47
|
+
}
|
48
|
+
|
49
|
+
// Allow loading default Amber files from a different location
|
50
|
+
// e.g. http://amber-lang.net/amber/
|
51
|
+
if (spec.home) home = spec.home;
|
52
|
+
|
53
|
+
// Specify a version string to avoid wrong browser caching
|
54
|
+
if (spec.version) {
|
55
|
+
nocache = '?' + spec.version;
|
56
|
+
}
|
57
|
+
|
58
|
+
loadDependencies();
|
59
|
+
addJSToLoad('compat.js');
|
60
|
+
addJSToLoad('boot.js');
|
61
|
+
|
62
|
+
if (deploy) {
|
63
|
+
loadPackages([
|
64
|
+
'Kernel-Objects.deploy',
|
65
|
+
'Kernel-Classes.deploy',
|
66
|
+
'Kernel-Methods.deploy',
|
67
|
+
'Kernel-Collections.deploy',
|
68
|
+
'Kernel-Exceptions.deploy',
|
69
|
+
'Kernel-Transcript.deploy',
|
70
|
+
'Kernel-Announcements.deploy',
|
71
|
+
'Canvas.deploy'
|
72
|
+
]);
|
73
|
+
} else {
|
74
|
+
loadIDEDependencies();
|
75
|
+
loadCSS('amber.css');
|
76
|
+
|
77
|
+
loadPackages([
|
78
|
+
'Kernel-Objects',
|
79
|
+
'Kernel-Classes',
|
80
|
+
'Kernel-Methods',
|
81
|
+
'Kernel-Collections',
|
82
|
+
'Kernel-Exceptions',
|
83
|
+
'Kernel-Transcript',
|
84
|
+
'Kernel-Announcements',
|
85
|
+
'Canvas',
|
86
|
+
'Compiler',
|
87
|
+
'parser',
|
88
|
+
'IDE',
|
89
|
+
'SUnit',
|
90
|
+
'Examples',
|
91
|
+
'Benchfib',
|
92
|
+
'Kernel-Tests'
|
93
|
+
]);
|
94
|
+
}
|
95
|
+
|
96
|
+
var additionalFiles = spec.packages || spec.files;
|
97
|
+
if (additionalFiles) {
|
98
|
+
loadPackages(additionalFiles, spec.prefix);
|
99
|
+
}
|
100
|
+
|
101
|
+
// Be sure to setup & initialize smalltalk classes
|
102
|
+
addJSToLoad('init.js');
|
103
|
+
initializeSmalltalk();
|
104
|
+
};
|
105
|
+
|
106
|
+
function loadPackages(names, prefix){
|
107
|
+
var name, url;
|
108
|
+
var prefix = prefix || 'js';
|
109
|
+
|
110
|
+
for (var i=0; i < names.length; i++) {
|
111
|
+
name = names[i].split(/\.js$/)[0];
|
112
|
+
addJSToLoad(name + '.js', prefix);
|
113
|
+
}
|
114
|
+
};
|
115
|
+
|
116
|
+
function addJSToLoad(name, prefix) {
|
117
|
+
jsToLoad.push(buildJSURL(name, prefix));
|
118
|
+
};
|
119
|
+
|
120
|
+
function buildJSURL(name, prefix) {
|
121
|
+
var prefix = prefix || 'js';
|
122
|
+
var name = name;
|
123
|
+
|
124
|
+
if (!deploy) {
|
125
|
+
name = name + nocache;
|
126
|
+
}
|
127
|
+
|
128
|
+
return home + prefix + '/' + name;
|
129
|
+
};
|
130
|
+
|
131
|
+
function loadCSS(name, prefix) {
|
132
|
+
var prefix = prefix || 'css';
|
133
|
+
var name = name;
|
134
|
+
if (!deploy) {
|
135
|
+
name = name + nocache;
|
136
|
+
}
|
137
|
+
|
138
|
+
var url = home + prefix + '/' + name;
|
139
|
+
|
140
|
+
var link = document.createElement("link");
|
141
|
+
link.setAttribute("rel", "stylesheet");
|
142
|
+
link.setAttribute("type", "text/css");
|
143
|
+
link.setAttribute("href", url);
|
144
|
+
document.getElementsByTagName("head")[0].appendChild(link);
|
145
|
+
};
|
146
|
+
|
147
|
+
function loadDependencies() {
|
148
|
+
if (typeof jQuery == 'undefined') {
|
149
|
+
writeScriptTag(buildJSURL('lib/jQuery/jquery-1.6.4.min.js'));
|
150
|
+
}
|
151
|
+
|
152
|
+
if ((typeof jQuery == 'undefined') || (typeof jQuery.ui == 'undefined')) {
|
153
|
+
writeScriptTag(buildJSURL('lib/jQuery/jquery-ui-1.8.16.custom.min.js'));
|
154
|
+
}
|
155
|
+
};
|
156
|
+
|
157
|
+
function loadIDEDependencies() {
|
158
|
+
addJSToLoad('lib/jQuery/jquery.textarea.js');
|
159
|
+
addJSToLoad('lib/CodeMirror/codemirror.js');
|
160
|
+
addJSToLoad('lib/CodeMirror/smalltalk.js');
|
161
|
+
loadCSS('lib/CodeMirror/codemirror.css', 'js');
|
162
|
+
loadCSS('lib/CodeMirror/amber.css', 'js');
|
163
|
+
};
|
164
|
+
|
165
|
+
// This will be called after JS files have been loaded
|
166
|
+
function initializeSmalltalk() {
|
167
|
+
window.smalltalkReady = function() {
|
168
|
+
if (deploy) {
|
169
|
+
smalltalk.setDeploymentMode();
|
170
|
+
}
|
171
|
+
|
172
|
+
if (spec.ready) {
|
173
|
+
spec.ready();
|
174
|
+
}
|
175
|
+
}
|
176
|
+
|
177
|
+
loadAllJS();
|
178
|
+
};
|
179
|
+
|
180
|
+
/*
|
181
|
+
* When loaded using AJAX, scripts order not guaranteed.
|
182
|
+
* Load JS in the order they have been added using addJSToLoad().
|
183
|
+
* If loaded, will use jQuery's getScript instead of adding a script element
|
184
|
+
*/
|
185
|
+
function loadAllJS() {
|
186
|
+
loadJS = loadJSViaScriptTag;
|
187
|
+
if (typeof jQuery != 'undefined') {
|
188
|
+
loadJS = loadJSViaJQuery;
|
189
|
+
}
|
190
|
+
loadNextJS();
|
191
|
+
};
|
192
|
+
|
193
|
+
function loadNextJS() {
|
194
|
+
loadJS(jsToLoad[0], function(){
|
195
|
+
jsToLoad.shift();
|
196
|
+
if (jsToLoad.length > 0) {
|
197
|
+
loadNextJS();
|
198
|
+
}
|
199
|
+
});
|
200
|
+
};
|
201
|
+
|
202
|
+
function loadJSViaScriptTag(url, callback) {
|
203
|
+
writeScriptTag(url);
|
204
|
+
callback();
|
205
|
+
};
|
206
|
+
|
207
|
+
function loadJSViaJQuery(url, callback) {
|
208
|
+
$.getScript(jsToLoad[0], callback);
|
209
|
+
};
|
210
|
+
|
211
|
+
function writeScriptTag(src) {
|
212
|
+
var scriptString = '<script src="' + src + '" type="text/javascript"></script>';
|
213
|
+
document.write(scriptString);
|
214
|
+
};
|
215
|
+
|
216
|
+
function populateLocalPackages(){
|
217
|
+
var localStorageRE = /^smalltalk\.packages\.(.*)$/;
|
218
|
+
localPackages = {};
|
219
|
+
|
220
|
+
var match, key;
|
221
|
+
|
222
|
+
for(var i=0; i < localStorage.length; i++) {
|
223
|
+
key = localStorage.key(i);
|
224
|
+
|
225
|
+
if (match = key.match(localStorageRE)) {
|
226
|
+
localPackages[match[1]] = localStorage[key];
|
227
|
+
}
|
228
|
+
}
|
229
|
+
|
230
|
+
return localPackages;
|
231
|
+
};
|
232
|
+
|
233
|
+
function clearLocalPackages() {
|
234
|
+
for (var name in localPackages) {
|
235
|
+
log('Removing ' + name + ' from local storage');
|
236
|
+
localStorage.removeItem('smalltalk.packages.' + name);
|
237
|
+
}
|
238
|
+
};
|
239
|
+
|
240
|
+
function log(string) {
|
241
|
+
if (debug) {
|
242
|
+
console.log(string);
|
243
|
+
}
|
244
|
+
}
|
245
|
+
|
246
|
+
return that;
|
247
|
+
})();
|
248
|
+
|
249
|
+
window.loadAmber = amber.load;
|
250
|
+
window.toggleAmberIDE = amber.toggleIDE;
|
data/amber/js/boot.js
ADDED
@@ -0,0 +1,587 @@
|
|
1
|
+
/* ====================================================================
|
2
|
+
|
|
3
|
+
| Amber Smalltalk
|
4
|
+
| http://amber-lang.net
|
5
|
+
|
|
6
|
+
======================================================================
|
7
|
+
|
8
|
+
======================================================================
|
9
|
+
|
|
10
|
+
| Copyright (c) 2010-2011
|
11
|
+
| Nicolas Petton <petton.nicolas@gmail.com>
|
12
|
+
|
|
13
|
+
| Amber is released under the MIT license
|
14
|
+
|
|
15
|
+
| Permission is hereby granted, free of charge, to any person obtaining
|
16
|
+
| a copy of this software and associated documentation files (the
|
17
|
+
| 'Software'), to deal in the Software without restriction, including
|
18
|
+
| without limitation the rights to use, copy, modify, merge, publish,
|
19
|
+
| distribute, sublicense, and/or sell copies of the Software, and to
|
20
|
+
| permit persons to whom the Software is furnished to do so, subject to
|
21
|
+
| the following conditions:
|
22
|
+
|
|
23
|
+
| The above copyright notice and this permission notice shall be
|
24
|
+
| included in all copies or substantial portions of the Software.
|
25
|
+
|
|
26
|
+
| THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
27
|
+
| EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
28
|
+
| MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
29
|
+
| IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
30
|
+
| CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
31
|
+
| TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
32
|
+
| SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
33
|
+
|
|
34
|
+
==================================================================== */
|
35
|
+
|
36
|
+
/* Make that console is defined */
|
37
|
+
|
38
|
+
if (typeof console === "undefined") {
|
39
|
+
this.console = {
|
40
|
+
log: function() {},
|
41
|
+
warn: function() {},
|
42
|
+
info: function() {},
|
43
|
+
debug: function() {},
|
44
|
+
error: function() {}
|
45
|
+
};
|
46
|
+
}
|
47
|
+
|
48
|
+
|
49
|
+
/* Smalltalk constructors definition */
|
50
|
+
|
51
|
+
function SmalltalkObject(){};
|
52
|
+
function SmalltalkBehavior(){};
|
53
|
+
function SmalltalkClass(){};
|
54
|
+
function SmalltalkPackage(){};
|
55
|
+
function SmalltalkMetaclass(){
|
56
|
+
this.meta = true;
|
57
|
+
};
|
58
|
+
function SmalltalkMethod(){};
|
59
|
+
function SmalltalkNil(){};
|
60
|
+
|
61
|
+
function SmalltalkSymbol(string){
|
62
|
+
this.value = string;
|
63
|
+
};
|
64
|
+
|
65
|
+
function Smalltalk(){
|
66
|
+
|
67
|
+
var st = this;
|
68
|
+
|
69
|
+
/* This is the current call context object. While it is publicly available,
|
70
|
+
Use smalltalk.getThisContext() instead which will answer a safe copy of
|
71
|
+
the current context */
|
72
|
+
|
73
|
+
st.thisContext = undefined;
|
74
|
+
|
75
|
+
/* List of all reserved words in JavaScript. They may not be used as variables
|
76
|
+
in Smalltalk. */
|
77
|
+
|
78
|
+
st.reservedWords = ['break', 'case', 'catch', 'char', 'class', 'continue', 'debugger',
|
79
|
+
'default', 'delete', 'do', 'else', 'finally', 'for', 'function',
|
80
|
+
'if', 'in', 'instanceof', 'new', 'private', 'protected',
|
81
|
+
'public', 'return', 'static', 'switch', 'this', 'throw',
|
82
|
+
'try', 'typeof', 'var', 'void', 'while', 'with', 'yield'];
|
83
|
+
|
84
|
+
/* The symbol table ensures symbol unicity */
|
85
|
+
|
86
|
+
symbolTable = {};
|
87
|
+
st.symbolFor = function(string) {
|
88
|
+
if(symbolTable[string] === undefined) {
|
89
|
+
symbolTable[string] = new SmalltalkSymbol(string);
|
90
|
+
};
|
91
|
+
|
92
|
+
return symbolTable[string];
|
93
|
+
};
|
94
|
+
|
95
|
+
/* Unique ID number generator */
|
96
|
+
|
97
|
+
oid = 0;
|
98
|
+
st.nextId = function() {
|
99
|
+
oid += 1;
|
100
|
+
return oid;
|
101
|
+
};
|
102
|
+
|
103
|
+
/* We hold all Packages in a separate Object */
|
104
|
+
|
105
|
+
st.packages = {};
|
106
|
+
|
107
|
+
/* Smalltalk package creation. To add a Package, use smalltalk.addPackage() */
|
108
|
+
|
109
|
+
function pkg(spec) {
|
110
|
+
var that = new SmalltalkPackage();
|
111
|
+
that.pkgName = spec.pkgName;
|
112
|
+
that.properties = spec.properties || {};
|
113
|
+
return that;
|
114
|
+
};
|
115
|
+
|
116
|
+
/* Smalltalk class creation. A class is an instance of an automatically
|
117
|
+
created metaclass object. Newly created classes (not their metaclass)
|
118
|
+
should be added to the smalltalk object, see smalltalk.addClass().
|
119
|
+
Superclass linking is *not* handled here, see smalltalk.init() */
|
120
|
+
|
121
|
+
function klass(spec) {
|
122
|
+
var spec = spec || {};
|
123
|
+
var that;
|
124
|
+
if(spec.meta) {
|
125
|
+
that = new SmalltalkMetaclass();
|
126
|
+
} else {
|
127
|
+
that = new (klass({meta: true})).fn;
|
128
|
+
that.klass.instanceClass = that;
|
129
|
+
that.className = spec.className;
|
130
|
+
that.klass.className = that.className + ' class';
|
131
|
+
}
|
132
|
+
|
133
|
+
that.fn = spec.fn || function(){};
|
134
|
+
that.superclass = spec.superclass;
|
135
|
+
that.iVarNames = spec.iVarNames || [];
|
136
|
+
if(that.superclass) {
|
137
|
+
that.klass.superclass = that.superclass.klass;
|
138
|
+
}
|
139
|
+
that.pkg = spec.pkg;
|
140
|
+
that.fn.prototype.methods = {};
|
141
|
+
that.fn.prototype.inheritedMethods = {};
|
142
|
+
that.fn.prototype.klass = that;
|
143
|
+
|
144
|
+
return that;
|
145
|
+
};
|
146
|
+
|
147
|
+
/* Smalltalk method object. To add a method to a class,
|
148
|
+
use smalltalk.addMethod() */
|
149
|
+
|
150
|
+
st.method = function(spec) {
|
151
|
+
var that = new SmalltalkMethod();
|
152
|
+
that.selector = spec.selector;
|
153
|
+
that.jsSelector = spec.jsSelector;
|
154
|
+
that.args = spec.args || {};
|
155
|
+
that.category = spec.category;
|
156
|
+
that.source = spec.source;
|
157
|
+
that.messageSends = spec.messageSends || [];
|
158
|
+
that.referencedClasses = spec.referencedClasses || [];
|
159
|
+
that.fn = spec.fn;
|
160
|
+
return that
|
161
|
+
};
|
162
|
+
|
163
|
+
/* Initialize a class in its class hierarchy. Handle both class and
|
164
|
+
metaclasses. */
|
165
|
+
|
166
|
+
st.init = function(klass) {
|
167
|
+
var subclasses = st.subclasses(klass);
|
168
|
+
var methods;
|
169
|
+
|
170
|
+
if(klass.superclass && klass.superclass !== nil) {
|
171
|
+
methods = st.methods(klass.superclass);
|
172
|
+
|
173
|
+
//Methods linking
|
174
|
+
for(var i in methods) {
|
175
|
+
if(!klass.fn.prototype.methods[i]) {
|
176
|
+
klass.fn.prototype.inheritedMethods[i] = methods[i];
|
177
|
+
klass.fn.prototype[methods[i].jsSelector] = methods[i].fn;
|
178
|
+
}
|
179
|
+
}
|
180
|
+
}
|
181
|
+
|
182
|
+
for(var i=0;i<subclasses.length;i++) {
|
183
|
+
st.init(subclasses[i]);
|
184
|
+
}
|
185
|
+
if(klass.klass && !klass.meta) {
|
186
|
+
st.init(klass.klass);
|
187
|
+
}
|
188
|
+
};
|
189
|
+
|
190
|
+
/* Answer all registered Packages as Array */
|
191
|
+
|
192
|
+
st.packages.all = function() {
|
193
|
+
var packages = [];
|
194
|
+
for(var i in st.packages) {
|
195
|
+
if (!st.packages.hasOwnProperty(i) || typeof(st.packages[i]) === "function") continue;
|
196
|
+
packages.push(st.packages[i]);
|
197
|
+
}
|
198
|
+
return packages
|
199
|
+
};
|
200
|
+
|
201
|
+
/* Answer all registered Smalltalk classes */
|
202
|
+
|
203
|
+
st.classes = function() {
|
204
|
+
var classes = [];
|
205
|
+
for(var i in st) {
|
206
|
+
if(i.search(/^[A-Z]/g) != -1) {
|
207
|
+
classes.push(st[i]);
|
208
|
+
}
|
209
|
+
}
|
210
|
+
return classes
|
211
|
+
};
|
212
|
+
|
213
|
+
/* Answer all methods (included inherited ones) of klass. */
|
214
|
+
|
215
|
+
st.methods = function(klass) {
|
216
|
+
var methods = {};
|
217
|
+
for(var i in klass.fn.prototype.methods) {
|
218
|
+
methods[i] = klass.fn.prototype.methods[i]
|
219
|
+
}
|
220
|
+
for(var i in klass.fn.prototype.inheritedMethods) {
|
221
|
+
methods[i] = klass.fn.prototype.inheritedMethods[i]
|
222
|
+
}
|
223
|
+
return methods;
|
224
|
+
}
|
225
|
+
|
226
|
+
/* Answer the direct subclasses of klass. */
|
227
|
+
|
228
|
+
st.subclasses = function(klass) {
|
229
|
+
var subclasses = [];
|
230
|
+
var classes = st.classes();
|
231
|
+
for(var i in classes) {
|
232
|
+
if(classes[i].fn) {
|
233
|
+
//Metaclasses
|
234
|
+
if(classes[i].klass && classes[i].klass.superclass === klass) {
|
235
|
+
subclasses.push(classes[i].klass);
|
236
|
+
}
|
237
|
+
//Classes
|
238
|
+
if(classes[i].superclass === klass) {
|
239
|
+
subclasses.push(classes[i]);
|
240
|
+
}
|
241
|
+
}
|
242
|
+
}
|
243
|
+
return subclasses;
|
244
|
+
};
|
245
|
+
|
246
|
+
/* Create a new class wrapping a JavaScript constructor, and add it to the
|
247
|
+
global smalltalk object. Package is lazily created if it does not exist with given name. */
|
248
|
+
|
249
|
+
st.mapClassName = function(className, pkgName, fn, superclass) {
|
250
|
+
var pkg = st.addPackage(pkgName);
|
251
|
+
st[className] = klass({
|
252
|
+
className: className,
|
253
|
+
superclass: superclass,
|
254
|
+
pkg: pkg,
|
255
|
+
fn: fn
|
256
|
+
});
|
257
|
+
};
|
258
|
+
|
259
|
+
/* Add a package to the smalltalk.packages object, creating a new one if needed.
|
260
|
+
If pkgName is null or empty we return nil, which is an allowed package for a class.
|
261
|
+
If package already exists we still update the properties of it. */
|
262
|
+
|
263
|
+
st.addPackage = function(pkgName, properties) {
|
264
|
+
if(!pkgName) {return nil;}
|
265
|
+
if(!(st.packages[pkgName])) {
|
266
|
+
st.packages[pkgName] = pkg({
|
267
|
+
pkgName: pkgName,
|
268
|
+
properties: properties
|
269
|
+
});
|
270
|
+
} else {
|
271
|
+
if(properties) {
|
272
|
+
st.packages[pkgName].properties = properties;
|
273
|
+
}
|
274
|
+
}
|
275
|
+
return st.packages[pkgName];
|
276
|
+
};
|
277
|
+
|
278
|
+
/* Add a class to the smalltalk object, creating a new one if needed.
|
279
|
+
Package is lazily created if it does not exist with given name.*/
|
280
|
+
|
281
|
+
st.addClass = function(className, superclass, iVarNames, pkgName) {
|
282
|
+
var pkg = st.addPackage(pkgName);
|
283
|
+
if(st[className]) {
|
284
|
+
st[className].superclass = superclass;
|
285
|
+
st[className].iVarNames = iVarNames;
|
286
|
+
st[className].pkg = pkg || st[className].pkg;
|
287
|
+
} else {
|
288
|
+
st[className] = klass({
|
289
|
+
className: className,
|
290
|
+
superclass: superclass,
|
291
|
+
pkg: pkg,
|
292
|
+
iVarNames: iVarNames
|
293
|
+
});
|
294
|
+
}
|
295
|
+
};
|
296
|
+
|
297
|
+
/* Add a method to a class */
|
298
|
+
|
299
|
+
st.addMethod = function(jsSelector, method, klass) {
|
300
|
+
klass.fn.prototype[jsSelector] = method.fn;
|
301
|
+
klass.fn.prototype.methods[method.selector] = method;
|
302
|
+
method.methodClass = klass;
|
303
|
+
method.jsSelector = jsSelector;
|
304
|
+
};
|
305
|
+
|
306
|
+
/* Handles Smalltalk message send. Automatically converts undefined to the nil object.
|
307
|
+
If the receiver does not understand the selector, call its #doesNotUnderstand: method */
|
308
|
+
|
309
|
+
sendWithoutContext = function(receiver, selector, args, klass) {
|
310
|
+
if(receiver === undefined || receiver === null) {
|
311
|
+
receiver = nil;
|
312
|
+
}
|
313
|
+
if(!klass && receiver.klass && receiver[selector]) {
|
314
|
+
return receiver[selector].apply(receiver, args);
|
315
|
+
} else if(klass && klass.fn.prototype[selector]) {
|
316
|
+
return klass.fn.prototype[selector].apply(receiver, args)
|
317
|
+
}
|
318
|
+
return messageNotUnderstood(receiver, selector, args);
|
319
|
+
};
|
320
|
+
|
321
|
+
|
322
|
+
/* Handles unhandled errors during message sends */
|
323
|
+
|
324
|
+
sendWithContext = function(receiver, selector, args, klass) {
|
325
|
+
if(st.thisContext) {
|
326
|
+
return withContextSend(receiver, selector, args, klass);
|
327
|
+
} else {
|
328
|
+
try {return withContextSend(receiver, selector, args, klass)}
|
329
|
+
catch(error) {
|
330
|
+
// Reset the context stack in any case
|
331
|
+
st.thisContext = undefined;
|
332
|
+
if(error.smalltalkError) {
|
333
|
+
handleError(error);
|
334
|
+
} else {
|
335
|
+
throw(error);
|
336
|
+
}
|
337
|
+
}
|
338
|
+
}
|
339
|
+
};
|
340
|
+
|
341
|
+
/* Same as sendWithoutContext but creates a methodContext. */
|
342
|
+
|
343
|
+
withContextSend = function(receiver, selector, args, klass) {
|
344
|
+
var call, context;
|
345
|
+
if(receiver === undefined || receiver === null) {
|
346
|
+
receiver = nil;
|
347
|
+
}
|
348
|
+
if(!klass && receiver.klass && receiver[selector]) {
|
349
|
+
context = pushContext(receiver, selector, args);
|
350
|
+
call = receiver[selector].apply(receiver, args);
|
351
|
+
popContext(context);
|
352
|
+
return call;
|
353
|
+
} else if(klass && klass.fn.prototype[selector]) {
|
354
|
+
context = pushContext(receiver, selector, args);
|
355
|
+
call = klass.fn.prototype[selector].apply(receiver, args);
|
356
|
+
popContext(context);
|
357
|
+
return call;
|
358
|
+
}
|
359
|
+
return messageNotUnderstood(receiver, selector, args);
|
360
|
+
};
|
361
|
+
|
362
|
+
/* Handles Smalltalk errors. Triggers the registered ErrorHandler
|
363
|
+
(See the Smalltalk class ErrorHandler and its subclasses */
|
364
|
+
|
365
|
+
function handleError(error) {
|
366
|
+
st.thisContext = undefined;
|
367
|
+
smalltalk.ErrorHandler._current()._handleError_(error);
|
368
|
+
}
|
369
|
+
|
370
|
+
/* Handles #dnu: *and* JavaScript method calls.
|
371
|
+
if the receiver has no klass, we consider it a JS object (outside of the
|
372
|
+
Amber system). Else assume that the receiver understands #doesNotUnderstand: */
|
373
|
+
|
374
|
+
function messageNotUnderstood(receiver, selector, args) {
|
375
|
+
/* Handles JS method calls. */
|
376
|
+
if(receiver.klass === undefined || receiver.allowJavaScriptCalls) {
|
377
|
+
return callJavaScriptMethod(receiver, selector, args);
|
378
|
+
}
|
379
|
+
|
380
|
+
/* Handles not understood messages. Also see the Amber counter-part
|
381
|
+
Object>>doesNotUnderstand: */
|
382
|
+
|
383
|
+
return receiver._doesNotUnderstand_(
|
384
|
+
st.Message._new()
|
385
|
+
._selector_(st.convertSelector(selector))
|
386
|
+
._arguments_(args)
|
387
|
+
);
|
388
|
+
};
|
389
|
+
|
390
|
+
/* Call a method of a JS object, or answer a property if it exists.
|
391
|
+
Else try wrapping a JSObjectProxy around the receiver.
|
392
|
+
|
393
|
+
Converts keyword-based selectors by using the first
|
394
|
+
keyword only, but keeping all message arguments.
|
395
|
+
|
396
|
+
Example:
|
397
|
+
"self do: aBlock with: anObject" -> "self.do(aBlock, anObject)" */
|
398
|
+
|
399
|
+
function callJavaScriptMethod(receiver, selector, args) {
|
400
|
+
var jsSelector = selector._asJavaScriptSelector();
|
401
|
+
var jsProperty = receiver[jsSelector];
|
402
|
+
if(typeof jsProperty === "function") {
|
403
|
+
return jsProperty.apply(receiver, args);
|
404
|
+
} else if(jsProperty !== undefined) {
|
405
|
+
if(args[0]) {
|
406
|
+
receiver[jsSelector] = args[0];
|
407
|
+
return nil;
|
408
|
+
} else {
|
409
|
+
return jsProperty
|
410
|
+
}
|
411
|
+
}
|
412
|
+
|
413
|
+
return st.send(st.JSObjectProxy._on_(receiver), selector, args);
|
414
|
+
};
|
415
|
+
|
416
|
+
|
417
|
+
/* Reuse old contexts stored in oldContexts */
|
418
|
+
|
419
|
+
st.oldContexts = [];
|
420
|
+
|
421
|
+
|
422
|
+
/* Handle thisContext pseudo variable */
|
423
|
+
|
424
|
+
st.getThisContext = function() {
|
425
|
+
if(st.thisContext) {
|
426
|
+
return st.thisContext.copy();
|
427
|
+
} else {
|
428
|
+
return undefined;
|
429
|
+
}
|
430
|
+
}
|
431
|
+
|
432
|
+
pushContext = function(receiver, selector, temps) {
|
433
|
+
if(st.thisContext) {
|
434
|
+
return st.thisContext = st.thisContext.newContext(receiver, selector, temps);
|
435
|
+
} else {
|
436
|
+
return st.thisContext = new SmalltalkMethodContext(receiver, selector, temps);
|
437
|
+
}
|
438
|
+
};
|
439
|
+
|
440
|
+
popContext = function(context) {
|
441
|
+
if(context) {
|
442
|
+
context.removeYourself();
|
443
|
+
}
|
444
|
+
};
|
445
|
+
|
446
|
+
/* Convert a string to a valid smalltalk selector.
|
447
|
+
if you modify the following functions, also change String>>asSelector
|
448
|
+
accordingly */
|
449
|
+
|
450
|
+
st.convertSelector = function(selector) {
|
451
|
+
if(selector.match(/__/)) {
|
452
|
+
return convertBinarySelector(selector);
|
453
|
+
} else {
|
454
|
+
return convertKeywordSelector(selector);
|
455
|
+
}
|
456
|
+
};
|
457
|
+
|
458
|
+
function convertKeywordSelector(selector) {
|
459
|
+
return selector.replace(/^_/, '').replace(/_/g, ':');
|
460
|
+
};
|
461
|
+
|
462
|
+
function convertBinarySelector(selector) {
|
463
|
+
return selector
|
464
|
+
.replace(/^_/, '')
|
465
|
+
.replace(/_plus/, '+')
|
466
|
+
.replace(/_minus/, '-')
|
467
|
+
.replace(/_star/, '*')
|
468
|
+
.replace(/_slash/, '/')
|
469
|
+
.replace(/_gt/, '>')
|
470
|
+
.replace(/_lt/, '<')
|
471
|
+
.replace(/_eq/, '=')
|
472
|
+
.replace(/_comma/, ',')
|
473
|
+
.replace(/_at/, '@')
|
474
|
+
};
|
475
|
+
|
476
|
+
/* Converts a JavaScript object to valid Smalltalk Object */
|
477
|
+
st.readJSObject = function(js) {
|
478
|
+
var object = js;
|
479
|
+
var readObject = (js.constructor === Object);
|
480
|
+
var readArray = (js.constructor === Array);
|
481
|
+
|
482
|
+
if(readObject) {
|
483
|
+
object = smalltalk.Dictionary._new();
|
484
|
+
}
|
485
|
+
for(var i in js) {
|
486
|
+
if(readObject) {
|
487
|
+
object._at_put_(i, st.readJSObject(js[i]));
|
488
|
+
}
|
489
|
+
if(readArray) {
|
490
|
+
object[i] = st.readJSObject(js[i]);
|
491
|
+
}
|
492
|
+
}
|
493
|
+
return object;
|
494
|
+
};
|
495
|
+
|
496
|
+
/* Toggle deployment mode (no context will be handled during message send */
|
497
|
+
st.setDeploymentMode = function() {
|
498
|
+
st.send = sendWithoutContext;
|
499
|
+
};
|
500
|
+
|
501
|
+
st.setDevelopmentMode = function() {
|
502
|
+
st.send = sendWithContext;
|
503
|
+
}
|
504
|
+
|
505
|
+
/* Set development mode by default */
|
506
|
+
st.setDevelopmentMode();
|
507
|
+
}
|
508
|
+
|
509
|
+
function SmalltalkMethodContext(receiver, selector, temps, home) {
|
510
|
+
var that = this;
|
511
|
+
that.receiver = receiver;
|
512
|
+
that.selector = selector;
|
513
|
+
that.temps = temps || {};
|
514
|
+
that.homeContext = home;
|
515
|
+
|
516
|
+
that.copy = function() {
|
517
|
+
var home = that.homeContext;
|
518
|
+
if(home) {home = home.copy()}
|
519
|
+
return new SmalltalkMethodContext(
|
520
|
+
that.receiver,
|
521
|
+
that.selector,
|
522
|
+
that.temps,
|
523
|
+
home
|
524
|
+
);
|
525
|
+
}
|
526
|
+
|
527
|
+
that.newContext = function(receiver, selector, temps) {
|
528
|
+
var c = smalltalk.oldContexts.pop();
|
529
|
+
if(c) {
|
530
|
+
c.homeContext = that;
|
531
|
+
c.receiver = receiver;
|
532
|
+
c.selector = selector;
|
533
|
+
c.temps = temps || {};
|
534
|
+
} else {
|
535
|
+
c = new SmalltalkMethodContext(receiver, selector, temps, that);
|
536
|
+
}
|
537
|
+
return c;
|
538
|
+
}
|
539
|
+
|
540
|
+
that.removeYourself = function() {
|
541
|
+
smalltalk.thisContext = that.homeContext;
|
542
|
+
that.homeContext = undefined;
|
543
|
+
smalltalk.oldContexts.push(that);
|
544
|
+
}
|
545
|
+
}
|
546
|
+
|
547
|
+
/* Global Smalltalk objects. */
|
548
|
+
|
549
|
+
var nil = new SmalltalkNil();
|
550
|
+
var smalltalk = new Smalltalk();
|
551
|
+
|
552
|
+
if(this.jQuery) {
|
553
|
+
this.jQuery.allowJavaScriptCalls = true;
|
554
|
+
}
|
555
|
+
|
556
|
+
/****************************************************************************************/
|
557
|
+
|
558
|
+
|
559
|
+
/* Base classes mapping. If you edit this part, do not forget to set the superclass of the
|
560
|
+
object metaclass to Class after the definition of Object */
|
561
|
+
|
562
|
+
smalltalk.mapClassName("Object", "Kernel", SmalltalkObject);
|
563
|
+
smalltalk.mapClassName("Smalltalk", "Kernel", Smalltalk, smalltalk.Object);
|
564
|
+
smalltalk.mapClassName("Package", "Kernel", SmalltalkPackage, smalltalk.Object);
|
565
|
+
smalltalk.mapClassName("Behavior", "Kernel", SmalltalkBehavior, smalltalk.Object);
|
566
|
+
smalltalk.mapClassName("Class", "Kernel", SmalltalkClass, smalltalk.Behavior);
|
567
|
+
smalltalk.mapClassName("Metaclass", "Kernel", SmalltalkMetaclass, smalltalk.Behavior);
|
568
|
+
smalltalk.mapClassName("CompiledMethod", "Kernel", SmalltalkMethod, smalltalk.Object);
|
569
|
+
|
570
|
+
smalltalk.Object.klass.superclass = smalltalk.Class;
|
571
|
+
|
572
|
+
smalltalk.mapClassName("Number", "Kernel", Number, smalltalk.Object);
|
573
|
+
smalltalk.mapClassName("BlockClosure", "Kernel", Function, smalltalk.Object);
|
574
|
+
smalltalk.mapClassName("Boolean", "Kernel", Boolean, smalltalk.Object);
|
575
|
+
smalltalk.mapClassName("Date", "Kernel", Date, smalltalk.Object);
|
576
|
+
smalltalk.mapClassName("UndefinedObject", "Kernel", SmalltalkNil, smalltalk.Object);
|
577
|
+
|
578
|
+
smalltalk.mapClassName("Collection", "Kernel", null, smalltalk.Object);
|
579
|
+
smalltalk.mapClassName("SequenceableCollection", "Kernel", null, smalltalk.Collection);
|
580
|
+
smalltalk.mapClassName("CharacterArray", "Kernel", null, smalltalk.SequenceableCollection);
|
581
|
+
smalltalk.mapClassName("String", "Kernel", String, smalltalk.CharacterArray);
|
582
|
+
smalltalk.mapClassName("Symbol", "Kernel", SmalltalkSymbol, smalltalk.CharacterArray);
|
583
|
+
smalltalk.mapClassName("Array", "Kernel", Array, smalltalk.SequenceableCollection);
|
584
|
+
smalltalk.mapClassName("RegularExpression", "Kernel", RegExp, smalltalk.String);
|
585
|
+
|
586
|
+
smalltalk.mapClassName("Error", "Kernel", Error, smalltalk.Object);
|
587
|
+
smalltalk.mapClassName("MethodContext", "Kernel", SmalltalkMethodContext, smalltalk.Object);
|