rails_product 0.5

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.
Files changed (114) hide show
  1. data/CHANGELOG +619 -0
  2. data/MIT-LICENSE +21 -0
  3. data/README +195 -0
  4. data/Rakefile +413 -0
  5. data/bin/benchmarker +19 -0
  6. data/bin/breakpointer +3 -0
  7. data/bin/breakpointer_for_gem +4 -0
  8. data/bin/console +23 -0
  9. data/bin/console_sandbox +0 -0
  10. data/bin/destroy +7 -0
  11. data/bin/generate +7 -0
  12. data/bin/listener +86 -0
  13. data/bin/process/reaper +123 -0
  14. data/bin/process/spawner +54 -0
  15. data/bin/process/spinner +60 -0
  16. data/bin/profiler +34 -0
  17. data/bin/rails +17 -0
  18. data/bin/rails_product +17 -0
  19. data/bin/runner +28 -0
  20. data/bin/server +125 -0
  21. data/bin/tracker +69 -0
  22. data/bin/update +5 -0
  23. data/configs/apache/vhost.example.conf +42 -0
  24. data/configs/apache.conf +40 -0
  25. data/configs/database.yml +23 -0
  26. data/configs/empty.log +0 -0
  27. data/configs/routes.rb +19 -0
  28. data/dispatches/dispatch.fcgi +24 -0
  29. data/dispatches/dispatch.rb +10 -0
  30. data/dispatches/gateway.cgi +97 -0
  31. data/doc/README_FOR_APP +2 -0
  32. data/environments/development.rb +14 -0
  33. data/environments/environment.rb +101 -0
  34. data/environments/production.rb +8 -0
  35. data/environments/test.rb +17 -0
  36. data/fresh_rakefile +223 -0
  37. data/helpers/application.rb +4 -0
  38. data/helpers/application_helper.rb +3 -0
  39. data/helpers/test_helper.rb +26 -0
  40. data/html/404.html +8 -0
  41. data/html/500.html +8 -0
  42. data/html/favicon.ico +0 -0
  43. data/html/index.html +78 -0
  44. data/html/javascripts/controls.js +446 -0
  45. data/html/javascripts/dragdrop.js +537 -0
  46. data/html/javascripts/effects.js +612 -0
  47. data/html/javascripts/prototype.js +1038 -0
  48. data/html/robots.txt +1 -0
  49. data/lib/binding_of_caller.rb +83 -0
  50. data/lib/breakpoint.rb +523 -0
  51. data/lib/breakpoint_client.rb +196 -0
  52. data/lib/code_statistics.rb +104 -0
  53. data/lib/console_sandbox.rb +6 -0
  54. data/lib/dispatcher.rb +59 -0
  55. data/lib/fcgi_handler.rb +156 -0
  56. data/lib/productize.rb +116 -0
  57. data/lib/rails_generator/base.rb +203 -0
  58. data/lib/rails_generator/commands.rb +409 -0
  59. data/lib/rails_generator/generators/applications/app/USAGE +16 -0
  60. data/lib/rails_generator/generators/applications/app/app_generator.rb +126 -0
  61. data/lib/rails_generator/generators/applications/productized_app/USAGE +16 -0
  62. data/lib/rails_generator/generators/applications/productized_app/productized_app_generator.rb +133 -0
  63. data/lib/rails_generator/generators/components/controller/USAGE +30 -0
  64. data/lib/rails_generator/generators/components/controller/controller_generator.rb +38 -0
  65. data/lib/rails_generator/generators/components/controller/templates/controller.rb +10 -0
  66. data/lib/rails_generator/generators/components/controller/templates/functional_test.rb +18 -0
  67. data/lib/rails_generator/generators/components/controller/templates/helper.rb +2 -0
  68. data/lib/rails_generator/generators/components/controller/templates/view.rhtml +2 -0
  69. data/lib/rails_generator/generators/components/mailer/USAGE +19 -0
  70. data/lib/rails_generator/generators/components/mailer/mailer_generator.rb +32 -0
  71. data/lib/rails_generator/generators/components/mailer/templates/fixture.rhtml +3 -0
  72. data/lib/rails_generator/generators/components/mailer/templates/mailer.rb +13 -0
  73. data/lib/rails_generator/generators/components/mailer/templates/unit_test.rb +37 -0
  74. data/lib/rails_generator/generators/components/mailer/templates/view.rhtml +3 -0
  75. data/lib/rails_generator/generators/components/migration/USAGE +14 -0
  76. data/lib/rails_generator/generators/components/migration/migration_generator.rb +9 -0
  77. data/lib/rails_generator/generators/components/migration/templates/migration.rb +7 -0
  78. data/lib/rails_generator/generators/components/model/USAGE +17 -0
  79. data/lib/rails_generator/generators/components/model/model_generator.rb +18 -0
  80. data/lib/rails_generator/generators/components/model/templates/fixtures.yml +5 -0
  81. data/lib/rails_generator/generators/components/model/templates/model.rb +2 -0
  82. data/lib/rails_generator/generators/components/model/templates/unit_test.rb +14 -0
  83. data/lib/rails_generator/generators/components/scaffold/USAGE +32 -0
  84. data/lib/rails_generator/generators/components/scaffold/scaffold_generator.rb +178 -0
  85. data/lib/rails_generator/generators/components/scaffold/templates/controller.rb +54 -0
  86. data/lib/rails_generator/generators/components/scaffold/templates/form.rhtml +3 -0
  87. data/lib/rails_generator/generators/components/scaffold/templates/form_scaffolding.rhtml +1 -0
  88. data/lib/rails_generator/generators/components/scaffold/templates/functional_test.rb +98 -0
  89. data/lib/rails_generator/generators/components/scaffold/templates/helper.rb +2 -0
  90. data/lib/rails_generator/generators/components/scaffold/templates/layout.rhtml +13 -0
  91. data/lib/rails_generator/generators/components/scaffold/templates/style.css +74 -0
  92. data/lib/rails_generator/generators/components/scaffold/templates/view_edit.rhtml +9 -0
  93. data/lib/rails_generator/generators/components/scaffold/templates/view_list.rhtml +27 -0
  94. data/lib/rails_generator/generators/components/scaffold/templates/view_new.rhtml +8 -0
  95. data/lib/rails_generator/generators/components/scaffold/templates/view_show.rhtml +8 -0
  96. data/lib/rails_generator/generators/components/web_service/USAGE +28 -0
  97. data/lib/rails_generator/generators/components/web_service/templates/api_definition.rb +5 -0
  98. data/lib/rails_generator/generators/components/web_service/templates/controller.rb +8 -0
  99. data/lib/rails_generator/generators/components/web_service/templates/functional_test.rb +19 -0
  100. data/lib/rails_generator/generators/components/web_service/web_service_generator.rb +29 -0
  101. data/lib/rails_generator/lookup.rb +206 -0
  102. data/lib/rails_generator/manifest.rb +53 -0
  103. data/lib/rails_generator/options.rb +134 -0
  104. data/lib/rails_generator/scripts/destroy.rb +7 -0
  105. data/lib/rails_generator/scripts/generate.rb +7 -0
  106. data/lib/rails_generator/scripts/update.rb +12 -0
  107. data/lib/rails_generator/scripts.rb +83 -0
  108. data/lib/rails_generator/simple_logger.rb +46 -0
  109. data/lib/rails_generator/spec.rb +44 -0
  110. data/lib/rails_generator.rb +43 -0
  111. data/lib/rubyprof_ext.rb +35 -0
  112. data/lib/webrick_server.rb +148 -0
  113. data/sites/fresh_rakefile +176 -0
  114. metadata +250 -0
@@ -0,0 +1,1038 @@
1
+ /* Prototype JavaScript framework, version 1.3.1
2
+ * (c) 2005 Sam Stephenson <sam@conio.net>
3
+ *
4
+ * THIS FILE IS AUTOMATICALLY GENERATED. When sending patches, please diff
5
+ * against the source tree, available from the Prototype darcs repository.
6
+ *
7
+ * Prototype is freely distributable under the terms of an MIT-style license.
8
+ *
9
+ * For details, see the Prototype web site: http://prototype.conio.net/
10
+ *
11
+ /*--------------------------------------------------------------------------*/
12
+
13
+ var Prototype = {
14
+ Version: '1.3.1',
15
+ emptyFunction: function() {}
16
+ }
17
+
18
+ var Class = {
19
+ create: function() {
20
+ return function() {
21
+ this.initialize.apply(this, arguments);
22
+ }
23
+ }
24
+ }
25
+
26
+ var Abstract = new Object();
27
+
28
+ Object.extend = function(destination, source) {
29
+ for (property in source) {
30
+ destination[property] = source[property];
31
+ }
32
+ return destination;
33
+ }
34
+
35
+ Object.prototype.extend = function(object) {
36
+ return Object.extend.apply(this, [this, object]);
37
+ }
38
+
39
+ Function.prototype.bind = function(object) {
40
+ var __method = this;
41
+ return function() {
42
+ __method.apply(object, arguments);
43
+ }
44
+ }
45
+
46
+ Function.prototype.bindAsEventListener = function(object) {
47
+ var __method = this;
48
+ return function(event) {
49
+ __method.call(object, event || window.event);
50
+ }
51
+ }
52
+
53
+ Number.prototype.toColorPart = function() {
54
+ var digits = this.toString(16);
55
+ if (this < 16) return '0' + digits;
56
+ return digits;
57
+ }
58
+
59
+ var Try = {
60
+ these: function() {
61
+ var returnValue;
62
+
63
+ for (var i = 0; i < arguments.length; i++) {
64
+ var lambda = arguments[i];
65
+ try {
66
+ returnValue = lambda();
67
+ break;
68
+ } catch (e) {}
69
+ }
70
+
71
+ return returnValue;
72
+ }
73
+ }
74
+
75
+ /*--------------------------------------------------------------------------*/
76
+
77
+ var PeriodicalExecuter = Class.create();
78
+ PeriodicalExecuter.prototype = {
79
+ initialize: function(callback, frequency) {
80
+ this.callback = callback;
81
+ this.frequency = frequency;
82
+ this.currentlyExecuting = false;
83
+
84
+ this.registerCallback();
85
+ },
86
+
87
+ registerCallback: function() {
88
+ setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
89
+ },
90
+
91
+ onTimerEvent: function() {
92
+ if (!this.currentlyExecuting) {
93
+ try {
94
+ this.currentlyExecuting = true;
95
+ this.callback();
96
+ } finally {
97
+ this.currentlyExecuting = false;
98
+ }
99
+ }
100
+ }
101
+ }
102
+
103
+ /*--------------------------------------------------------------------------*/
104
+
105
+ function $() {
106
+ var elements = new Array();
107
+
108
+ for (var i = 0; i < arguments.length; i++) {
109
+ var element = arguments[i];
110
+ if (typeof element == 'string')
111
+ element = document.getElementById(element);
112
+
113
+ if (arguments.length == 1)
114
+ return element;
115
+
116
+ elements.push(element);
117
+ }
118
+
119
+ return elements;
120
+ }
121
+
122
+ if (!Array.prototype.push) {
123
+ Array.prototype.push = function() {
124
+ var startLength = this.length;
125
+ for (var i = 0; i < arguments.length; i++)
126
+ this[startLength + i] = arguments[i];
127
+ return this.length;
128
+ }
129
+ }
130
+
131
+ if (!Function.prototype.apply) {
132
+ // Based on code from http://www.youngpup.net/
133
+ Function.prototype.apply = function(object, parameters) {
134
+ var parameterStrings = new Array();
135
+ if (!object) object = window;
136
+ if (!parameters) parameters = new Array();
137
+
138
+ for (var i = 0; i < parameters.length; i++)
139
+ parameterStrings[i] = 'parameters[' + i + ']';
140
+
141
+ object.__apply__ = this;
142
+ var result = eval('object.__apply__(' +
143
+ parameterStrings[i].join(', ') + ')');
144
+ object.__apply__ = null;
145
+
146
+ return result;
147
+ }
148
+ }
149
+
150
+ String.prototype.extend({
151
+ stripTags: function() {
152
+ return this.replace(/<\/?[^>]+>/gi, '');
153
+ },
154
+
155
+ escapeHTML: function() {
156
+ var div = document.createElement('div');
157
+ var text = document.createTextNode(this);
158
+ div.appendChild(text);
159
+ return div.innerHTML;
160
+ },
161
+
162
+ unescapeHTML: function() {
163
+ var div = document.createElement('div');
164
+ div.innerHTML = this.stripTags();
165
+ return div.childNodes[0].nodeValue;
166
+ }
167
+ });
168
+
169
+ var Ajax = {
170
+ getTransport: function() {
171
+ return Try.these(
172
+ function() {return new ActiveXObject('Msxml2.XMLHTTP')},
173
+ function() {return new ActiveXObject('Microsoft.XMLHTTP')},
174
+ function() {return new XMLHttpRequest()}
175
+ ) || false;
176
+ }
177
+ }
178
+
179
+ Ajax.Base = function() {};
180
+ Ajax.Base.prototype = {
181
+ setOptions: function(options) {
182
+ this.options = {
183
+ method: 'post',
184
+ asynchronous: true,
185
+ parameters: ''
186
+ }.extend(options || {});
187
+ },
188
+
189
+ responseIsSuccess: function() {
190
+ return this.transport.status == undefined
191
+ || this.transport.status == 0
192
+ || (this.transport.status >= 200 && this.transport.status < 300);
193
+ },
194
+
195
+ responseIsFailure: function() {
196
+ return !this.responseIsSuccess();
197
+ }
198
+ }
199
+
200
+ Ajax.Request = Class.create();
201
+ Ajax.Request.Events =
202
+ ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
203
+
204
+ Ajax.Request.prototype = (new Ajax.Base()).extend({
205
+ initialize: function(url, options) {
206
+ this.transport = Ajax.getTransport();
207
+ this.setOptions(options);
208
+ this.request(url);
209
+ },
210
+
211
+ request: function(url) {
212
+ var parameters = this.options.parameters || '';
213
+ if (parameters.length > 0) parameters += '&_=';
214
+
215
+ try {
216
+ if (this.options.method == 'get')
217
+ url += '?' + parameters;
218
+
219
+ this.transport.open(this.options.method, url,
220
+ this.options.asynchronous);
221
+
222
+ if (this.options.asynchronous) {
223
+ this.transport.onreadystatechange = this.onStateChange.bind(this);
224
+ setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
225
+ }
226
+
227
+ this.setRequestHeaders();
228
+
229
+ var body = this.options.postBody ? this.options.postBody : parameters;
230
+ this.transport.send(this.options.method == 'post' ? body : null);
231
+
232
+ } catch (e) {
233
+ }
234
+ },
235
+
236
+ setRequestHeaders: function() {
237
+ var requestHeaders =
238
+ ['X-Requested-With', 'XMLHttpRequest',
239
+ 'X-Prototype-Version', Prototype.Version];
240
+
241
+ if (this.options.method == 'post') {
242
+ requestHeaders.push('Content-type',
243
+ 'application/x-www-form-urlencoded');
244
+
245
+ /* Force "Connection: close" for Mozilla browsers to work around
246
+ * a bug where XMLHttpReqeuest sends an incorrect Content-length
247
+ * header. See Mozilla Bugzilla #246651.
248
+ */
249
+ if (this.transport.overrideMimeType)
250
+ requestHeaders.push('Connection', 'close');
251
+ }
252
+
253
+ if (this.options.requestHeaders)
254
+ requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
255
+
256
+ for (var i = 0; i < requestHeaders.length; i += 2)
257
+ this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
258
+ },
259
+
260
+ onStateChange: function() {
261
+ var readyState = this.transport.readyState;
262
+ if (readyState != 1)
263
+ this.respondToReadyState(this.transport.readyState);
264
+ },
265
+
266
+ respondToReadyState: function(readyState) {
267
+ var event = Ajax.Request.Events[readyState];
268
+
269
+ if (event == 'Complete')
270
+ (this.options['on' + this.transport.status]
271
+ || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
272
+ || Prototype.emptyFunction)(this.transport);
273
+
274
+ (this.options['on' + event] || Prototype.emptyFunction)(this.transport);
275
+
276
+ /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
277
+ if (event == 'Complete')
278
+ this.transport.onreadystatechange = Prototype.emptyFunction;
279
+ }
280
+ });
281
+
282
+ Ajax.Updater = Class.create();
283
+ Ajax.Updater.ScriptFragment = '(?:<script.*?>)((\n|.)*?)(?:<\/script>)';
284
+
285
+ Ajax.Updater.prototype.extend(Ajax.Request.prototype).extend({
286
+ initialize: function(container, url, options) {
287
+ this.containers = {
288
+ success: container.success ? $(container.success) : $(container),
289
+ failure: container.failure ? $(container.failure) :
290
+ (container.success ? null : $(container))
291
+ }
292
+
293
+ this.transport = Ajax.getTransport();
294
+ this.setOptions(options);
295
+
296
+ var onComplete = this.options.onComplete || Prototype.emptyFunction;
297
+ this.options.onComplete = (function() {
298
+ this.updateContent();
299
+ onComplete(this.transport);
300
+ }).bind(this);
301
+
302
+ this.request(url);
303
+ },
304
+
305
+ updateContent: function() {
306
+ var receiver = this.responseIsSuccess() ?
307
+ this.containers.success : this.containers.failure;
308
+
309
+ var match = new RegExp(Ajax.Updater.ScriptFragment, 'img');
310
+ var response = this.transport.responseText.replace(match, '');
311
+ var scripts = this.transport.responseText.match(match);
312
+
313
+ if (receiver) {
314
+ if (this.options.insertion) {
315
+ new this.options.insertion(receiver, response);
316
+ } else {
317
+ receiver.innerHTML = response;
318
+ }
319
+ }
320
+
321
+ if (this.responseIsSuccess()) {
322
+ if (this.onComplete)
323
+ setTimeout((function() {this.onComplete(
324
+ this.transport)}).bind(this), 10);
325
+ }
326
+
327
+ if (this.options.evalScripts && scripts) {
328
+ match = new RegExp(Ajax.Updater.ScriptFragment, 'im');
329
+ setTimeout((function() {
330
+ for (var i = 0; i < scripts.length; i++)
331
+ eval(scripts[i].match(match)[1]);
332
+ }).bind(this), 10);
333
+ }
334
+ }
335
+ });
336
+
337
+ Ajax.PeriodicalUpdater = Class.create();
338
+ Ajax.PeriodicalUpdater.prototype = (new Ajax.Base()).extend({
339
+ initialize: function(container, url, options) {
340
+ this.setOptions(options);
341
+ this.onComplete = this.options.onComplete;
342
+
343
+ this.frequency = (this.options.frequency || 2);
344
+ this.decay = 1;
345
+
346
+ this.updater = {};
347
+ this.container = container;
348
+ this.url = url;
349
+
350
+ this.start();
351
+ },
352
+
353
+ start: function() {
354
+ this.options.onComplete = this.updateComplete.bind(this);
355
+ this.onTimerEvent();
356
+ },
357
+
358
+ stop: function() {
359
+ this.updater.onComplete = undefined;
360
+ clearTimeout(this.timer);
361
+ (this.onComplete || Ajax.emptyFunction).apply(this, arguments);
362
+ },
363
+
364
+ updateComplete: function(request) {
365
+ if (this.options.decay) {
366
+ this.decay = (request.responseText == this.lastText ?
367
+ this.decay * this.options.decay : 1);
368
+
369
+ this.lastText = request.responseText;
370
+ }
371
+ this.timer = setTimeout(this.onTimerEvent.bind(this),
372
+ this.decay * this.frequency * 1000);
373
+ },
374
+
375
+ onTimerEvent: function() {
376
+ this.updater = new Ajax.Updater(this.container, this.url, this.options);
377
+ }
378
+ });
379
+
380
+ document.getElementsByClassName = function(className) {
381
+ var children = document.getElementsByTagName('*') || document.all;
382
+ var elements = new Array();
383
+
384
+ for (var i = 0; i < children.length; i++) {
385
+ var child = children[i];
386
+ var classNames = child.className.split(' ');
387
+ for (var j = 0; j < classNames.length; j++) {
388
+ if (classNames[j] == className) {
389
+ elements.push(child);
390
+ break;
391
+ }
392
+ }
393
+ }
394
+
395
+ return elements;
396
+ }
397
+
398
+ /*--------------------------------------------------------------------------*/
399
+
400
+ if (!window.Element) {
401
+ var Element = new Object();
402
+ }
403
+
404
+ Object.extend(Element, {
405
+ toggle: function() {
406
+ for (var i = 0; i < arguments.length; i++) {
407
+ var element = $(arguments[i]);
408
+ element.style.display =
409
+ (element.style.display == 'none' ? '' : 'none');
410
+ }
411
+ },
412
+
413
+ hide: function() {
414
+ for (var i = 0; i < arguments.length; i++) {
415
+ var element = $(arguments[i]);
416
+ element.style.display = 'none';
417
+ }
418
+ },
419
+
420
+ show: function() {
421
+ for (var i = 0; i < arguments.length; i++) {
422
+ var element = $(arguments[i]);
423
+ element.style.display = '';
424
+ }
425
+ },
426
+
427
+ remove: function(element) {
428
+ element = $(element);
429
+ element.parentNode.removeChild(element);
430
+ },
431
+
432
+ getHeight: function(element) {
433
+ element = $(element);
434
+ return element.offsetHeight;
435
+ },
436
+
437
+ hasClassName: function(element, className) {
438
+ element = $(element);
439
+ if (!element)
440
+ return;
441
+ var a = element.className.split(' ');
442
+ for (var i = 0; i < a.length; i++) {
443
+ if (a[i] == className)
444
+ return true;
445
+ }
446
+ return false;
447
+ },
448
+
449
+ addClassName: function(element, className) {
450
+ element = $(element);
451
+ Element.removeClassName(element, className);
452
+ element.className += ' ' + className;
453
+ },
454
+
455
+ removeClassName: function(element, className) {
456
+ element = $(element);
457
+ if (!element)
458
+ return;
459
+ var newClassName = '';
460
+ var a = element.className.split(' ');
461
+ for (var i = 0; i < a.length; i++) {
462
+ if (a[i] != className) {
463
+ if (i > 0)
464
+ newClassName += ' ';
465
+ newClassName += a[i];
466
+ }
467
+ }
468
+ element.className = newClassName;
469
+ },
470
+
471
+ // removes whitespace-only text node children
472
+ cleanWhitespace: function(element) {
473
+ var element = $(element);
474
+ for (var i = 0; i < element.childNodes.length; i++) {
475
+ var node = element.childNodes[i];
476
+ if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
477
+ Element.remove(node);
478
+ }
479
+ }
480
+ });
481
+
482
+ var Toggle = new Object();
483
+ Toggle.display = Element.toggle;
484
+
485
+ /*--------------------------------------------------------------------------*/
486
+
487
+ Abstract.Insertion = function(adjacency) {
488
+ this.adjacency = adjacency;
489
+ }
490
+
491
+ Abstract.Insertion.prototype = {
492
+ initialize: function(element, content) {
493
+ this.element = $(element);
494
+ this.content = content;
495
+
496
+ if (this.adjacency && this.element.insertAdjacentHTML) {
497
+ this.element.insertAdjacentHTML(this.adjacency, this.content);
498
+ } else {
499
+ this.range = this.element.ownerDocument.createRange();
500
+ if (this.initializeRange) this.initializeRange();
501
+ this.fragment = this.range.createContextualFragment(this.content);
502
+ this.insertContent();
503
+ }
504
+ }
505
+ }
506
+
507
+ var Insertion = new Object();
508
+
509
+ Insertion.Before = Class.create();
510
+ Insertion.Before.prototype = (new Abstract.Insertion('beforeBegin')).extend({
511
+ initializeRange: function() {
512
+ this.range.setStartBefore(this.element);
513
+ },
514
+
515
+ insertContent: function() {
516
+ this.element.parentNode.insertBefore(this.fragment, this.element);
517
+ }
518
+ });
519
+
520
+ Insertion.Top = Class.create();
521
+ Insertion.Top.prototype = (new Abstract.Insertion('afterBegin')).extend({
522
+ initializeRange: function() {
523
+ this.range.selectNodeContents(this.element);
524
+ this.range.collapse(true);
525
+ },
526
+
527
+ insertContent: function() {
528
+ this.element.insertBefore(this.fragment, this.element.firstChild);
529
+ }
530
+ });
531
+
532
+ Insertion.Bottom = Class.create();
533
+ Insertion.Bottom.prototype = (new Abstract.Insertion('beforeEnd')).extend({
534
+ initializeRange: function() {
535
+ this.range.selectNodeContents(this.element);
536
+ this.range.collapse(this.element);
537
+ },
538
+
539
+ insertContent: function() {
540
+ this.element.appendChild(this.fragment);
541
+ }
542
+ });
543
+
544
+ Insertion.After = Class.create();
545
+ Insertion.After.prototype = (new Abstract.Insertion('afterEnd')).extend({
546
+ initializeRange: function() {
547
+ this.range.setStartAfter(this.element);
548
+ },
549
+
550
+ insertContent: function() {
551
+ this.element.parentNode.insertBefore(this.fragment,
552
+ this.element.nextSibling);
553
+ }
554
+ });
555
+
556
+ var Field = {
557
+ clear: function() {
558
+ for (var i = 0; i < arguments.length; i++)
559
+ $(arguments[i]).value = '';
560
+ },
561
+
562
+ focus: function(element) {
563
+ $(element).focus();
564
+ },
565
+
566
+ present: function() {
567
+ for (var i = 0; i < arguments.length; i++)
568
+ if ($(arguments[i]).value == '') return false;
569
+ return true;
570
+ },
571
+
572
+ select: function(element) {
573
+ $(element).select();
574
+ },
575
+
576
+ activate: function(element) {
577
+ $(element).focus();
578
+ $(element).select();
579
+ }
580
+ }
581
+
582
+ /*--------------------------------------------------------------------------*/
583
+
584
+ var Form = {
585
+ serialize: function(form) {
586
+ var elements = Form.getElements($(form));
587
+ var queryComponents = new Array();
588
+
589
+ for (var i = 0; i < elements.length; i++) {
590
+ var queryComponent = Form.Element.serialize(elements[i]);
591
+ if (queryComponent)
592
+ queryComponents.push(queryComponent);
593
+ }
594
+
595
+ return queryComponents.join('&');
596
+ },
597
+
598
+ getElements: function(form) {
599
+ var form = $(form);
600
+ var elements = new Array();
601
+
602
+ for (tagName in Form.Element.Serializers) {
603
+ var tagElements = form.getElementsByTagName(tagName);
604
+ for (var j = 0; j < tagElements.length; j++)
605
+ elements.push(tagElements[j]);
606
+ }
607
+ return elements;
608
+ },
609
+
610
+ getInputs: function(form, typeName, name) {
611
+ var form = $(form);
612
+ var inputs = form.getElementsByTagName('input');
613
+
614
+ if (!typeName && !name)
615
+ return inputs;
616
+
617
+ var matchingInputs = new Array();
618
+ for (var i = 0; i < inputs.length; i++) {
619
+ var input = inputs[i];
620
+ if ((typeName && input.type != typeName) ||
621
+ (name && input.name != name))
622
+ continue;
623
+ matchingInputs.push(input);
624
+ }
625
+
626
+ return matchingInputs;
627
+ },
628
+
629
+ disable: function(form) {
630
+ var elements = Form.getElements(form);
631
+ for (var i = 0; i < elements.length; i++) {
632
+ var element = elements[i];
633
+ element.blur();
634
+ element.disabled = 'true';
635
+ }
636
+ },
637
+
638
+ enable: function(form) {
639
+ var elements = Form.getElements(form);
640
+ for (var i = 0; i < elements.length; i++) {
641
+ var element = elements[i];
642
+ element.disabled = '';
643
+ }
644
+ },
645
+
646
+ focusFirstElement: function(form) {
647
+ var form = $(form);
648
+ var elements = Form.getElements(form);
649
+ for (var i = 0; i < elements.length; i++) {
650
+ var element = elements[i];
651
+ if (element.type != 'hidden' && !element.disabled) {
652
+ Field.activate(element);
653
+ break;
654
+ }
655
+ }
656
+ },
657
+
658
+ reset: function(form) {
659
+ $(form).reset();
660
+ }
661
+ }
662
+
663
+ Form.Element = {
664
+ serialize: function(element) {
665
+ var element = $(element);
666
+ var method = element.tagName.toLowerCase();
667
+ var parameter = Form.Element.Serializers[method](element);
668
+
669
+ if (parameter)
670
+ return encodeURIComponent(parameter[0]) + '=' +
671
+ encodeURIComponent(parameter[1]);
672
+ },
673
+
674
+ getValue: function(element) {
675
+ var element = $(element);
676
+ var method = element.tagName.toLowerCase();
677
+ var parameter = Form.Element.Serializers[method](element);
678
+
679
+ if (parameter)
680
+ return parameter[1];
681
+ }
682
+ }
683
+
684
+ Form.Element.Serializers = {
685
+ input: function(element) {
686
+ switch (element.type.toLowerCase()) {
687
+ case 'submit':
688
+ case 'hidden':
689
+ case 'password':
690
+ case 'text':
691
+ return Form.Element.Serializers.textarea(element);
692
+ case 'checkbox':
693
+ case 'radio':
694
+ return Form.Element.Serializers.inputSelector(element);
695
+ }
696
+ return false;
697
+ },
698
+
699
+ inputSelector: function(element) {
700
+ if (element.checked)
701
+ return [element.name, element.value];
702
+ },
703
+
704
+ textarea: function(element) {
705
+ return [element.name, element.value];
706
+ },
707
+
708
+ select: function(element) {
709
+ var value = '';
710
+ if (element.type == 'select-one') {
711
+ var index = element.selectedIndex;
712
+ if (index >= 0)
713
+ value = element.options[index].value || element.options[index].text;
714
+ } else {
715
+ value = new Array();
716
+ for (var i = 0; i < element.length; i++) {
717
+ var opt = element.options[i];
718
+ if (opt.selected)
719
+ value.push(opt.value || opt.text);
720
+ }
721
+ }
722
+ return [element.name, value];
723
+ }
724
+ }
725
+
726
+ /*--------------------------------------------------------------------------*/
727
+
728
+ var $F = Form.Element.getValue;
729
+
730
+ /*--------------------------------------------------------------------------*/
731
+
732
+ Abstract.TimedObserver = function() {}
733
+ Abstract.TimedObserver.prototype = {
734
+ initialize: function(element, frequency, callback) {
735
+ this.frequency = frequency;
736
+ this.element = $(element);
737
+ this.callback = callback;
738
+
739
+ this.lastValue = this.getValue();
740
+ this.registerCallback();
741
+ },
742
+
743
+ registerCallback: function() {
744
+ setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
745
+ },
746
+
747
+ onTimerEvent: function() {
748
+ var value = this.getValue();
749
+ if (this.lastValue != value) {
750
+ this.callback(this.element, value);
751
+ this.lastValue = value;
752
+ }
753
+ }
754
+ }
755
+
756
+ Form.Element.Observer = Class.create();
757
+ Form.Element.Observer.prototype = (new Abstract.TimedObserver()).extend({
758
+ getValue: function() {
759
+ return Form.Element.getValue(this.element);
760
+ }
761
+ });
762
+
763
+ Form.Observer = Class.create();
764
+ Form.Observer.prototype = (new Abstract.TimedObserver()).extend({
765
+ getValue: function() {
766
+ return Form.serialize(this.element);
767
+ }
768
+ });
769
+
770
+ /*--------------------------------------------------------------------------*/
771
+
772
+ Abstract.EventObserver = function() {}
773
+ Abstract.EventObserver.prototype = {
774
+ initialize: function(element, callback) {
775
+ this.element = $(element);
776
+ this.callback = callback;
777
+
778
+ this.lastValue = this.getValue();
779
+ if (this.element.tagName.toLowerCase() == 'form')
780
+ this.registerFormCallbacks();
781
+ else
782
+ this.registerCallback(this.element);
783
+ },
784
+
785
+ onElementEvent: function() {
786
+ var value = this.getValue();
787
+ if (this.lastValue != value) {
788
+ this.callback(this.element, value);
789
+ this.lastValue = value;
790
+ }
791
+ },
792
+
793
+ registerFormCallbacks: function() {
794
+ var elements = Form.getElements(this.element);
795
+ for (var i = 0; i < elements.length; i++)
796
+ this.registerCallback(elements[i]);
797
+ },
798
+
799
+ registerCallback: function(element) {
800
+ if (element.type) {
801
+ switch (element.type.toLowerCase()) {
802
+ case 'checkbox':
803
+ case 'radio':
804
+ element.target = this;
805
+ element.prev_onclick = element.onclick || Prototype.emptyFunction;
806
+ element.onclick = function() {
807
+ this.prev_onclick();
808
+ this.target.onElementEvent();
809
+ }
810
+ break;
811
+ case 'password':
812
+ case 'text':
813
+ case 'textarea':
814
+ case 'select-one':
815
+ case 'select-multiple':
816
+ element.target = this;
817
+ element.prev_onchange = element.onchange || Prototype.emptyFunction;
818
+ element.onchange = function() {
819
+ this.prev_onchange();
820
+ this.target.onElementEvent();
821
+ }
822
+ break;
823
+ }
824
+ }
825
+ }
826
+ }
827
+
828
+ Form.Element.EventObserver = Class.create();
829
+ Form.Element.EventObserver.prototype = (new Abstract.EventObserver()).extend({
830
+ getValue: function() {
831
+ return Form.Element.getValue(this.element);
832
+ }
833
+ });
834
+
835
+ Form.EventObserver = Class.create();
836
+ Form.EventObserver.prototype = (new Abstract.EventObserver()).extend({
837
+ getValue: function() {
838
+ return Form.serialize(this.element);
839
+ }
840
+ });
841
+
842
+
843
+ if (!window.Event) {
844
+ var Event = new Object();
845
+ }
846
+
847
+ Object.extend(Event, {
848
+ KEY_BACKSPACE: 8,
849
+ KEY_TAB: 9,
850
+ KEY_RETURN: 13,
851
+ KEY_ESC: 27,
852
+ KEY_LEFT: 37,
853
+ KEY_UP: 38,
854
+ KEY_RIGHT: 39,
855
+ KEY_DOWN: 40,
856
+ KEY_DELETE: 46,
857
+
858
+ element: function(event) {
859
+ return event.target || event.srcElement;
860
+ },
861
+
862
+ isLeftClick: function(event) {
863
+ return (((event.which) && (event.which == 1)) ||
864
+ ((event.button) && (event.button == 1)));
865
+ },
866
+
867
+ pointerX: function(event) {
868
+ return event.pageX || (event.clientX +
869
+ (document.documentElement.scrollLeft || document.body.scrollLeft));
870
+ },
871
+
872
+ pointerY: function(event) {
873
+ return event.pageY || (event.clientY +
874
+ (document.documentElement.scrollTop || document.body.scrollTop));
875
+ },
876
+
877
+ stop: function(event) {
878
+ if (event.preventDefault) {
879
+ event.preventDefault();
880
+ event.stopPropagation();
881
+ } else {
882
+ event.returnValue = false;
883
+ }
884
+ },
885
+
886
+ // find the first node with the given tagName, starting from the
887
+ // node the event was triggered on; traverses the DOM upwards
888
+ findElement: function(event, tagName) {
889
+ var element = Event.element(event);
890
+ while (element.parentNode && (!element.tagName ||
891
+ (element.tagName.toUpperCase() != tagName.toUpperCase())))
892
+ element = element.parentNode;
893
+ return element;
894
+ },
895
+
896
+ observers: false,
897
+
898
+ _observeAndCache: function(element, name, observer, useCapture) {
899
+ if (!this.observers) this.observers = [];
900
+ if (element.addEventListener) {
901
+ this.observers.push([element, name, observer, useCapture]);
902
+ element.addEventListener(name, observer, useCapture);
903
+ } else if (element.attachEvent) {
904
+ this.observers.push([element, name, observer, useCapture]);
905
+ element.attachEvent('on' + name, observer);
906
+ }
907
+ },
908
+
909
+ unloadCache: function() {
910
+ if (!Event.observers) return;
911
+ for (var i = 0; i < Event.observers.length; i++) {
912
+ Event.stopObserving.apply(this, Event.observers[i]);
913
+ Event.observers[i][0] = null;
914
+ }
915
+ Event.observers = false;
916
+ },
917
+
918
+ observe: function(element, name, observer, useCapture) {
919
+ var element = $(element);
920
+ useCapture = useCapture || false;
921
+
922
+ if (name == 'keypress' &&
923
+ ((navigator.appVersion.indexOf('AppleWebKit') > 0)
924
+ || element.attachEvent))
925
+ name = 'keydown';
926
+
927
+ this._observeAndCache(element, name, observer, useCapture);
928
+ },
929
+
930
+ stopObserving: function(element, name, observer, useCapture) {
931
+ var element = $(element);
932
+ useCapture = useCapture || false;
933
+
934
+ if (name == 'keypress' &&
935
+ ((navigator.appVersion.indexOf('AppleWebKit') > 0)
936
+ || element.detachEvent))
937
+ name = 'keydown';
938
+
939
+ if (element.removeEventListener) {
940
+ element.removeEventListener(name, observer, useCapture);
941
+ } else if (element.detachEvent) {
942
+ element.detachEvent('on' + name, observer);
943
+ }
944
+ }
945
+ });
946
+
947
+ /* prevent memory leaks in IE */
948
+ Event.observe(window, 'unload', Event.unloadCache, false);
949
+
950
+ var Position = {
951
+
952
+ // set to true if needed, warning: firefox performance problems
953
+ // NOT neeeded for page scrolling, only if draggable contained in
954
+ // scrollable elements
955
+ includeScrollOffsets: false,
956
+
957
+ // must be called before calling withinIncludingScrolloffset, every time the
958
+ // page is scrolled
959
+ prepare: function() {
960
+ this.deltaX = window.pageXOffset
961
+ || document.documentElement.scrollLeft
962
+ || document.body.scrollLeft
963
+ || 0;
964
+ this.deltaY = window.pageYOffset
965
+ || document.documentElement.scrollTop
966
+ || document.body.scrollTop
967
+ || 0;
968
+ },
969
+
970
+ realOffset: function(element) {
971
+ var valueT = 0, valueL = 0;
972
+ do {
973
+ valueT += element.scrollTop || 0;
974
+ valueL += element.scrollLeft || 0;
975
+ element = element.parentNode;
976
+ } while (element);
977
+ return [valueL, valueT];
978
+ },
979
+
980
+ cumulativeOffset: function(element) {
981
+ var valueT = 0, valueL = 0;
982
+ do {
983
+ valueT += element.offsetTop || 0;
984
+ valueL += element.offsetLeft || 0;
985
+ element = element.offsetParent;
986
+ } while (element);
987
+ return [valueL, valueT];
988
+ },
989
+
990
+ // caches x/y coordinate pair to use with overlap
991
+ within: function(element, x, y) {
992
+ if (this.includeScrollOffsets)
993
+ return this.withinIncludingScrolloffsets(element, x, y);
994
+ this.xcomp = x;
995
+ this.ycomp = y;
996
+ this.offset = this.cumulativeOffset(element);
997
+
998
+ return (y >= this.offset[1] &&
999
+ y < this.offset[1] + element.offsetHeight &&
1000
+ x >= this.offset[0] &&
1001
+ x < this.offset[0] + element.offsetWidth);
1002
+ },
1003
+
1004
+ withinIncludingScrolloffsets: function(element, x, y) {
1005
+ var offsetcache = this.realOffset(element);
1006
+
1007
+ this.xcomp = x + offsetcache[0] - this.deltaX;
1008
+ this.ycomp = y + offsetcache[1] - this.deltaY;
1009
+ this.offset = this.cumulativeOffset(element);
1010
+
1011
+ return (this.ycomp >= this.offset[1] &&
1012
+ this.ycomp < this.offset[1] + element.offsetHeight &&
1013
+ this.xcomp >= this.offset[0] &&
1014
+ this.xcomp < this.offset[0] + element.offsetWidth);
1015
+ },
1016
+
1017
+ // within must be called directly before
1018
+ overlap: function(mode, element) {
1019
+ if (!mode) return 0;
1020
+ if (mode == 'vertical')
1021
+ return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
1022
+ element.offsetHeight;
1023
+ if (mode == 'horizontal')
1024
+ return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
1025
+ element.offsetWidth;
1026
+ },
1027
+
1028
+ clone: function(source, target) {
1029
+ source = $(source);
1030
+ target = $(target);
1031
+ target.style.position = 'absolute';
1032
+ var offsets = this.cumulativeOffset(source);
1033
+ target.style.top = offsets[1] + 'px';
1034
+ target.style.left = offsets[0] + 'px';
1035
+ target.style.width = source.offsetWidth + 'px';
1036
+ target.style.height = source.offsetHeight + 'px';
1037
+ }
1038
+ }