acts_as_dashboard 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +54 -0
  5. data/Rakefile +23 -0
  6. data/VERSION +1 -0
  7. data/acts_as_dashboard.gemspec +166 -0
  8. data/generators/dashboard/USAGE +23 -0
  9. data/generators/dashboard/dashboard_generator.rb +105 -0
  10. data/generators/dashboard/templates/controller.erb +39 -0
  11. data/generators/dashboard/templates/dashboard.css +66 -0
  12. data/generators/dashboard/templates/dashboard.js +305 -0
  13. data/generators/dashboard/templates/jqplot-0.9.7/jquery.jqplot.min.js +14 -0
  14. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.barRenderer.js +404 -0
  15. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.barRenderer.min.js +14 -0
  16. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasAxisLabelRenderer.js +200 -0
  17. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasAxisLabelRenderer.min.js +14 -0
  18. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasAxisTickRenderer.js +232 -0
  19. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasAxisTickRenderer.min.js +14 -0
  20. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasTextRenderer.js +408 -0
  21. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.canvasTextRenderer.min.js +14 -0
  22. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.categoryAxisRenderer.js +238 -0
  23. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.categoryAxisRenderer.min.js +14 -0
  24. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.cursor.js +812 -0
  25. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.cursor.min.js +14 -0
  26. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.dateAxisRenderer.js +313 -0
  27. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.dateAxisRenderer.min.js +14 -0
  28. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.dragable.js +203 -0
  29. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.dragable.min.js +14 -0
  30. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.highlighter.js +359 -0
  31. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.highlighter.min.js +14 -0
  32. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.logAxisRenderer.js +434 -0
  33. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.logAxisRenderer.min.js +14 -0
  34. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.mekkoAxisRenderer.js +595 -0
  35. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.mekkoAxisRenderer.min.js +14 -0
  36. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.mekkoRenderer.js +308 -0
  37. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.mekkoRenderer.min.js +14 -0
  38. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.ohlcRenderer.js +343 -0
  39. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.ohlcRenderer.min.js +14 -0
  40. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.pieRenderer.js +333 -0
  41. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.pieRenderer.min.js +14 -0
  42. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.pointLabels.js +307 -0
  43. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.pointLabels.js.orig +273 -0
  44. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.pointLabels.min.js +14 -0
  45. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.trendline.js +208 -0
  46. data/generators/dashboard/templates/jqplot-0.9.7/plugins/jqplot.trendline.min.js +14 -0
  47. data/generators/dashboard/templates/jquery.jqplot.min.css +1 -0
  48. data/generators/dashboard/templates/js.class-2.1.4/CHANGELOG +269 -0
  49. data/generators/dashboard/templates/js.class-2.1.4/MIT-LICENSE +30 -0
  50. data/generators/dashboard/templates/js.class-2.1.4/README +30 -0
  51. data/generators/dashboard/templates/js.class-2.1.4/min/command.js +1 -0
  52. data/generators/dashboard/templates/js.class-2.1.4/min/comparable.js +1 -0
  53. data/generators/dashboard/templates/js.class-2.1.4/min/constant_scope.js +1 -0
  54. data/generators/dashboard/templates/js.class-2.1.4/min/core.js +1 -0
  55. data/generators/dashboard/templates/js.class-2.1.4/min/decorator.js +1 -0
  56. data/generators/dashboard/templates/js.class-2.1.4/min/enumerable.js +1 -0
  57. data/generators/dashboard/templates/js.class-2.1.4/min/forwardable.js +1 -0
  58. data/generators/dashboard/templates/js.class-2.1.4/min/hash.js +1 -0
  59. data/generators/dashboard/templates/js.class-2.1.4/min/linked_list.js +1 -0
  60. data/generators/dashboard/templates/js.class-2.1.4/min/loader.js +1 -0
  61. data/generators/dashboard/templates/js.class-2.1.4/min/method_chain.js +1 -0
  62. data/generators/dashboard/templates/js.class-2.1.4/min/observable.js +1 -0
  63. data/generators/dashboard/templates/js.class-2.1.4/min/package.js +1 -0
  64. data/generators/dashboard/templates/js.class-2.1.4/min/proxy.js +1 -0
  65. data/generators/dashboard/templates/js.class-2.1.4/min/ruby.js +1 -0
  66. data/generators/dashboard/templates/js.class-2.1.4/min/set.js +1 -0
  67. data/generators/dashboard/templates/js.class-2.1.4/min/stack_trace.js +1 -0
  68. data/generators/dashboard/templates/js.class-2.1.4/min/state.js +1 -0
  69. data/generators/dashboard/templates/js.class-2.1.4/min/stdlib.js +16 -0
  70. data/generators/dashboard/templates/js.class-2.1.4/src/command.js +93 -0
  71. data/generators/dashboard/templates/js.class-2.1.4/src/comparable.js +37 -0
  72. data/generators/dashboard/templates/js.class-2.1.4/src/constant_scope.js +48 -0
  73. data/generators/dashboard/templates/js.class-2.1.4/src/core.js +1060 -0
  74. data/generators/dashboard/templates/js.class-2.1.4/src/decorator.js +50 -0
  75. data/generators/dashboard/templates/js.class-2.1.4/src/enumerable.js +505 -0
  76. data/generators/dashboard/templates/js.class-2.1.4/src/forwardable.js +22 -0
  77. data/generators/dashboard/templates/js.class-2.1.4/src/hash.js +334 -0
  78. data/generators/dashboard/templates/js.class-2.1.4/src/linked_list.js +114 -0
  79. data/generators/dashboard/templates/js.class-2.1.4/src/loader.js +458 -0
  80. data/generators/dashboard/templates/js.class-2.1.4/src/method_chain.js +172 -0
  81. data/generators/dashboard/templates/js.class-2.1.4/src/observable.js +55 -0
  82. data/generators/dashboard/templates/js.class-2.1.4/src/package.js +377 -0
  83. data/generators/dashboard/templates/js.class-2.1.4/src/proxy.js +58 -0
  84. data/generators/dashboard/templates/js.class-2.1.4/src/ruby.js +44 -0
  85. data/generators/dashboard/templates/js.class-2.1.4/src/set.js +332 -0
  86. data/generators/dashboard/templates/js.class-2.1.4/src/stack_trace.js +151 -0
  87. data/generators/dashboard/templates/js.class-2.1.4/src/state.js +95 -0
  88. data/generators/dashboard/templates/js.class-2.1.4/src/stdlib.js +2517 -0
  89. data/generators/dashboard/templates/show.html.erb +67 -0
  90. data/lib/acts_as_dashboard/app/views/dashboards/show.html.erb +67 -0
  91. data/lib/acts_as_dashboard/class_methods.rb +58 -0
  92. data/lib/acts_as_dashboard/config.rb +25 -0
  93. data/lib/acts_as_dashboard/instance_methods.rb +32 -0
  94. data/lib/acts_as_dashboard/line_graph_widget.rb +68 -0
  95. data/lib/acts_as_dashboard/public/javascripts/dashboard.js +305 -0
  96. data/lib/acts_as_dashboard/public/stylesheets/dashboard.css +66 -0
  97. data/lib/acts_as_dashboard/short_messages_widget.rb +25 -0
  98. data/lib/acts_as_dashboard/widget.rb +55 -0
  99. data/lib/acts_as_dashboard.rb +17 -0
  100. data/spec/acts_as_dashboard/class_method_specs.rb +188 -0
  101. data/spec/acts_as_dashboard/config_spec.rb +57 -0
  102. data/spec/acts_as_dashboard/instance_methods_spec.rb +134 -0
  103. data/spec/acts_as_dashboard/line_graph_widget_spec.rb +165 -0
  104. data/spec/acts_as_dashboard/short_messages_widget_spec.rb +69 -0
  105. data/spec/acts_as_dashboard/widget_spec.rb +6 -0
  106. data/spec/acts_as_dashboard_spec.rb +15 -0
  107. data/spec/shared/widget_behaviours.rb +171 -0
  108. data/spec/spec.opts +1 -0
  109. data/spec/spec_helper.rb +10 -0
  110. data/tasks/install.rake +8 -0
  111. data/tasks/install_javascript.rake +7 -0
  112. data/tasks/install_stylesheets.rake +7 -0
  113. metadata +209 -0
@@ -0,0 +1,458 @@
1
+ this.JS = this.JS || {};
2
+
3
+ JS.Package = function(loader) {
4
+ var Set = JS.Package.OrderedSet;
5
+ JS.Package._index(this);
6
+
7
+ this._loader = loader;
8
+ this._names = new Set();
9
+ this._deps = new Set();
10
+ this._uses = new Set();
11
+ this._observers = {};
12
+ this._events = {};
13
+ };
14
+
15
+ (function(klass) {
16
+ //================================================================
17
+ // Ordered list of unique elements, for storing dependencies
18
+
19
+ var Set = klass.OrderedSet = function(list, transform) {
20
+ this._members = this.list = [];
21
+ this._index = {};
22
+ if (!list) return;
23
+
24
+ for (var i = 0, n = list.length; i < n; i++)
25
+ this.push(transform ? transform(list[i]) : list[i]);
26
+ };
27
+
28
+ Set.prototype.push = function(item) {
29
+ var key = (item.id !== undefined) ? item.id : item,
30
+ index = this._index;
31
+
32
+ if (index.hasOwnProperty(key)) return;
33
+ index[key] = this._members.length;
34
+ this._members.push(item);
35
+ };
36
+
37
+ //================================================================
38
+ // Environment settings
39
+
40
+ klass._env = this;
41
+
42
+ if ((this.document || {}).getElementsByTagName) {
43
+ var script = document.getElementsByTagName('script')[0];
44
+ klass._isIE = (script.readyState !== undefined);
45
+ }
46
+
47
+
48
+ //================================================================
49
+ // Configuration methods, called by the DSL
50
+
51
+ var instance = klass.prototype;
52
+
53
+ instance.addDependency = function(pkg) {
54
+ this._deps.push(pkg);
55
+ };
56
+
57
+ instance.addSoftDependency = function(pkg) {
58
+ this._uses.push(pkg);
59
+ };
60
+
61
+ instance.addName = function(name) {
62
+ this._names.push(name);
63
+ klass.getFromCache(name).pkg = this;
64
+ };
65
+
66
+ instance.onload = function(block) {
67
+ this._onload = block;
68
+ };
69
+
70
+ //================================================================
71
+ // Event dispatchers, for communication between packages
72
+
73
+ instance.on = function(eventType, block, scope) {
74
+ if (this._events[eventType]) return block.call(scope);
75
+ var list = this._observers[eventType] = this._observers[eventType] || [];
76
+ list.push([block, scope]);
77
+ };
78
+
79
+ instance.fire = function(eventType) {
80
+ if (this._events[eventType]) return false;
81
+ this._events[eventType] = true;
82
+
83
+ var list = this._observers[eventType];
84
+ if (!list) return true;
85
+ delete this._observers[eventType];
86
+
87
+ for (var i = 0, n = list.length; i < n; i++)
88
+ list[i][0].call(list[i][1]);
89
+
90
+ return true;
91
+ };
92
+
93
+ //================================================================
94
+ // Loading frontend and other miscellany
95
+
96
+ instance.isLoaded = function(withExceptions) {
97
+ if (!withExceptions && this._isLoaded !== undefined) return this._isLoaded;
98
+
99
+ var names = this._names.list,
100
+ i = names.length,
101
+ name, object;
102
+
103
+ while (i--) { name = names[i];
104
+ object = klass.getObject(name);
105
+ if (object !== undefined) continue;
106
+ if (withExceptions)
107
+ throw new Error('Expected package at ' + this._loader + ' to define ' + name);
108
+ else
109
+ return this._isLoaded = false;
110
+ }
111
+ return this._isLoaded = true;
112
+ };
113
+
114
+ instance.load = function() {
115
+ if (!this.fire('request')) return;
116
+
117
+ var allDeps = this._deps.list.concat(this._uses.list),
118
+ startEvent = 'load', // could potentially use 'download' event in
119
+ listener = {}; // browsers that guarantee execution order
120
+
121
+ listener[startEvent] = this._deps.list;
122
+
123
+ klass.when(listener, function() {
124
+ klass.when({complete: allDeps, load: [this]}, function() {
125
+ this.fire('complete');
126
+ }, this);
127
+
128
+ var self = this, fireOnLoad = function() {
129
+ if (self._onload) self._onload();
130
+ self.isLoaded(true);
131
+ self.fire('load');
132
+ };
133
+
134
+ if (this.isLoaded()) {
135
+ this.fire('download');
136
+ return this.fire('load');
137
+ }
138
+
139
+ if (this._loader === undefined)
140
+ throw new Error('No load path found for ' + this._names.list[0]);
141
+
142
+ typeof this._loader === 'function'
143
+ ? this._loader(fireOnLoad)
144
+ : klass.Loader.loadFile(this._loader, fireOnLoad);
145
+
146
+ this.fire('download');
147
+ }, this);
148
+ };
149
+
150
+ instance.toString = function() {
151
+ return 'Package:' + this._names.list.join(',');
152
+ };
153
+
154
+ //================================================================
155
+ // Class-level event API, handles group listeners
156
+
157
+ klass.when = function(eventTable, block, scope) {
158
+ var eventList = [], event, packages, i;
159
+ for (event in eventTable) {
160
+ if (!eventTable.hasOwnProperty(event)) continue;
161
+ packages = new klass.OrderedSet(eventTable[event], function(name) { return klass.getByName(name) });
162
+ i = packages.list.length;
163
+ while (i--) eventList.push([event, packages.list[i]]);
164
+ }
165
+
166
+ var waiting = i = eventList.length;
167
+ if (waiting === 0) return block && block.call(scope);
168
+
169
+ while (i--) {
170
+ eventList[i][1].on(eventList[i][0], function() {
171
+ waiting -= 1;
172
+ if (waiting === 0 && block) block.call(scope);
173
+ });
174
+ eventList[i][1].load();
175
+ }
176
+ };
177
+
178
+ //================================================================
179
+ // Indexes for fast lookup by path and name, and assigning IDs
180
+
181
+ klass._autoIncrement = 1;
182
+ klass._indexByPath = {};
183
+ klass._indexByName = {};
184
+
185
+ klass._index = function(pkg) {
186
+ pkg.id = this._autoIncrement;
187
+ this._autoIncrement += 1;
188
+ };
189
+
190
+ klass.getByPath = function(loader) {
191
+ var path = loader.toString();
192
+ return this._indexByPath[path] = this._indexByPath[path] || new this(loader);
193
+ };
194
+
195
+ klass.getByName = function(name) {
196
+ if (typeof name !== 'string') return name;
197
+ var cached = this.getFromCache(name);
198
+ if (cached.pkg) return cached.pkg;
199
+
200
+ var placeholder = new this();
201
+ placeholder.addName(name);
202
+ return placeholder;
203
+ };
204
+
205
+ //================================================================
206
+ // Cache for named packages and runtime objects
207
+
208
+ klass.getFromCache = function(name) {
209
+ return this._indexByName[name] = this._indexByName[name] || {};
210
+ };
211
+
212
+ klass.getObject = function(name) {
213
+ var cached = this.getFromCache(name);
214
+ if (cached.obj !== undefined) return cached.obj;
215
+
216
+ var object = this._env,
217
+ parts = name.split('.'), part;
218
+
219
+ while (part = parts.shift()) object = object && object[part];
220
+
221
+ return this.getFromCache(name).obj = object;
222
+ };
223
+
224
+ })(JS.Package);
225
+
226
+
227
+ JS.Package.DomLoader = {
228
+ usable: function() {
229
+ return !!JS.Package.getObject('window.document.getElementsByTagName');
230
+ },
231
+
232
+ __FILE__: function() {
233
+ var scripts = document.getElementsByTagName('script');
234
+ return scripts[scripts.length - 1].src;
235
+ },
236
+
237
+ loadFile: function(path, fireCallbacks) {
238
+ var self = this,
239
+ tag = document.createElement('script');
240
+
241
+ tag.type = 'text/javascript';
242
+ tag.src = path;
243
+
244
+ tag.onload = tag.onreadystatechange = function() {
245
+ var state = tag.readyState, status = tag.status;
246
+ if ( !state || state === 'loaded' || state === 'complete' || (state === 4 && status === 200) ) {
247
+ fireCallbacks();
248
+ tag.onload = tag.onreadystatechange = self._K;
249
+ tag = null;
250
+ }
251
+ };
252
+
253
+ if (window.console && console.info)
254
+ console.info('Loading ' + path);
255
+
256
+ document.getElementsByTagName('head')[0].appendChild(tag);
257
+ },
258
+
259
+ _K: function() {}
260
+ };
261
+
262
+ JS.Package.ServerLoader = {
263
+ usable: function() {
264
+ return typeof JS.Package.getObject('load') === 'function' &&
265
+ typeof JS.Package.getObject('version') === 'function';
266
+ },
267
+
268
+ setup: function() {
269
+ var self = this;
270
+ load = (function(origLoad) {
271
+ return function() {
272
+ self._currentPath = arguments[0];
273
+ return origLoad.apply(JS.Package._env, arguments);
274
+ };
275
+ })(load);
276
+ },
277
+
278
+ __FILE__: function() {
279
+ return this._currentPath;
280
+ },
281
+
282
+ loadFile: function(path, fireCallbacks) {
283
+ load(path);
284
+ fireCallbacks();
285
+ }
286
+ };
287
+
288
+ (function() {
289
+ var candidates = [ JS.Package.DomLoader,
290
+ JS.Package.ServerLoader ],
291
+
292
+ n = candidates.length,
293
+ i, candidate;
294
+
295
+ for (i = 0; i < n; i++) {
296
+ candidate = candidates[i];
297
+ if (candidate.usable()) {
298
+ JS.Package.Loader = candidate;
299
+ if (candidate.setup) candidate.setup();
300
+ break;
301
+ }
302
+ }
303
+ })();
304
+
305
+
306
+ JS.Package.DSL = {
307
+ __FILE__: function() {
308
+ return JS.Package.Loader.__FILE__();
309
+ },
310
+
311
+ pkg: function(name, path) {
312
+ var pkg = path
313
+ ? JS.Package.getByPath(path)
314
+ : JS.Package.getByName(name);
315
+ pkg.addName(name);
316
+ return new JS.Package.Description(pkg);
317
+ },
318
+
319
+ file: function(path) {
320
+ var pkg = JS.Package.getByPath(path);
321
+ return new JS.Package.Description(pkg);
322
+ },
323
+
324
+ load: function(path, fireCallbacks) {
325
+ JS.Package.Loader.loadFile(path, fireCallbacks);
326
+ }
327
+ };
328
+
329
+ JS.Package.Description = function(pkg) {
330
+ this._pkg = pkg;
331
+ };
332
+
333
+ (function(klass) {
334
+
335
+ klass._batch = function(method, args) {
336
+ var n = args.length, method = this._pkg[method], i;
337
+ for (i = 0; i < n; i++) method.call(this._pkg, args[i]);
338
+ return this;
339
+ };
340
+
341
+ klass.provides = function() {
342
+ return this._batch('addName', arguments);
343
+ };
344
+
345
+ klass.requires = function() {
346
+ return this._batch('addDependency', arguments);
347
+ };
348
+
349
+ klass.uses = function() {
350
+ return this._batch('addSoftDependency', arguments);
351
+ };
352
+
353
+ klass.setup = function(block) {
354
+ this._pkg.onload(block);
355
+ return this;
356
+ };
357
+
358
+ })(JS.Package.Description.prototype);
359
+
360
+ JS.Package.DSL.loader = JS.Package.DSL.file;
361
+
362
+ JS.Packages = function(declaration) {
363
+ declaration.call(JS.Package.DSL);
364
+ };
365
+
366
+ JS.require = function() {
367
+ var requirements = [], i = 0;
368
+
369
+ while (typeof arguments[i] === 'string'){
370
+ requirements.push(arguments[i]);
371
+ i += 1;
372
+ }
373
+
374
+ JS.Package.when({complete: requirements}, arguments[i], arguments[i+1]);
375
+ };
376
+
377
+ require = JS.require;
378
+
379
+
380
+ JS.Packages(function() { with(this) {
381
+
382
+ var PATH = JS.Package._env.JSCLASS_PATH ||
383
+ __FILE__().replace(/[^\/]*$/g, '');
384
+
385
+ if (!/\/$/.test(PATH)) PATH = PATH + '/';
386
+
387
+ var module = function(name) { return file(PATH + name + '.js') };
388
+
389
+ module('core') .provides('JS.Module',
390
+ 'JS.Class',
391
+ 'JS.Kernel',
392
+ 'JS.Singleton',
393
+ 'JS.Interface');
394
+
395
+ module('comparable') .provides('JS.Comparable')
396
+ .requires('JS.Module');
397
+
398
+ module('constant_scope').provides('JS.ConstantScope')
399
+ .requires('JS.Module');
400
+
401
+ module('forwardable') .provides('JS.Forwardable')
402
+ .requires('JS.Module');
403
+
404
+ module('enumerable') .provides('JS.Enumerable')
405
+ .requires('JS.Module',
406
+ 'JS.Class');
407
+
408
+ module('observable') .provides('JS.Observable')
409
+ .requires('JS.Module');
410
+
411
+ module('hash') .provides('JS.Hash')
412
+ .requires('JS.Class',
413
+ 'JS.Enumerable',
414
+ 'JS.Comparable');
415
+
416
+ module('set') .provides('JS.Set',
417
+ 'JS.HashSet',
418
+ 'JS.SortedSet')
419
+ .requires('JS.Class',
420
+ 'JS.Enumerable')
421
+ .uses( 'JS.Hash');
422
+
423
+ module('linked_list') .provides('JS.LinkedList',
424
+ 'JS.LinkedList.Doubly',
425
+ 'JS.LinkedList.Doubly.Circular')
426
+ .requires('JS.Class',
427
+ 'JS.Enumerable');
428
+
429
+ module('command') .provides('JS.Command',
430
+ 'JS.Command.Stack')
431
+ .requires('JS.Class',
432
+ 'JS.Enumerable',
433
+ 'JS.Observable');
434
+
435
+ module('decorator') .provides('JS.Decorator')
436
+ .requires('JS.Module',
437
+ 'JS.Class');
438
+
439
+ module('method_chain') .provides('JS.MethodChain')
440
+ .requires('JS.Module',
441
+ 'JS.Kernel');
442
+
443
+ module('proxy') .provides('JS.Proxy',
444
+ 'JS.Proxy.Virtual')
445
+ .requires('JS.Module',
446
+ 'JS.Class');
447
+
448
+ module('ruby') .provides('JS.Ruby')
449
+ .requires('JS.Class');
450
+
451
+ module('stack_trace') .provides('JS.StackTrace')
452
+ .requires('JS.Module',
453
+ 'JS.Singleton');
454
+
455
+ module('state') .provides('JS.State')
456
+ .requires('JS.Module',
457
+ 'JS.Class');
458
+ }});
@@ -0,0 +1,172 @@
1
+ JS.MethodChain = function(base) {
2
+ var queue = [],
3
+ baseObject = base || {};
4
+
5
+ this.____ = function(method, args) {
6
+ queue.push({func: method, args: args});
7
+ };
8
+
9
+ this.fire = function(base) {
10
+ return JS.MethodChain.fire(queue, base || baseObject);
11
+ };
12
+ };
13
+
14
+ JS.MethodChain.fire = function(queue, object) {
15
+ var method, property, i, n;
16
+ loop: for (i = 0, n = queue.length; i < n; i++) {
17
+ method = queue[i];
18
+ if (object instanceof JS.MethodChain) {
19
+ object.____(method.func, method.args);
20
+ continue;
21
+ }
22
+ switch (typeof method.func) {
23
+ case 'string': property = object[method.func]; break;
24
+ case 'function': property = method.func; break;
25
+ case 'object': object = method.func; continue loop; break;
26
+ }
27
+ object = (typeof property === 'function')
28
+ ? property.apply(object, method.args)
29
+ : property;
30
+ }
31
+ return object;
32
+ };
33
+
34
+ JS.MethodChain.prototype = {
35
+ _: function() {
36
+ var base = arguments[0],
37
+ args, i, n;
38
+
39
+ switch (typeof base) {
40
+ case 'object': case 'function':
41
+ args = [];
42
+ for (i = 1, n = arguments.length; i < n; i++) args.push(arguments[i]);
43
+ this.____(base, args);
44
+ }
45
+ return this;
46
+ },
47
+
48
+ toFunction: function() {
49
+ var chain = this;
50
+ return function(object) { return chain.fire(object); };
51
+ }
52
+ };
53
+
54
+ JS.MethodChain.reserved = (function() {
55
+ var names = [], key;
56
+ for (key in new JS.MethodChain) names.push(key);
57
+ return new RegExp('^(?:' + names.join('|') + ')$');
58
+ })();
59
+
60
+ JS.MethodChain.addMethod = function(name) {
61
+ if (this.reserved.test(name)) return;
62
+ var func = this.prototype[name] = function() {
63
+ this.____(name, arguments);
64
+ return this;
65
+ };
66
+ func.displayName = 'MethodChain#' + name;
67
+ };
68
+
69
+ JS.MethodChain.displayName = 'MethodChain';
70
+
71
+ JS.MethodChain.addMethods = function(object) {
72
+ var methods = [], property, i;
73
+
74
+ for (property in object)
75
+ Number(property) !== property && methods.push(property);
76
+
77
+ if (object instanceof Array) {
78
+ i = object.length;
79
+ while (i--)
80
+ typeof object[i] === 'string' && methods.push(object[i]);
81
+ }
82
+ i = methods.length;
83
+ while (i--) this.addMethod(methods[i]);
84
+
85
+ object.__fns__ && this.addMethods(object.__fns__);
86
+ object.prototype && this.addMethods(object.prototype);
87
+ };
88
+
89
+ it = its = function() { return new JS.MethodChain; };
90
+
91
+ JS.Module.methodAdded(function(name) {
92
+ JS.MethodChain.addMethod(name);
93
+ });
94
+
95
+ JS.Kernel.include({
96
+ wait: function(time) {
97
+ var chain = new JS.MethodChain;
98
+
99
+ typeof time === 'number' &&
100
+ setTimeout(chain.fire.bind(chain, this), time * 1000);
101
+
102
+ this.forEach && typeof time === 'function' &&
103
+ this.forEach(function() {
104
+ setTimeout(chain.fire.bind(chain, arguments[0]), time.apply(this, arguments) * 1000);
105
+ });
106
+
107
+ return chain;
108
+ },
109
+
110
+ _: function() {
111
+ var base = arguments[0],
112
+ args = [],
113
+ i, n;
114
+
115
+ for (i = 1, n = arguments.length; i < n; i++) args.push(arguments[i]);
116
+ return (typeof base === 'object' && base) ||
117
+ (typeof base === 'function' && base.apply(this, args)) ||
118
+ this;
119
+ }
120
+ }, true);
121
+
122
+ (function() {
123
+ var queue = JS.Module.__chainq__,
124
+ n = queue.length;
125
+
126
+ while (n--) JS.MethodChain.addMethods(queue[n]);
127
+ JS.Module.__chainq__ = null;
128
+ })();
129
+
130
+ JS.MethodChain.addMethods([
131
+ "abbr", "abs", "accept", "acceptCharset", "accesskey", "acos", "action", "addEventListener",
132
+ "adjacentNode", "align", "alignWithTop", "alink", "alt", "anchor", "appendChild", "appendedNode",
133
+ "apply", "archive", "arguments", "arity", "asin", "atan", "atan2", "attrNode", "attributes",
134
+ "axis", "background", "bgcolor", "big", "blink", "blur", "bold", "border", "call", "caller",
135
+ "ceil", "cellpadding", "cellspacing", "char", "charAt", "charCodeAt", "charoff", "charset",
136
+ "checked", "childNodes", "cite", "className", "classid", "clear", "click", "clientHeight",
137
+ "clientLeft", "clientTop", "clientWidth", "cloneNode", "code", "codebase", "codetype", "color",
138
+ "cols", "colspan", "compact", "concat", "content", "coords", "cos", "data", "datetime", "declare",
139
+ "deep", "defer", "dir", "disabled", "dispatchEvent", "enctype", "event", "every", "exec", "exp",
140
+ "face", "filter", "firstChild", "fixed", "floor", "focus", "fontcolor", "fontsize", "forEach",
141
+ "frame", "frameborder", "fromCharCode", "getAttribute", "getAttributeNS", "getAttributeNode",
142
+ "getAttributeNodeNS", "getDate", "getDay", "getElementsByTagName", "getElementsByTagNameNS",
143
+ "getFullYear", "getHours", "getMilliseconds", "getMinutes", "getMonth", "getSeconds", "getTime",
144
+ "getTimezoneOffset", "getUTCDate", "getUTCDay", "getUTCFullYear", "getUTCHours",
145
+ "getUTCMilliseconds", "getUTCMinutes", "getUTCMonth", "getUTCSeconds", "getYear", "global",
146
+ "handler", "hasAttribute", "hasAttributeNS", "hasAttributes", "hasChildNodes", "hasOwnProperty",
147
+ "headers", "height", "href", "hreflang", "hspace", "htmlFor", "httpEquiv", "id", "ignoreCase",
148
+ "index", "indexOf", "innerHTML", "input", "insertBefore", "insertedNode", "isPrototypeOf", "ismap",
149
+ "italics", "join", "label", "lang", "language", "lastChild", "lastIndex", "lastIndexOf", "length",
150
+ "link", "listener", "localName", "log", "longdesc", "map", "marginheight", "marginwidth", "match",
151
+ "max", "maxlength", "media", "method", "min", "multiline", "multiple", "name", "namespace",
152
+ "namespaceURI", "nextSibling", "node", "nodeName", "nodeType", "nodeValue", "nohref", "noresize",
153
+ "normalize", "noshade", "now", "nowrap", "object", "offsetHeight", "offsetLeft", "offsetParent",
154
+ "offsetTop", "offsetWidth", "onblur", "onchange", "onclick", "ondblclick", "onfocus", "onkeydown",
155
+ "onkeypress", "onkeyup", "onload", "onmousedown", "onmousemove", "onmouseout", "onmouseover",
156
+ "onmouseup", "onreset", "onselect", "onsubmit", "onunload", "ownerDocument", "parentNode", "parse",
157
+ "pop", "pow", "prefix", "previousSibling", "profile", "prompt", "propertyIsEnumerable", "push",
158
+ "random", "readonly", "reduce", "reduceRight", "rel", "removeAttribute", "removeAttributeNS",
159
+ "removeAttributeNode", "removeChild", "removeEventListener", "removedNode", "replace",
160
+ "replaceChild", "replacedNode", "rev", "reverse", "round", "rows", "rowspan", "rules", "scheme",
161
+ "scope", "scrollHeight", "scrollIntoView", "scrollLeft", "scrollTop", "scrollWidth", "scrolling",
162
+ "search", "selected", "setAttribute", "setAttributeNS", "setAttributeNode", "setAttributeNodeNS",
163
+ "setDate", "setFullYear", "setHours", "setMilliseconds", "setMinutes", "setMonth", "setSeconds",
164
+ "setTime", "setUTCDate", "setUTCFullYear", "setUTCHours", "setUTCMilliseconds", "setUTCMinutes",
165
+ "setUTCMonth", "setUTCSeconds", "setYear", "shape", "shift", "sin", "size", "slice", "small",
166
+ "some", "sort", "source", "span", "splice", "split", "sqrt", "src", "standby", "start", "strike",
167
+ "style", "sub", "substr", "substring", "summary", "sup", "tabIndex", "tabindex", "tagName", "tan",
168
+ "target", "test", "text", "textContent", "title", "toArray", "toFunction", "toGMTString",
169
+ "toLocaleDateString", "toLocaleFormat", "toLocaleString", "toLocaleTimeString", "toLowerCase",
170
+ "toSource", "toString", "toUTCString", "toUpperCase", "type", "unshift", "unwatch", "useCapture",
171
+ "usemap", "valign", "value", "valueOf", "valuetype", "version", "vlink", "vspace", "watch", "width"
172
+ ]);
@@ -0,0 +1,55 @@
1
+ JS.Observable = new JS.Module('Observable', {
2
+ extend: {
3
+ DEFAULT_METHOD: 'update'
4
+ },
5
+
6
+ addObserver: function(observer, context) {
7
+ (this.__observers__ = this.__observers__ || []).push({_block: observer, _context: context || null});
8
+ },
9
+
10
+ removeObserver: function(observer, context) {
11
+ this.__observers__ = this.__observers__ || [];
12
+ context = context || null;
13
+ var i = this.countObservers();
14
+ while (i--) {
15
+ if (this.__observers__[i]._block === observer && this.__observers__[i]._context === context) {
16
+ this.__observers__.splice(i,1);
17
+ return;
18
+ }
19
+ }
20
+ },
21
+
22
+ removeObservers: function() {
23
+ this.__observers__ = [];
24
+ },
25
+
26
+ countObservers: function() {
27
+ return (this.__observers__ = this.__observers__ || []).length;
28
+ },
29
+
30
+ notifyObservers: function() {
31
+ if (!this.isChanged()) return;
32
+ var i = this.countObservers(), observer, block, context;
33
+ while (i--) {
34
+ observer = this.__observers__[i];
35
+ block = observer._block;
36
+ context = observer._context;
37
+ if (JS.isFn(block)) block.apply(context || null, arguments);
38
+ else block[context || JS.Observable.DEFAULT_METHOD].apply(block, arguments);
39
+ }
40
+ },
41
+
42
+ setChanged: function(state) {
43
+ this.__changed__ = !(state === false);
44
+ },
45
+
46
+ isChanged: function() {
47
+ if (this.__changed__ === undefined) this.__changed__ = true;
48
+ return !!this.__changed__;
49
+ }
50
+ });
51
+
52
+ JS.Observable.include({
53
+ subscribe: JS.Observable.instanceMethod('addObserver'),
54
+ unsubscribe: JS.Observable.instanceMethod('removeObserver')
55
+ }, true);