nitro 0.29.0 → 0.30.0

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 (93) hide show
  1. data/CHANGELOG +410 -0
  2. data/ProjectInfo +36 -44
  3. data/README +5 -5
  4. data/doc/AUTHORS +6 -0
  5. data/doc/RELEASES +159 -2
  6. data/lib/glue/sweeper.rb +2 -2
  7. data/lib/glue/webfile.rb +14 -1
  8. data/lib/nitro.rb +6 -9
  9. data/lib/nitro/adapter/mongrel.rb +36 -43
  10. data/lib/nitro/adapter/scgi.rb +1 -1
  11. data/lib/nitro/adapter/webrick.rb +96 -24
  12. data/lib/nitro/caching/actions.rb +2 -1
  13. data/lib/nitro/caching/fragments.rb +1 -8
  14. data/lib/nitro/caching/output.rb +14 -4
  15. data/lib/nitro/cgi.rb +19 -21
  16. data/lib/nitro/cgi/cookie.rb +5 -1
  17. data/lib/nitro/cgi/request.rb +20 -4
  18. data/lib/nitro/compiler.rb +74 -28
  19. data/lib/nitro/compiler/cleanup.rb +1 -1
  20. data/lib/nitro/compiler/elements.rb +1 -2
  21. data/lib/nitro/compiler/localization.rb +1 -1
  22. data/lib/nitro/compiler/markup.rb +1 -1
  23. data/lib/nitro/compiler/script.rb +52 -44
  24. data/lib/nitro/compiler/squeeze.rb +4 -3
  25. data/lib/nitro/compiler/xslt.rb +7 -6
  26. data/lib/nitro/context.rb +39 -20
  27. data/lib/nitro/controller.rb +24 -5
  28. data/lib/nitro/dispatcher.rb +13 -5
  29. data/lib/nitro/global.rb +63 -0
  30. data/lib/nitro/helper/feed.rb +432 -0
  31. data/lib/nitro/helper/form.rb +11 -3
  32. data/lib/nitro/helper/form/builder.rb +140 -0
  33. data/lib/nitro/helper/form/controls.rb +2 -1
  34. data/lib/nitro/helper/javascript.rb +6 -0
  35. data/lib/nitro/helper/javascript/morphing.rb +13 -6
  36. data/lib/nitro/helper/xhtml.rb +42 -6
  37. data/lib/nitro/helper/xml.rb +3 -0
  38. data/lib/nitro/part.rb +2 -2
  39. data/lib/nitro/render.rb +7 -2
  40. data/lib/nitro/router.rb +57 -16
  41. data/lib/nitro/scaffolding.rb +29 -20
  42. data/lib/nitro/server.rb +4 -10
  43. data/lib/nitro/server/drb.rb +1 -1
  44. data/lib/nitro/server/runner.rb +10 -0
  45. data/lib/nitro/session.rb +31 -12
  46. data/lib/nitro/session/drb.rb +13 -1
  47. data/lib/nitro/session/file.rb +1 -1
  48. data/lib/nitro/session/memcached.rb +1 -1
  49. data/lib/nitro/session/memory.rb +1 -1
  50. data/lib/nitro/session/og.rb +1 -1
  51. data/lib/nitro/test/testcase.rb +3 -0
  52. data/proto/public/error.xhtml +5 -5
  53. data/proto/public/js/controls.js +2 -2
  54. data/proto/public/js/dragdrop.js +320 -79
  55. data/proto/public/js/effects.js +200 -152
  56. data/proto/public/js/prototype.js +284 -63
  57. data/proto/public/js/scriptaculous.js +7 -5
  58. data/proto/public/js/unittest.js +11 -0
  59. data/proto/public/scaffold/advanced_search.xhtml +30 -0
  60. data/proto/public/scaffold/list.xhtml +8 -1
  61. data/proto/public/scaffold/search.xhtml +2 -1
  62. data/proto/script/scgi_service +1 -1
  63. data/src/part/admin/controller.rb +1 -1
  64. data/src/part/admin/skin.rb +1 -1
  65. data/test/nitro/CONFIG.rb +3 -0
  66. data/test/nitro/adapter/tc_webrick.rb +1 -1
  67. data/test/nitro/cgi/tc_cookie.rb +1 -1
  68. data/test/nitro/cgi/tc_request.rb +5 -5
  69. data/test/nitro/compiler/tc_client_morpher.rb +47 -0
  70. data/test/nitro/compiler/tc_compiler.rb +2 -0
  71. data/test/nitro/helper/tc_feed.rb +138 -0
  72. data/test/nitro/helper/tc_pager.rb +1 -1
  73. data/test/nitro/helper/tc_rss.rb +1 -1
  74. data/test/nitro/helper/tc_table.rb +1 -1
  75. data/test/nitro/helper/tc_xhtml.rb +1 -1
  76. data/test/nitro/tc_caching.rb +1 -1
  77. data/test/nitro/tc_cgi.rb +1 -1
  78. data/test/nitro/tc_context.rb +1 -1
  79. data/test/nitro/tc_controller.rb +31 -3
  80. data/test/nitro/tc_controller_aspect.rb +1 -1
  81. data/test/nitro/tc_dispatcher.rb +1 -1
  82. data/test/nitro/tc_element.rb +1 -1
  83. data/test/nitro/tc_flash.rb +1 -1
  84. data/test/nitro/tc_helper.rb +1 -1
  85. data/test/nitro/tc_render.rb +6 -6
  86. data/test/nitro/tc_router.rb +8 -4
  87. data/test/nitro/tc_server.rb +1 -3
  88. data/test/nitro/tc_session.rb +1 -3
  89. metadata +107 -104
  90. data/Rakefile +0 -232
  91. data/lib/nitro/adapter/acgi.rb +0 -237
  92. data/proto/public/Makefile.acgi +0 -40
  93. data/proto/public/acgi.c +0 -138
@@ -1,17 +1,13 @@
1
- /* Prototype JavaScript framework, version 1.4.0
1
+ /* Prototype JavaScript framework, version 1.5.0_rc0
2
2
  * (c) 2005 Sam Stephenson <sam@conio.net>
3
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
4
  * Prototype is freely distributable under the terms of an MIT-style license.
8
- *
9
5
  * For details, see the Prototype web site: http://prototype.conio.net/
10
6
  *
11
7
  /*--------------------------------------------------------------------------*/
12
8
 
13
9
  var Prototype = {
14
- Version: '1.4.0',
10
+ Version: '1.5.0_rc0',
15
11
  ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',
16
12
 
17
13
  emptyFunction: function() {},
@@ -29,7 +25,7 @@ var Class = {
29
25
  var Abstract = new Object();
30
26
 
31
27
  Object.extend = function(destination, source) {
32
- for (property in source) {
28
+ for (var property in source) {
33
29
  destination[property] = source[property];
34
30
  }
35
31
  return destination;
@@ -120,26 +116,49 @@ PeriodicalExecuter.prototype = {
120
116
  }
121
117
  }
122
118
  }
119
+ Object.extend(String.prototype, {
120
+ gsub: function(pattern, replacement) {
121
+ var result = '', source = this, match;
122
+ replacement = arguments.callee.prepareReplacement(replacement);
123
+
124
+ while (source.length > 0) {
125
+ if (match = source.match(pattern)) {
126
+ result += source.slice(0, match.index);
127
+ result += (replacement(match) || '').toString();
128
+ source = source.slice(match.index + match[0].length);
129
+ } else {
130
+ result += source, source = '';
131
+ }
132
+ }
133
+ return result;
134
+ },
123
135
 
124
- /*--------------------------------------------------------------------------*/
136
+ sub: function(pattern, replacement, count) {
137
+ replacement = this.gsub.prepareReplacement(replacement);
138
+ count = count === undefined ? 1 : count;
125
139
 
126
- function $() {
127
- var elements = new Array();
140
+ return this.gsub(pattern, function(match) {
141
+ if (--count < 0) return match[0];
142
+ return replacement(match);
143
+ });
144
+ },
128
145
 
129
- for (var i = 0; i < arguments.length; i++) {
130
- var element = arguments[i];
131
- if (typeof element == 'string')
132
- element = document.getElementById(element);
146
+ scan: function(pattern, iterator) {
147
+ this.gsub(pattern, iterator);
148
+ return this;
149
+ },
133
150
 
134
- if (arguments.length == 1)
135
- return element;
151
+ truncate: function(length, truncation) {
152
+ length = length || 30;
153
+ truncation = truncation === undefined ? '...' : truncation;
154
+ return this.length > length ?
155
+ this.slice(0, length - truncation.length) + truncation : this;
156
+ },
136
157
 
137
- elements.push(element);
138
- }
158
+ strip: function() {
159
+ return this.replace(/^\s+/, '').replace(/\s+$/, '');
160
+ },
139
161
 
140
- return elements;
141
- }
142
- Object.extend(String.prototype, {
143
162
  stripTags: function() {
144
163
  return this.replace(/<\/?[^>]+>/gi, '');
145
164
  },
@@ -157,7 +176,7 @@ Object.extend(String.prototype, {
157
176
  },
158
177
 
159
178
  evalScripts: function() {
160
- return this.extractScripts().map(eval);
179
+ return this.extractScripts().map(function(script) { return eval(script) });
161
180
  },
162
181
 
163
182
  escapeHTML: function() {
@@ -203,12 +222,35 @@ Object.extend(String.prototype, {
203
222
  },
204
223
 
205
224
  inspect: function() {
206
- return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'";
225
+ return "'" + this.replace(/\\/g, '\\\\').replace(/'/g, '\\\'') + "'";
207
226
  }
208
227
  });
209
228
 
229
+ String.prototype.gsub.prepareReplacement = function(replacement) {
230
+ if (typeof replacement == 'function') return replacement;
231
+ var template = new Template(replacement);
232
+ return function(match) { return template.evaluate(match) };
233
+ }
234
+
210
235
  String.prototype.parseQuery = String.prototype.toQueryParams;
211
236
 
237
+ var Template = Class.create();
238
+ Template.Pattern = /(^|.|\r|\n)(#\{(.*?)\})/;
239
+ Template.prototype = {
240
+ initialize: function(template, pattern) {
241
+ this.template = template.toString();
242
+ this.pattern = pattern || Template.Pattern;
243
+ },
244
+
245
+ evaluate: function(object) {
246
+ return this.template.gsub(this.pattern, function(match) {
247
+ var before = match[1];
248
+ if (before == '\\') return match[2];
249
+ return before + (object[match[3]] || '').toString();
250
+ });
251
+ }
252
+ }
253
+
212
254
  var $break = new Object();
213
255
  var $continue = new Object();
214
256
 
@@ -313,7 +355,7 @@ var Enumerable = {
313
355
  var result;
314
356
  this.each(function(value, index) {
315
357
  value = (iterator || Prototype.K)(value, index);
316
- if (value >= (result || value))
358
+ if (result == undefined || value >= result)
317
359
  result = value;
318
360
  });
319
361
  return result;
@@ -323,7 +365,7 @@ var Enumerable = {
323
365
  var result;
324
366
  this.each(function(value, index) {
325
367
  value = (iterator || Prototype.K)(value, index);
326
- if (value <= (result || value))
368
+ if (result == undefined || value < result)
327
369
  result = value;
328
370
  });
329
371
  return result;
@@ -375,8 +417,7 @@ var Enumerable = {
375
417
 
376
418
  var collections = [this].concat(args).map($A);
377
419
  return this.map(function(value, index) {
378
- iterator(value = collections.pluck(index));
379
- return value;
420
+ return iterator(collections.pluck(index));
380
421
  });
381
422
  },
382
423
 
@@ -406,7 +447,8 @@ var $A = Array.from = function(iterable) {
406
447
 
407
448
  Object.extend(Array.prototype, Enumerable);
408
449
 
409
- Array.prototype._reverse = Array.prototype.reverse;
450
+ if (!Array.prototype._reverse)
451
+ Array.prototype._reverse = Array.prototype.reverse;
410
452
 
411
453
  Object.extend(Array.prototype, {
412
454
  _each: function(iterator) {
@@ -435,7 +477,7 @@ Object.extend(Array.prototype, {
435
477
 
436
478
  flatten: function() {
437
479
  return this.inject([], function(array, value) {
438
- return array.concat(value.constructor == Array ?
480
+ return array.concat(value && value.constructor == Array ?
439
481
  value.flatten() : [value]);
440
482
  });
441
483
  },
@@ -457,21 +499,13 @@ Object.extend(Array.prototype, {
457
499
  return (inline !== false ? this : this.toArray())._reverse();
458
500
  },
459
501
 
460
- shift: function() {
461
- var result = this[0];
462
- for (var i = 0; i < this.length - 1; i++)
463
- this[i] = this[i + 1];
464
- this.length--;
465
- return result;
466
- },
467
-
468
502
  inspect: function() {
469
503
  return '[' + this.map(Object.inspect).join(', ') + ']';
470
504
  }
471
505
  });
472
506
  var Hash = {
473
507
  _each: function(iterator) {
474
- for (key in this) {
508
+ for (var key in this) {
475
509
  var value = this[key];
476
510
  if (typeof value == 'function') continue;
477
511
 
@@ -549,9 +583,9 @@ var $R = function(start, end, exclusive) {
549
583
  var Ajax = {
550
584
  getTransport: function() {
551
585
  return Try.these(
586
+ function() {return new XMLHttpRequest()},
552
587
  function() {return new ActiveXObject('Msxml2.XMLHTTP')},
553
- function() {return new ActiveXObject('Microsoft.XMLHTTP')},
554
- function() {return new XMLHttpRequest()}
588
+ function() {return new ActiveXObject('Microsoft.XMLHTTP')}
555
589
  ) || false;
556
590
  },
557
591
 
@@ -603,6 +637,7 @@ Ajax.Base.prototype = {
603
637
  this.options = {
604
638
  method: 'post',
605
639
  asynchronous: true,
640
+ contentType: 'application/x-www-form-urlencoded',
606
641
  parameters: ''
607
642
  }
608
643
  Object.extend(this.options, options || {});
@@ -662,11 +697,11 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
662
697
  setRequestHeaders: function() {
663
698
  var requestHeaders =
664
699
  ['X-Requested-With', 'XMLHttpRequest',
665
- 'X-Prototype-Version', Prototype.Version];
700
+ 'X-Prototype-Version', Prototype.Version,
701
+ 'Accept', 'text/javascript, text/html, application/xml, text/xml, */*'];
666
702
 
667
703
  if (this.options.method == 'post') {
668
- requestHeaders.push('Content-type',
669
- 'application/x-www-form-urlencoded');
704
+ requestHeaders.push('Content-type', this.options.contentType);
670
705
 
671
706
  /* Force "Connection: close" for Mozilla browsers to work around
672
707
  * a bug where XMLHttpReqeuest sends an incorrect Content-length
@@ -697,7 +732,7 @@ Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
697
732
 
698
733
  evalJSON: function() {
699
734
  try {
700
- return eval(this.header('X-JSON'));
735
+ return eval('(' + this.header('X-JSON') + ')');
701
736
  } catch (e) {}
702
737
  },
703
738
 
@@ -831,22 +866,57 @@ Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
831
866
  this.updater = new Ajax.Updater(this.container, this.url, this.options);
832
867
  }
833
868
  });
869
+ function $() {
870
+ var results = [], element;
871
+ for (var i = 0; i < arguments.length; i++) {
872
+ element = arguments[i];
873
+ if (typeof element == 'string')
874
+ element = document.getElementById(element);
875
+ results.push(Element.extend(element));
876
+ }
877
+ return results.length < 2 ? results[0] : results;
878
+ }
879
+
834
880
  document.getElementsByClassName = function(className, parentElement) {
835
881
  var children = ($(parentElement) || document.body).getElementsByTagName('*');
836
882
  return $A(children).inject([], function(elements, child) {
837
883
  if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
838
- elements.push(child);
884
+ elements.push(Element.extend(child));
839
885
  return elements;
840
886
  });
841
887
  }
842
888
 
843
889
  /*--------------------------------------------------------------------------*/
844
890
 
845
- if (!window.Element) {
891
+ if (!window.Element)
846
892
  var Element = new Object();
893
+
894
+ Element.extend = function(element) {
895
+ if (!element) return;
896
+ if (_nativeExtensions) return element;
897
+
898
+ if (!element._extended && element.tagName && element != window) {
899
+ var methods = Element.Methods, cache = Element.extend.cache;
900
+ for (property in methods) {
901
+ var value = methods[property];
902
+ if (typeof value == 'function')
903
+ element[property] = cache.findOrStore(value);
904
+ }
905
+ }
906
+
907
+ element._extended = true;
908
+ return element;
847
909
  }
848
910
 
849
- Object.extend(Element, {
911
+ Element.extend.cache = {
912
+ findOrStore: function(value) {
913
+ return this[value] = this[value] || function() {
914
+ return value.apply(null, [this].concat($A(arguments)));
915
+ }
916
+ }
917
+ }
918
+
919
+ Element.Methods = {
850
920
  visible: function(element) {
851
921
  return $(element).style.display != 'none';
852
922
  },
@@ -882,6 +952,19 @@ Object.extend(Element, {
882
952
  setTimeout(function() {html.evalScripts()}, 10);
883
953
  },
884
954
 
955
+ replace: function(element, html) {
956
+ element = $(element);
957
+ if (element.outerHTML) {
958
+ element.outerHTML = html.stripScripts();
959
+ } else {
960
+ var range = element.ownerDocument.createRange();
961
+ range.selectNodeContents(element);
962
+ element.parentNode.replaceChild(
963
+ range.createContextualFragment(html.stripScripts()), element);
964
+ }
965
+ setTimeout(function() {html.evalScripts()}, 10);
966
+ },
967
+
885
968
  getHeight: function(element) {
886
969
  element = $(element);
887
970
  return element.offsetHeight;
@@ -920,6 +1003,13 @@ Object.extend(Element, {
920
1003
  return $(element).innerHTML.match(/^\s*$/);
921
1004
  },
922
1005
 
1006
+ childOf: function(element, ancestor) {
1007
+ element = $(element), ancestor = $(ancestor);
1008
+ while (element = element.parentNode)
1009
+ if (element == ancestor) return true;
1010
+ return false;
1011
+ },
1012
+
923
1013
  scrollTo: function(element) {
924
1014
  element = $(element);
925
1015
  var x = element.x ? element.x : element.offsetLeft,
@@ -947,7 +1037,7 @@ Object.extend(Element, {
947
1037
 
948
1038
  setStyle: function(element, style) {
949
1039
  element = $(element);
950
- for (name in style)
1040
+ for (var name in style)
951
1041
  element.style[name.camelize()] = style[name];
952
1042
  },
953
1043
 
@@ -1013,7 +1103,32 @@ Object.extend(Element, {
1013
1103
  element.style.overflow = element._overflow;
1014
1104
  element._overflow = undefined;
1015
1105
  }
1016
- });
1106
+ }
1107
+
1108
+ Object.extend(Element, Element.Methods);
1109
+
1110
+ var _nativeExtensions = false;
1111
+
1112
+ if(!HTMLElement && /Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
1113
+ var HTMLElement = {}
1114
+ HTMLElement.prototype = document.createElement('div').__proto__;
1115
+ }
1116
+
1117
+ Element.addMethods = function(methods) {
1118
+ Object.extend(Element.Methods, methods || {});
1119
+
1120
+ if(typeof HTMLElement != 'undefined') {
1121
+ var methods = Element.Methods, cache = Element.extend.cache;
1122
+ for (property in methods) {
1123
+ var value = methods[property];
1124
+ if (typeof value == 'function')
1125
+ HTMLElement.prototype[property] = cache.findOrStore(value);
1126
+ }
1127
+ _nativeExtensions = true;
1128
+ }
1129
+ }
1130
+
1131
+ Element.addMethods();
1017
1132
 
1018
1133
  var Toggle = new Object();
1019
1134
  Toggle.display = Element.toggle;
@@ -1033,7 +1148,8 @@ Abstract.Insertion.prototype = {
1033
1148
  try {
1034
1149
  this.element.insertAdjacentHTML(this.adjacency, this.content);
1035
1150
  } catch (e) {
1036
- if (this.element.tagName.toLowerCase() == 'tbody') {
1151
+ var tagName = this.element.tagName.toLowerCase();
1152
+ if (tagName == 'tbody' || tagName == 'tr') {
1037
1153
  this.insertContent(this.contentFromAnonymousTable());
1038
1154
  } else {
1039
1155
  throw e;
@@ -1148,6 +1264,116 @@ Element.ClassNames.prototype = {
1148
1264
  }
1149
1265
 
1150
1266
  Object.extend(Element.ClassNames.prototype, Enumerable);
1267
+ var Selector = Class.create();
1268
+ Selector.prototype = {
1269
+ initialize: function(expression) {
1270
+ this.params = {classNames: []};
1271
+ this.expression = expression.toString().strip();
1272
+ this.parseExpression();
1273
+ this.compileMatcher();
1274
+ },
1275
+
1276
+ parseExpression: function() {
1277
+ function abort(message) { throw 'Parse error in selector: ' + message; }
1278
+
1279
+ if (this.expression == '') abort('empty expression');
1280
+
1281
+ var params = this.params, expr = this.expression, match, modifier, clause, rest;
1282
+ while (match = expr.match(/^(.*)\[([a-z0-9_:-]+?)(?:([~\|!]?=)(?:"([^"]*)"|([^\]\s]*)))?\]$/i)) {
1283
+ params.attributes = params.attributes || [];
1284
+ params.attributes.push({name: match[2], operator: match[3], value: match[4] || match[5] || ''});
1285
+ expr = match[1];
1286
+ }
1287
+
1288
+ if (expr == '*') return this.params.wildcard = true;
1289
+
1290
+ while (match = expr.match(/^([^a-z0-9_-])?([a-z0-9_-]+)(.*)/i)) {
1291
+ modifier = match[1], clause = match[2], rest = match[3];
1292
+ switch (modifier) {
1293
+ case '#': params.id = clause; break;
1294
+ case '.': params.classNames.push(clause); break;
1295
+ case '':
1296
+ case undefined: params.tagName = clause.toUpperCase(); break;
1297
+ default: abort(expr.inspect());
1298
+ }
1299
+ expr = rest;
1300
+ }
1301
+
1302
+ if (expr.length > 0) abort(expr.inspect());
1303
+ },
1304
+
1305
+ buildMatchExpression: function() {
1306
+ var params = this.params, conditions = [], clause;
1307
+
1308
+ if (params.wildcard)
1309
+ conditions.push('true');
1310
+ if (clause = params.id)
1311
+ conditions.push('element.id == ' + clause.inspect());
1312
+ if (clause = params.tagName)
1313
+ conditions.push('element.tagName.toUpperCase() == ' + clause.inspect());
1314
+ if ((clause = params.classNames).length > 0)
1315
+ for (var i = 0; i < clause.length; i++)
1316
+ conditions.push('Element.hasClassName(element, ' + clause[i].inspect() + ')');
1317
+ if (clause = params.attributes) {
1318
+ clause.each(function(attribute) {
1319
+ var value = 'element.getAttribute(' + attribute.name.inspect() + ')';
1320
+ var splitValueBy = function(delimiter) {
1321
+ return value + ' && ' + value + '.split(' + delimiter.inspect() + ')';
1322
+ }
1323
+
1324
+ switch (attribute.operator) {
1325
+ case '=': conditions.push(value + ' == ' + attribute.value.inspect()); break;
1326
+ case '~=': conditions.push(splitValueBy(' ') + '.include(' + attribute.value.inspect() + ')'); break;
1327
+ case '|=': conditions.push(
1328
+ splitValueBy('-') + '.first().toUpperCase() == ' + attribute.value.toUpperCase().inspect()
1329
+ ); break;
1330
+ case '!=': conditions.push(value + ' != ' + attribute.value.inspect()); break;
1331
+ case '':
1332
+ case undefined: conditions.push(value + ' != null'); break;
1333
+ default: throw 'Unknown operator ' + attribute.operator + ' in selector';
1334
+ }
1335
+ });
1336
+ }
1337
+
1338
+ return conditions.join(' && ');
1339
+ },
1340
+
1341
+ compileMatcher: function() {
1342
+ this.match = new Function('element', 'if (!element.tagName) return false; \
1343
+ return ' + this.buildMatchExpression());
1344
+ },
1345
+
1346
+ findElements: function(scope) {
1347
+ var element;
1348
+
1349
+ if (element = $(this.params.id))
1350
+ if (this.match(element))
1351
+ if (!scope || Element.childOf(element, scope))
1352
+ return [element];
1353
+
1354
+ scope = (scope || document).getElementsByTagName(this.params.tagName || '*');
1355
+
1356
+ var results = [];
1357
+ for (var i = 0; i < scope.length; i++)
1358
+ if (this.match(element = scope[i]))
1359
+ results.push(Element.extend(element));
1360
+
1361
+ return results;
1362
+ },
1363
+
1364
+ toString: function() {
1365
+ return this.expression;
1366
+ }
1367
+ }
1368
+
1369
+ function $$() {
1370
+ return $A(arguments).map(function(expression) {
1371
+ return expression.strip().split(/\s+/).inject([null], function(results, expr) {
1372
+ var selector = new Selector(expr);
1373
+ return results.map(selector.findElements.bind(selector)).flatten();
1374
+ });
1375
+ }).flatten();
1376
+ }
1151
1377
  var Field = {
1152
1378
  clear: function() {
1153
1379
  for (var i = 0; i < arguments.length; i++)
@@ -1196,7 +1422,7 @@ var Form = {
1196
1422
  form = $(form);
1197
1423
  var elements = new Array();
1198
1424
 
1199
- for (tagName in Form.Element.Serializers) {
1425
+ for (var tagName in Form.Element.Serializers) {
1200
1426
  var tagElements = form.getElementsByTagName(tagName);
1201
1427
  for (var j = 0; j < tagElements.length; j++)
1202
1428
  elements.push(tagElements[j]);
@@ -1318,23 +1544,17 @@ Form.Element.Serializers = {
1318
1544
  var value = '', opt, index = element.selectedIndex;
1319
1545
  if (index >= 0) {
1320
1546
  opt = element.options[index];
1321
- value = opt.value;
1322
- if (!value && !('value' in opt))
1323
- value = opt.text;
1547
+ value = opt.value || opt.text;
1324
1548
  }
1325
1549
  return [element.name, value];
1326
1550
  },
1327
1551
 
1328
1552
  selectMany: function(element) {
1329
- var value = new Array();
1553
+ var value = [];
1330
1554
  for (var i = 0; i < element.length; i++) {
1331
1555
  var opt = element.options[i];
1332
- if (opt.selected) {
1333
- var optValue = opt.value;
1334
- if (!optValue && !('value' in opt))
1335
- optValue = opt.text;
1336
- value.push(optValue);
1337
- }
1556
+ if (opt.selected)
1557
+ value.push(opt.value || opt.text);
1338
1558
  }
1339
1559
  return [element.name, value];
1340
1560
  }
@@ -1551,7 +1771,8 @@ Object.extend(Event, {
1551
1771
  });
1552
1772
 
1553
1773
  /* prevent memory leaks in IE */
1554
- Event.observe(window, 'unload', Event.unloadCache, false);
1774
+ if (navigator.appVersion.match(/\bMSIE\b/))
1775
+ Event.observe(window, 'unload', Event.unloadCache, false);
1555
1776
  var Position = {
1556
1777
  // set to true if needed, warning: firefox performance problems
1557
1778
  // NOT neeeded for page scrolling, only if draggable contained in
@@ -1782,4 +2003,4 @@ if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
1782
2003
 
1783
2004
  return [valueL, valueT];
1784
2005
  }
1785
- }
2006
+ }