hobix 0.4 → 0.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (129) hide show
  1. data/COPYING +18 -0
  2. data/README +18 -0
  3. data/Rakefile +96 -0
  4. data/bin/hobix +7 -3
  5. data/contrib/blosxom-to-hobix.rb +253 -0
  6. data/contrib/txp-to-hobix.rb +56 -0
  7. data/contrib/webrick-all-mine.rb +20 -0
  8. data/doc/CHANGELOG +285 -0
  9. data/doc/rdoc/classes/Hobix/API.html +382 -0
  10. data/doc/rdoc/classes/Hobix/Article.html +111 -0
  11. data/doc/rdoc/classes/Hobix/BaseContent.html +692 -0
  12. data/doc/rdoc/classes/Hobix/BaseEntry.html +218 -0
  13. data/doc/rdoc/classes/Hobix/BaseFacet.html +205 -0
  14. data/doc/rdoc/classes/Hobix/BaseOutput.html +122 -0
  15. data/doc/rdoc/classes/Hobix/BasePlugin.html +201 -0
  16. data/doc/rdoc/classes/Hobix/BaseProperties/ClassMethods.html +243 -0
  17. data/doc/rdoc/classes/Hobix/BaseProperties.html +218 -0
  18. data/doc/rdoc/classes/Hobix/BasePublish.html +157 -0
  19. data/doc/rdoc/classes/Hobix/BaseStorage.html +417 -0
  20. data/doc/rdoc/classes/Hobix/BixWik/Entry.html +196 -0
  21. data/doc/rdoc/classes/Hobix/BixWik/IndexEntry.html +170 -0
  22. data/doc/rdoc/classes/Hobix/BixWik/WikiRedCloth.html +111 -0
  23. data/doc/rdoc/classes/Hobix/BixWik.html +418 -0
  24. data/doc/rdoc/classes/Hobix/BixWikPlugin.html +158 -0
  25. data/doc/rdoc/classes/Hobix/CommandLine.html +1970 -0
  26. data/doc/rdoc/classes/Hobix/Comment.html +113 -0
  27. data/doc/rdoc/classes/Hobix/Config.html +212 -0
  28. data/doc/rdoc/classes/Hobix/DataMarsh.html +667 -0
  29. data/doc/rdoc/classes/Hobix/Entry.html +178 -0
  30. data/doc/rdoc/classes/Hobix/EntryEnum.html +162 -0
  31. data/doc/rdoc/classes/Hobix/Enumerable.html +170 -0
  32. data/doc/rdoc/classes/Hobix/Facets/WikiEdit.html +180 -0
  33. data/doc/rdoc/classes/Hobix/Facets.html +111 -0
  34. data/doc/rdoc/classes/Hobix/LinkList.html +182 -0
  35. data/doc/rdoc/classes/Hobix/Out/Quick.html +412 -0
  36. data/doc/rdoc/classes/Hobix/Out.html +119 -0
  37. data/doc/rdoc/classes/Hobix/Page.html +381 -0
  38. data/doc/rdoc/classes/Hobix/Trackback.html +113 -0
  39. data/doc/rdoc/classes/Hobix/UriStr.html +198 -0
  40. data/doc/rdoc/classes/Hobix/WebApp/QueryString.html +207 -0
  41. data/doc/rdoc/classes/Hobix/WebApp/QueryValidationFailure.html +111 -0
  42. data/doc/rdoc/classes/Hobix/WebApp.html +1383 -0
  43. data/doc/rdoc/classes/Hobix/Weblog/AuthorNotFound.html +111 -0
  44. data/doc/rdoc/classes/Hobix/Weblog.html +2082 -0
  45. data/doc/rdoc/classes/Hobix.html +399 -0
  46. data/doc/rdoc/classes/Kernel.html +139 -0
  47. data/doc/rdoc/classes/Regexp.html +154 -0
  48. data/doc/rdoc/classes/YAML/Omap.html +144 -0
  49. data/doc/rdoc/classes/YAML.html +111 -0
  50. data/doc/rdoc/created.rid +1 -0
  51. data/doc/rdoc/files/COPYING.html +129 -0
  52. data/doc/rdoc/files/README.html +131 -0
  53. data/doc/rdoc/files/doc/CHANGELOG.html +101 -0
  54. data/doc/rdoc/files/lib/hobix/api_rb.html +119 -0
  55. data/doc/rdoc/files/lib/hobix/article_rb.html +126 -0
  56. data/doc/rdoc/files/lib/hobix/base_rb.html +128 -0
  57. data/doc/rdoc/files/lib/hobix/bixwik_rb.html +126 -0
  58. data/doc/rdoc/files/lib/hobix/commandline_rb.html +140 -0
  59. data/doc/rdoc/files/lib/hobix/comments_rb.html +126 -0
  60. data/doc/rdoc/files/lib/hobix/config_rb.html +125 -0
  61. data/doc/rdoc/files/lib/hobix/datamarsh_rb.html +108 -0
  62. data/doc/rdoc/files/lib/hobix/entry_rb.html +118 -0
  63. data/doc/rdoc/files/lib/hobix/linklist_rb.html +127 -0
  64. data/doc/rdoc/files/lib/hobix/publisher_rb.html +126 -0
  65. data/doc/rdoc/files/lib/hobix/trackbacks_rb.html +128 -0
  66. data/doc/rdoc/files/lib/hobix/webapp_rb.html +127 -0
  67. data/doc/rdoc/files/lib/hobix/weblog_rb.html +135 -0
  68. data/doc/rdoc/files/lib/hobix_rb.html +127 -0
  69. data/doc/rdoc/fr_class_index.html +67 -0
  70. data/doc/rdoc/fr_file_index.html +44 -0
  71. data/doc/rdoc/fr_method_index.html +307 -0
  72. data/doc/rdoc/index.html +24 -0
  73. data/doc/rdoc/rdoc-style.css +208 -0
  74. data/git_hobix_update.php +13 -0
  75. data/lib/hobix/base.rb +6 -3
  76. data/lib/hobix/bixwik.rb +12 -12
  77. data/lib/hobix/commandline.rb +18 -2
  78. data/lib/hobix/comments.rb +4 -5
  79. data/lib/hobix/entry.rb +2 -1
  80. data/lib/hobix/facets/comments.rb +31 -6
  81. data/lib/hobix/linklist.rb +6 -1
  82. data/lib/hobix/out/atom.rb +29 -20
  83. data/lib/hobix/out/quick.rb +8 -6
  84. data/lib/hobix/out/rss.rb +16 -3
  85. data/lib/hobix/plugin/akismet.rb +196 -0
  86. data/lib/hobix/plugin/calendar.rb +6 -14
  87. data/lib/hobix/plugin/recent_comments.rb +4 -2
  88. data/lib/hobix/plugin/tags.rb +1 -1
  89. data/lib/hobix/storage/filesys.rb +41 -31
  90. data/lib/hobix/trackbacks.rb +1 -2
  91. data/lib/hobix/weblog.rb +73 -40
  92. data/lib/hobix.rb +9 -2
  93. data/share/default-blog/hobix.yaml +16 -0
  94. data/share/default-blog/htdocs/site.css +174 -0
  95. data/share/default-blog/skel/entry.html.quick +0 -0
  96. data/share/default-blog/skel/index.atom.atom +0 -0
  97. data/share/default-blog/skel/index.html.quick-summary +0 -0
  98. data/share/default-blog/skel/index.xml.rss +0 -0
  99. data/share/default-blog/skel/index.yaml.okaynews +0 -0
  100. data/share/default-blog/skel/monthly.html.quick-archive +0 -0
  101. data/share/default-blog/skel/section.html.quick-archive +0 -0
  102. data/share/default-blog/skel/yearly.html.quick-archive +0 -0
  103. data/share/default-blog-modes.yaml +7 -0
  104. data/share/default-blog.apache-cgi.patch +8 -0
  105. data/share/default-blog.apache-ssi.patch +38 -0
  106. data/share/default-blog.apache2-ssi.patch +3 -0
  107. data/share/default-blog.cgi.patch +8 -0
  108. data/share/default-blog.comments.patch +5 -0
  109. data/share/default-blog.prototype.patch +766 -0
  110. data/share/default-blog.publisher.patch +5 -0
  111. data/share/default-blog.wiki.patch +29 -0
  112. data/share/publisher/css/control.css +90 -0
  113. data/share/publisher/css/form.css +238 -0
  114. data/share/publisher/css/form.import.css +72 -0
  115. data/share/publisher/css/main-menu.css +134 -0
  116. data/share/publisher/i/hobix-emblazen-1.png +0 -0
  117. data/share/publisher/i/hobix-emblazen-2.png +0 -0
  118. data/share/publisher/i/hobix-emblazen-3.png +0 -0
  119. data/share/publisher/i/hobix-emblazen-4.png +0 -0
  120. data/share/publisher/i/hobix-emblazen-5.png +0 -0
  121. data/share/publisher/i/hobix-emblazen-6.png +0 -0
  122. data/share/publisher/i/hobix-emblazen-7.png +0 -0
  123. data/share/publisher/index.erb +66 -0
  124. data/share/publisher/js/controls.js +261 -0
  125. data/share/publisher/js/dragdrop.js +476 -0
  126. data/share/publisher/js/effects.js +570 -0
  127. data/share/publisher/js/prototype.js +1011 -0
  128. metadata +196 -53
  129. checksums.yaml +0 -7
@@ -0,0 +1,1011 @@
1
+ /* Prototype JavaScript framework, version 1.3.0
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.0',
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] = 'x[' + 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
+
190
+ Ajax.Request = Class.create();
191
+ Ajax.Request.Events =
192
+ ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
193
+
194
+ Ajax.Request.prototype = (new Ajax.Base()).extend({
195
+ initialize: function(url, options) {
196
+ this.transport = Ajax.getTransport();
197
+ this.setOptions(options);
198
+
199
+ var parameters = this.options.parameters || '';
200
+ if (parameters.length > 0) parameters += '&_=';
201
+
202
+ try {
203
+ if (this.options.method == 'get')
204
+ url += '?' + parameters;
205
+
206
+ this.transport.open(this.options.method, url,
207
+ this.options.asynchronous);
208
+
209
+ if (this.options.asynchronous) {
210
+ this.transport.onreadystatechange = this.onStateChange.bind(this);
211
+ setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
212
+ }
213
+
214
+ this.setRequestHeaders();
215
+
216
+ var body = this.options.postBody ? this.options.postBody : parameters;
217
+ this.transport.send(this.options.method == 'post' ? body : null);
218
+
219
+ } catch (e) {
220
+ }
221
+ },
222
+
223
+ setRequestHeaders: function() {
224
+ var requestHeaders = [
225
+ 'X-Requested-With', 'XMLHttpRequest',
226
+ 'X-Prototype-Version', Prototype.Version];
227
+
228
+ if (this.options.method == 'post') {
229
+ requestHeaders.push(
230
+ 'Content-type', 'application/x-www-form-urlencoded');
231
+ if(navigator.userAgent.indexOf('Gecko')>0)
232
+ requestHeaders.push(
233
+ 'Connection', 'close');
234
+ }
235
+
236
+ if (this.options.requestHeaders)
237
+ requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
238
+
239
+ for (var i = 0; i < requestHeaders.length; i += 2)
240
+ this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
241
+ },
242
+
243
+ onStateChange: function() {
244
+ var readyState = this.transport.readyState;
245
+ if (readyState != 1)
246
+ this.respondToReadyState(this.transport.readyState);
247
+ },
248
+
249
+ respondToReadyState: function(readyState) {
250
+ var event = Ajax.Request.Events[readyState];
251
+
252
+ if (event == 'Complete' && this.transport.status != 200)
253
+ (this.options['on' + this.transport.status]
254
+ || this.options.onFailure
255
+ || Prototype.emptyFunction)(this.transport);
256
+
257
+ (this.options['on' + event] || Prototype.emptyFunction)(this.transport);
258
+ }
259
+ });
260
+
261
+ Ajax.Updater = Class.create();
262
+ Ajax.Updater.ScriptFragmentMatch = /<script.*?>((?:\n|.)*?)<\/script>/img;
263
+
264
+ Ajax.Updater.prototype = (new Ajax.Base()).extend({
265
+ initialize: function(container, url, options) {
266
+ this.containers = {
267
+ success: container.success ? $(container.success) : $(container),
268
+ failure: container.failure ? $(container.failure) : $(container)
269
+ }
270
+
271
+ this.setOptions(options);
272
+
273
+ if (this.options.asynchronous) {
274
+ this.onComplete = this.options.onComplete;
275
+ this.options.onComplete = this.updateContent.bind(this);
276
+ }
277
+
278
+ this.request = new Ajax.Request(url, this.options);
279
+
280
+ if (!this.options.asynchronous)
281
+ this.updateContent();
282
+ },
283
+
284
+ updateContent: function() {
285
+ var receiver =
286
+ (this.request.transport.status == 200) ?
287
+ this.containers.success : this.containers.failure;
288
+
289
+ var response = this.request.transport.responseText.
290
+ replace(Ajax.Updater.ScriptFragmentMatch, '');
291
+
292
+ var scripts = this.request.transport.responseText.
293
+ match(Ajax.Updater.ScriptFragmentMatch);
294
+
295
+ if (receiver) {
296
+ if (this.options.insertion) {
297
+ new this.options.insertion(receiver, response);
298
+ } else {
299
+ receiver.innerHTML = response;
300
+ }
301
+ }
302
+
303
+ if (this.request.transport.status == 200)
304
+ if (this.onComplete)
305
+ setTimeout((function() {this.onComplete(
306
+ this.request.transport)}).bind(this), 10);
307
+
308
+ if (this.options.evalScripts && scripts)
309
+ setTimeout( (function() {
310
+ for(var i=0;i<scripts.length;i++)
311
+ eval(scripts[i].replace(/^<script.*?>/,'').replace(/<\/script>$/,''));
312
+ } ).bind(this), 10);
313
+
314
+ }
315
+ });
316
+
317
+ Ajax.PeriodicalUpdater = Class.create();
318
+ Ajax.PeriodicalUpdater.prototype = (new Ajax.Base()).extend({
319
+ initialize: function(container, url, options) {
320
+ this.setOptions(options);
321
+ this.onComplete = this.options.onComplete;
322
+
323
+ this.frequency = (this.options.frequency || 2);
324
+ this.decay = 1;
325
+
326
+ this.updater = {};
327
+ this.container = container;
328
+ this.url = url;
329
+
330
+ this.start();
331
+ },
332
+
333
+ start: function() {
334
+ this.options.onComplete = this.updateComplete.bind(this);
335
+ this.onTimerEvent();
336
+ },
337
+
338
+ stop: function() {
339
+ this.updater.onComplete = undefined;
340
+ clearTimeout(this.timer);
341
+ (this.onComplete || Ajax.emptyFunction).apply(this, arguments);
342
+ },
343
+
344
+ updateComplete: function(request) {
345
+ if (this.options.decay) {
346
+ this.decay = (request.responseText == this.lastText ?
347
+ this.decay * this.options.decay : 1);
348
+
349
+ this.lastText = request.responseText;
350
+ }
351
+ this.timer = setTimeout(this.onTimerEvent.bind(this),
352
+ this.decay * this.frequency * 1000);
353
+ },
354
+
355
+ onTimerEvent: function() {
356
+ this.updater = new Ajax.Updater(this.container, this.url, this.options);
357
+ }
358
+ });
359
+
360
+ document.getElementsByClassName = function(className) {
361
+ var children = document.getElementsByTagName('*') || document.all;
362
+ var elements = new Array();
363
+
364
+ for (var i = 0; i < children.length; i++) {
365
+ var child = children[i];
366
+ var classNames = child.className.split(' ');
367
+ for (var j = 0; j < classNames.length; j++) {
368
+ if (classNames[j] == className) {
369
+ elements.push(child);
370
+ break;
371
+ }
372
+ }
373
+ }
374
+
375
+ return elements;
376
+ }
377
+
378
+ /*--------------------------------------------------------------------------*/
379
+
380
+ if (!window.Element) {
381
+ var Element = new Object();
382
+ }
383
+
384
+ Object.extend(Element, {
385
+ toggle: function() {
386
+ for (var i = 0; i < arguments.length; i++) {
387
+ var element = $(arguments[i]);
388
+ element.style.display =
389
+ (element.style.display == 'none' ? '' : 'none');
390
+ }
391
+ },
392
+
393
+ hide: function() {
394
+ for (var i = 0; i < arguments.length; i++) {
395
+ var element = $(arguments[i]);
396
+ element.style.display = 'none';
397
+ }
398
+ },
399
+
400
+ show: function() {
401
+ for (var i = 0; i < arguments.length; i++) {
402
+ var element = $(arguments[i]);
403
+ element.style.display = '';
404
+ }
405
+ },
406
+
407
+ remove: function(element) {
408
+ element = $(element);
409
+ element.parentNode.removeChild(element);
410
+ },
411
+
412
+ getHeight: function(element) {
413
+ element = $(element);
414
+ return element.offsetHeight;
415
+ },
416
+
417
+ hasClassName: function(element, className) {
418
+ element = $(element);
419
+ if (!element)
420
+ return;
421
+ var a = element.className.split(' ');
422
+ for (var i = 0; i < a.length; i++) {
423
+ if (a[i] == className)
424
+ return true;
425
+ }
426
+ return false;
427
+ },
428
+
429
+ addClassName: function(element, className) {
430
+ element = $(element);
431
+ Element.removeClassName(element, className);
432
+ element.className += ' ' + className;
433
+ },
434
+
435
+ removeClassName: function(element, className) {
436
+ element = $(element);
437
+ if (!element)
438
+ return;
439
+ var newClassName = '';
440
+ var a = element.className.split(' ');
441
+ for (var i = 0; i < a.length; i++) {
442
+ if (a[i] != className) {
443
+ if (i > 0)
444
+ newClassName += ' ';
445
+ newClassName += a[i];
446
+ }
447
+ }
448
+ element.className = newClassName;
449
+ },
450
+
451
+ // removes whitespace-only text node children
452
+ cleanWhitespace: function(element) {
453
+ var element = $(element);
454
+ for (var i = 0; i < element.childNodes.length; i++) {
455
+ var node = element.childNodes[i];
456
+ if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
457
+ Element.remove(node);
458
+ }
459
+ }
460
+ });
461
+
462
+ var Toggle = new Object();
463
+ Toggle.display = Element.toggle;
464
+
465
+ /*--------------------------------------------------------------------------*/
466
+
467
+ Abstract.Insertion = function(adjacency) {
468
+ this.adjacency = adjacency;
469
+ }
470
+
471
+ Abstract.Insertion.prototype = {
472
+ initialize: function(element, content) {
473
+ this.element = $(element);
474
+ this.content = content;
475
+
476
+ if (this.adjacency && this.element.insertAdjacentHTML) {
477
+ this.element.insertAdjacentHTML(this.adjacency, this.content);
478
+ } else {
479
+ this.range = this.element.ownerDocument.createRange();
480
+ if (this.initializeRange) this.initializeRange();
481
+ this.fragment = this.range.createContextualFragment(this.content);
482
+ this.insertContent();
483
+ }
484
+ }
485
+ }
486
+
487
+ var Insertion = new Object();
488
+
489
+ Insertion.Before = Class.create();
490
+ Insertion.Before.prototype = (new Abstract.Insertion('beforeBegin')).extend({
491
+ initializeRange: function() {
492
+ this.range.setStartBefore(this.element);
493
+ },
494
+
495
+ insertContent: function() {
496
+ this.element.parentNode.insertBefore(this.fragment, this.element);
497
+ }
498
+ });
499
+
500
+ Insertion.Top = Class.create();
501
+ Insertion.Top.prototype = (new Abstract.Insertion('afterBegin')).extend({
502
+ initializeRange: function() {
503
+ this.range.selectNodeContents(this.element);
504
+ this.range.collapse(true);
505
+ },
506
+
507
+ insertContent: function() {
508
+ this.element.insertBefore(this.fragment, this.element.firstChild);
509
+ }
510
+ });
511
+
512
+ Insertion.Bottom = Class.create();
513
+ Insertion.Bottom.prototype = (new Abstract.Insertion('beforeEnd')).extend({
514
+ initializeRange: function() {
515
+ this.range.selectNodeContents(this.element);
516
+ this.range.collapse(this.element);
517
+ },
518
+
519
+ insertContent: function() {
520
+ this.element.appendChild(this.fragment);
521
+ }
522
+ });
523
+
524
+ Insertion.After = Class.create();
525
+ Insertion.After.prototype = (new Abstract.Insertion('afterEnd')).extend({
526
+ initializeRange: function() {
527
+ this.range.setStartAfter(this.element);
528
+ },
529
+
530
+ insertContent: function() {
531
+ this.element.parentNode.insertBefore(this.fragment,
532
+ this.element.nextSibling);
533
+ }
534
+ });
535
+
536
+ var Field = {
537
+ clear: function() {
538
+ for (var i = 0; i < arguments.length; i++)
539
+ $(arguments[i]).value = '';
540
+ },
541
+
542
+ focus: function(element) {
543
+ $(element).focus();
544
+ },
545
+
546
+ present: function() {
547
+ for (var i = 0; i < arguments.length; i++)
548
+ if ($(arguments[i]).value == '') return false;
549
+ return true;
550
+ },
551
+
552
+ select: function(element) {
553
+ $(element).select();
554
+ },
555
+
556
+ activate: function(element) {
557
+ $(element).focus();
558
+ $(element).select();
559
+ }
560
+ }
561
+
562
+ /*--------------------------------------------------------------------------*/
563
+
564
+ var Form = {
565
+ serialize: function(form) {
566
+ var elements = Form.getElements($(form));
567
+ var queryComponents = new Array();
568
+
569
+ for (var i = 0; i < elements.length; i++) {
570
+ var queryComponent = Form.Element.serialize(elements[i]);
571
+ if (queryComponent)
572
+ queryComponents.push(queryComponent);
573
+ }
574
+
575
+ return queryComponents.join('&');
576
+ },
577
+
578
+ getElements: function(form) {
579
+ var form = $(form);
580
+ var elements = new Array();
581
+
582
+ for (tagName in Form.Element.Serializers) {
583
+ var tagElements = form.getElementsByTagName(tagName);
584
+ for (var j = 0; j < tagElements.length; j++)
585
+ elements.push(tagElements[j]);
586
+ }
587
+ return elements;
588
+ },
589
+
590
+ getInputs: function(form, typeName, name) {
591
+ var form = $(form);
592
+ var inputs = form.getElementsByTagName('input');
593
+
594
+ if (!typeName && !name)
595
+ return inputs;
596
+
597
+ var matchingInputs = new Array();
598
+ for (var i = 0; i < inputs.length; i++) {
599
+ var input = inputs[i];
600
+ if ((typeName && input.type != typeName) ||
601
+ (name && input.name != name))
602
+ continue;
603
+ matchingInputs.push(input);
604
+ }
605
+
606
+ return matchingInputs;
607
+ },
608
+
609
+ disable: function(form) {
610
+ var elements = Form.getElements(form);
611
+ for (var i = 0; i < elements.length; i++) {
612
+ var element = elements[i];
613
+ element.blur();
614
+ element.disabled = 'true';
615
+ }
616
+ },
617
+
618
+ enable: function(form) {
619
+ var elements = Form.getElements(form);
620
+ for (var i = 0; i < elements.length; i++) {
621
+ var element = elements[i];
622
+ element.disabled = '';
623
+ }
624
+ },
625
+
626
+ focusFirstElement: function(form) {
627
+ var form = $(form);
628
+ var elements = Form.getElements(form);
629
+ for (var i = 0; i < elements.length; i++) {
630
+ var element = elements[i];
631
+ if (element.type != 'hidden' && !element.disabled) {
632
+ Field.activate(element);
633
+ break;
634
+ }
635
+ }
636
+ },
637
+
638
+ reset: function(form) {
639
+ $(form).reset();
640
+ }
641
+ }
642
+
643
+ Form.Element = {
644
+ serialize: function(element) {
645
+ var element = $(element);
646
+ var method = element.tagName.toLowerCase();
647
+ var parameter = Form.Element.Serializers[method](element);
648
+
649
+ if (parameter)
650
+ return encodeURIComponent(parameter[0]) + '=' +
651
+ encodeURIComponent(parameter[1]);
652
+ },
653
+
654
+ getValue: function(element) {
655
+ var element = $(element);
656
+ var method = element.tagName.toLowerCase();
657
+ var parameter = Form.Element.Serializers[method](element);
658
+
659
+ if (parameter)
660
+ return parameter[1];
661
+ }
662
+ }
663
+
664
+ Form.Element.Serializers = {
665
+ input: function(element) {
666
+ switch (element.type.toLowerCase()) {
667
+ case 'submit':
668
+ case 'hidden':
669
+ case 'password':
670
+ case 'text':
671
+ return Form.Element.Serializers.textarea(element);
672
+ case 'checkbox':
673
+ case 'radio':
674
+ return Form.Element.Serializers.inputSelector(element);
675
+ }
676
+ return false;
677
+ },
678
+
679
+ inputSelector: function(element) {
680
+ if (element.checked)
681
+ return [element.name, element.value];
682
+ },
683
+
684
+ textarea: function(element) {
685
+ return [element.name, element.value];
686
+ },
687
+
688
+ select: function(element) {
689
+ var value = '';
690
+ if (element.type == 'select-one') {
691
+ var index = element.selectedIndex;
692
+ if (index >= 0)
693
+ value = element.options[index].value || element.options[index].text;
694
+ } else {
695
+ value = new Array();
696
+ for (var i = 0; i < element.length; i++) {
697
+ var opt = element.options[i];
698
+ if (opt.selected)
699
+ value.push(opt.value || opt.text);
700
+ }
701
+ }
702
+ return [element.name, value];
703
+ }
704
+ }
705
+
706
+ /*--------------------------------------------------------------------------*/
707
+
708
+ var $F = Form.Element.getValue;
709
+
710
+ /*--------------------------------------------------------------------------*/
711
+
712
+ Abstract.TimedObserver = function() {}
713
+ Abstract.TimedObserver.prototype = {
714
+ initialize: function(element, frequency, callback) {
715
+ this.frequency = frequency;
716
+ this.element = $(element);
717
+ this.callback = callback;
718
+
719
+ this.lastValue = this.getValue();
720
+ this.registerCallback();
721
+ },
722
+
723
+ registerCallback: function() {
724
+ setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
725
+ },
726
+
727
+ onTimerEvent: function() {
728
+ var value = this.getValue();
729
+ if (this.lastValue != value) {
730
+ this.callback(this.element, value);
731
+ this.lastValue = value;
732
+ }
733
+ }
734
+ }
735
+
736
+ Form.Element.Observer = Class.create();
737
+ Form.Element.Observer.prototype = (new Abstract.TimedObserver()).extend({
738
+ getValue: function() {
739
+ return Form.Element.getValue(this.element);
740
+ }
741
+ });
742
+
743
+ Form.Observer = Class.create();
744
+ Form.Observer.prototype = (new Abstract.TimedObserver()).extend({
745
+ getValue: function() {
746
+ return Form.serialize(this.element);
747
+ }
748
+ });
749
+
750
+ /*--------------------------------------------------------------------------*/
751
+
752
+ Abstract.EventObserver = function() {}
753
+ Abstract.EventObserver.prototype = {
754
+ initialize: function(element, callback) {
755
+ this.element = $(element);
756
+ this.callback = callback;
757
+
758
+ this.lastValue = this.getValue();
759
+ if (this.element.tagName.toLowerCase() == 'form')
760
+ this.registerFormCallbacks();
761
+ else
762
+ this.registerCallback(this.element);
763
+ },
764
+
765
+ onElementEvent: function() {
766
+ var value = this.getValue();
767
+ if (this.lastValue != value) {
768
+ this.callback(this.element, value);
769
+ this.lastValue = value;
770
+ }
771
+ },
772
+
773
+ registerFormCallbacks: function() {
774
+ var elements = Form.getElements(this.element);
775
+ for (var i = 0; i < elements.length; i++)
776
+ this.registerCallback(elements[i]);
777
+ },
778
+
779
+ registerCallback: function(element) {
780
+ if (element.type) {
781
+ switch (element.type.toLowerCase()) {
782
+ case 'checkbox':
783
+ case 'radio':
784
+ element.target = this;
785
+ element.prev_onclick = element.onclick || Prototype.emptyFunction;
786
+ element.onclick = function() {
787
+ this.prev_onclick();
788
+ this.target.onElementEvent();
789
+ }
790
+ break;
791
+ case 'password':
792
+ case 'text':
793
+ case 'textarea':
794
+ case 'select-one':
795
+ case 'select-multiple':
796
+ element.target = this;
797
+ element.prev_onchange = element.onchange || Prototype.emptyFunction;
798
+ element.onchange = function() {
799
+ this.prev_onchange();
800
+ this.target.onElementEvent();
801
+ }
802
+ break;
803
+ }
804
+ }
805
+ }
806
+ }
807
+
808
+ Form.Element.EventObserver = Class.create();
809
+ Form.Element.EventObserver.prototype = (new Abstract.EventObserver()).extend({
810
+ getValue: function() {
811
+ return Form.Element.getValue(this.element);
812
+ }
813
+ });
814
+
815
+ Form.EventObserver = Class.create();
816
+ Form.EventObserver.prototype = (new Abstract.EventObserver()).extend({
817
+ getValue: function() {
818
+ return Form.serialize(this.element);
819
+ }
820
+ });
821
+
822
+
823
+ if (!window.Event) {
824
+ var Event = new Object();
825
+ }
826
+
827
+ Object.extend(Event, {
828
+ KEY_BACKSPACE: 8,
829
+ KEY_TAB: 9,
830
+ KEY_RETURN: 13,
831
+ KEY_ESC: 27,
832
+ KEY_LEFT: 37,
833
+ KEY_UP: 38,
834
+ KEY_RIGHT: 39,
835
+ KEY_DOWN: 40,
836
+ KEY_DELETE: 46,
837
+
838
+ element: function(event) {
839
+ return event.srcElement || event.currentTarget;
840
+ },
841
+
842
+ isLeftClick: function(event) {
843
+ return (((event.which) && (event.which == 1)) ||
844
+ ((event.button) && (event.button == 1)));
845
+ },
846
+
847
+ pointerX: function(event) {
848
+ return event.pageX || (event.clientX +
849
+ (document.documentElement.scrollLeft || document.body.scrollLeft));
850
+ },
851
+
852
+ pointerY: function(event) {
853
+ return event.pageY || (event.clientY +
854
+ (document.documentElement.scrollTop || document.body.scrollTop));
855
+ },
856
+
857
+ stop: function(event) {
858
+ if (event.preventDefault) {
859
+ event.preventDefault();
860
+ event.stopPropagation();
861
+ } else {
862
+ event.returnValue = false;
863
+ }
864
+ },
865
+
866
+ // find the first node with the given tagName, starting from the
867
+ // node the event was triggered on; traverses the DOM upwards
868
+ findElement: function(event, tagName) {
869
+ var element = Event.element(event);
870
+ while (element.parentNode && (!element.tagName ||
871
+ (element.tagName.toUpperCase() != tagName.toUpperCase())))
872
+ element = element.parentNode;
873
+ return element;
874
+ },
875
+
876
+ observe: function(element, name, observer, useCapture) {
877
+ var element = $(element);
878
+ useCapture = useCapture || false;
879
+
880
+ if (name == 'keypress') {
881
+ if (navigator.appVersion.indexOf('AppleWebKit') > 0) {
882
+ element.addEventListener('keydown', observer, useCapture);
883
+ return;
884
+ }
885
+ if (element.addEventListener) {
886
+ element.addEventListener('keypress', observer, useCapture);
887
+ } else if (element.attachEvent) {
888
+ element.attachEvent('onkeydown', observer);
889
+ }
890
+ } else {
891
+ if (element.addEventListener) {
892
+ element.addEventListener(name, observer, useCapture);
893
+ } else if (element.attachEvent) {
894
+ element.attachEvent('on' + name, observer);
895
+ }
896
+ }
897
+ },
898
+
899
+ stopObserving: function(element, name, observer, useCapture) {
900
+ var element = $(element);
901
+ useCapture = useCapture || false;
902
+
903
+ if (name == 'keypress') {
904
+ if (navigator.appVersion.indexOf('AppleWebKit') > 0) {
905
+ element.removeEventListener('keydown', observer, useCapture);
906
+ return;
907
+ }
908
+ if (element.removeEventListener) {
909
+ element.removeEventListener('keypress', observer, useCapture);
910
+ } else if (element.detachEvent) {
911
+ element.detachEvent('onkeydown', observer);
912
+ }
913
+ } else {
914
+ if (element.removeEventListener) {
915
+ element.removeEventListener(name, observer, useCapture);
916
+ } else if (element.detachEvent) {
917
+ element.detachEvent('on' + name, observer);
918
+ }
919
+ }
920
+ }
921
+ });
922
+
923
+ var Position = {
924
+
925
+ // set to true if needed, warning: firefox performance problems
926
+ // NOT neeeded for page scrolling, only if draggable contained in
927
+ // scrollable elements
928
+ includeScrollOffsets: false,
929
+
930
+ // must be called before calling withinIncludingScrolloffset, every time the
931
+ // page is scrolled
932
+ prepare: function() {
933
+ this.deltaX = window.pageXOffset
934
+ || document.documentElement.scrollLeft
935
+ || document.body.scrollLeft
936
+ || 0;
937
+ this.deltaY = window.pageYOffset
938
+ || document.documentElement.scrollTop
939
+ || document.body.scrollTop
940
+ || 0;
941
+ },
942
+
943
+ realOffset: function(element) {
944
+ var valueT = 0, valueL = 0;
945
+ do {
946
+ valueT += element.scrollTop || 0;
947
+ valueL += element.scrollLeft || 0;
948
+ element = element.parentNode;
949
+ } while (element);
950
+ return [valueL, valueT];
951
+ },
952
+
953
+ cumulativeOffset: function(element) {
954
+ var valueT = 0, valueL = 0;
955
+ do {
956
+ valueT += element.offsetTop || 0;
957
+ valueL += element.offsetLeft || 0;
958
+ element = element.offsetParent;
959
+ } while (element);
960
+ return [valueL, valueT];
961
+ },
962
+
963
+ // caches x/y coordinate pair to use with overlap
964
+ within: function(element, x, y) {
965
+ if (this.includeScrollOffsets)
966
+ return this.withinIncludingScrolloffsets(element, x, y);
967
+ this.xcomp = x;
968
+ this.ycomp = y;
969
+ this.offset = this.cumulativeOffset(element);
970
+
971
+ return (y >= this.offset[1] &&
972
+ y < this.offset[1] + element.offsetHeight &&
973
+ x >= this.offset[0] &&
974
+ x < this.offset[0] + element.offsetWidth);
975
+ },
976
+
977
+ withinIncludingScrolloffsets: function(element, x, y) {
978
+ var offsetcache = this.realOffset(element);
979
+
980
+ this.xcomp = x + offsetcache[0] - this.deltaX;
981
+ this.ycomp = y + offsetcache[1] - this.deltaY;
982
+ this.offset = this.cumulativeOffset(element);
983
+
984
+ return (this.ycomp >= this.offset[1] &&
985
+ this.ycomp < this.offset[1] + element.offsetHeight &&
986
+ this.xcomp >= this.offset[0] &&
987
+ this.xcomp < this.offset[0] + element.offsetWidth);
988
+ },
989
+
990
+ // within must be called directly before
991
+ overlap: function(mode, element) {
992
+ if (!mode) return 0;
993
+ if (mode == 'vertical')
994
+ return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
995
+ element.offsetHeight;
996
+ if (mode == 'horizontal')
997
+ return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
998
+ element.offsetWidth;
999
+ },
1000
+
1001
+ clone: function(source, target) {
1002
+ source = $(source);
1003
+ target = $(target);
1004
+ target.style.position = 'absolute';
1005
+ var offsets = this.cumulativeOffset(source);
1006
+ target.style.top = offsets[1] + 'px';
1007
+ target.style.left = offsets[0] + 'px';
1008
+ target.style.width = source.offsetWidth + 'px';
1009
+ target.style.height = source.offsetHeight + 'px';
1010
+ }
1011
+ }