source: proiecte/HadoopJUnit/hadoop-0.20.1/docs/cn/skin/prototype.js @ 120

Last change on this file since 120 was 120, checked in by (none), 14 years ago

Added the mail files for the Hadoop JUNit Project

  • Property svn:executable set to *
File size: 32.1 KB
Line 
1/*  Prototype JavaScript framework, version 1.4.0_pre4
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
13var Prototype = {
14  Version: '1.4.0_pre4',
15 
16  emptyFunction: function() {},
17  K: function(x) {return x}
18}
19
20var Class = {
21  create: function() {
22    return function() { 
23      this.initialize.apply(this, arguments);
24    }
25  }
26}
27
28var Abstract = new Object();
29
30Object.extend = function(destination, source) {
31  for (property in source) {
32    destination[property] = source[property];
33  }
34  return destination;
35}
36
37Function.prototype.bind = function(object) {
38  var __method = this;
39  return function() {
40    return __method.apply(object, arguments);
41  }
42}
43
44Function.prototype.bindAsEventListener = function(object) {
45  var __method = this;
46  return function(event) {
47    return __method.call(object, event || window.event);
48  }
49}
50
51Number.prototype.toColorPart = function() {
52  var digits = this.toString(16);
53  if (this < 16) return '0' + digits;
54  return digits;
55}
56
57var Try = {
58  these: function() {
59    var returnValue;
60
61    for (var i = 0; i < arguments.length; i++) {
62      var lambda = arguments[i];
63      try {
64        returnValue = lambda();
65        break;
66      } catch (e) {}
67    }
68
69    return returnValue;
70  }
71}
72
73/*--------------------------------------------------------------------------*/
74
75var PeriodicalExecuter = Class.create();
76PeriodicalExecuter.prototype = {
77  initialize: function(callback, frequency) {
78    this.callback = callback;
79    this.frequency = frequency;
80    this.currentlyExecuting = false;
81
82    this.registerCallback();
83  },
84
85  registerCallback: function() {
86    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
87  },
88
89  onTimerEvent: function() {
90    if (!this.currentlyExecuting) {
91      try { 
92        this.currentlyExecuting = true;
93        this.callback(); 
94      } finally { 
95        this.currentlyExecuting = false;
96      }
97    }
98  }
99}
100
101/*--------------------------------------------------------------------------*/
102
103function $() {
104  var elements = new Array();
105
106  for (var i = 0; i < arguments.length; i++) {
107    var element = arguments[i];
108    if (typeof element == 'string')
109      element = document.getElementById(element);
110
111    if (arguments.length == 1) 
112      return element;
113
114    elements.push(element);
115  }
116
117  return elements;
118}
119
120if (!Array.prototype.push) {
121  Array.prototype.push = function() {
122                var startLength = this.length;
123                for (var i = 0; i < arguments.length; i++)
124      this[startLength + i] = arguments[i];
125          return this.length;
126  }
127}
128
129if (!Function.prototype.apply) {
130  // Based on code from http://www.youngpup.net/
131  Function.prototype.apply = function(object, parameters) {
132    var parameterStrings = new Array();
133    if (!object)     object = window;
134    if (!parameters) parameters = new Array();
135   
136    for (var i = 0; i < parameters.length; i++)
137      parameterStrings[i] = 'parameters[' + i + ']';
138   
139    object.__apply__ = this;
140    var result = eval('object.__apply__(' + 
141      parameterStrings.join(', ') + ')');
142    object.__apply__ = null;
143   
144    return result;
145  }
146}
147
148Object.extend(String.prototype, {
149  stripTags: function() {
150    return this.replace(/<\/?[^>]+>/gi, '');
151  },
152
153  escapeHTML: function() {
154    var div = document.createElement('div');
155    var text = document.createTextNode(this);
156    div.appendChild(text);
157    return div.innerHTML;
158  },
159
160  unescapeHTML: function() {
161    var div = document.createElement('div');
162    div.innerHTML = this.stripTags();
163    return div.childNodes[0].nodeValue;
164  },
165 
166  parseQuery: function() {
167    var str = this;
168    if (str.substring(0,1) == '?') {
169      str = this.substring(1);
170    }
171    var result = {};
172    var pairs = str.split('&');
173    for (var i = 0; i < pairs.length; i++) {
174      var pair = pairs[i].split('=');
175      result[pair[0]] = pair[1];
176    }
177    return result;
178  }
179});
180
181
182var _break    = new Object();
183var _continue = new Object();
184
185var Enumerable = {
186  each: function(iterator) {
187    var index = 0;
188    try {
189      this._each(function(value) {
190        try {
191          iterator(value, index++);
192        } catch (e) {
193          if (e != _continue) throw e;
194        }
195      });
196    } catch (e) {
197      if (e != _break) throw e;
198    }
199  },
200 
201  all: function(iterator) {
202    var result = true;
203    this.each(function(value, index) {
204      if (!(result &= (iterator || Prototype.K)(value, index))) 
205        throw _break;
206    });
207    return result;
208  },
209 
210  any: function(iterator) {
211    var result = true;
212    this.each(function(value, index) {
213      if (result &= (iterator || Prototype.K)(value, index)) 
214        throw _break;
215    });
216    return result;
217  },
218 
219  collect: function(iterator) {
220    var results = [];
221    this.each(function(value, index) {
222      results.push(iterator(value, index));
223    });
224    return results;
225  },
226 
227  detect: function (iterator) {
228    var result;
229    this.each(function(value, index) {
230      if (iterator(value, index)) {
231        result = value;
232        throw _break;
233      }
234    });
235    return result;
236  },
237 
238  findAll: function(iterator) {
239    var results = [];
240    this.each(function(value, index) {
241      if (iterator(value, index))
242        results.push(value);
243    });
244    return results;
245  },
246 
247  grep: function(pattern, iterator) {
248    var results = [];
249    this.each(function(value, index) {
250      var stringValue = value.toString();
251      if (stringValue.match(pattern))
252        results.push((iterator || Prototype.K)(value, index));
253    })
254    return results;
255  },
256 
257  include: function(object) {
258    var found = false;
259    this.each(function(value) {
260      if (value == object) {
261        found = true;
262        throw _break;
263      }
264    });
265    return found;
266  },
267 
268  inject: function(memo, iterator) {
269    this.each(function(value, index) {
270      memo = iterator(memo, value, index);
271    });
272    return memo;
273  },
274 
275  invoke: function(method) {
276    var args = $A(arguments).slice(1);
277    return this.collect(function(value) {
278      return value[method].apply(value, args);
279    });
280  },
281 
282  max: function(iterator) {
283    var result;
284    this.each(function(value, index) {
285      value = (iterator || Prototype.K)(value, index);
286      if (value >= (result || value))
287        result = value;
288    });
289    return result;
290  },
291 
292  min: function(iterator) {
293    var result;
294    this.each(function(value, index) {
295      value = (iterator || Prototype.K)(value, index);
296      if (value <= (result || value))
297        result = value;
298    });
299    return result;
300  },
301 
302  partition: function(iterator) {
303    var trues = [], falses = [];
304    this.each(function(value, index) {
305      ((iterator || Prototype.K)(value, index) ? 
306        trues : falses).push(value);
307    });
308    return [trues, falses];
309  },
310 
311  pluck: function(property) {
312    var results = [];
313    this.each(function(value, index) {
314      results.push(value[property]);
315    });
316    return results;
317  },
318 
319  reject: function(iterator) {
320    var results = [];
321    this.each(function(value, index) {
322      if (!iterator(value, index))
323        results.push(value);
324    });
325    return results;
326  },
327 
328  sortBy: function(iterator) {
329    return this.collect(function(value, index) {
330      return {value: value, criteria: iterator(value, index)};
331    }).sort(function(left, right) {
332      var a = left.criteria, b = right.criteria;
333      return a < b ? -1 : a > b ? 1 : 0;
334    }).pluck('value');
335  },
336 
337  toArray: function() {
338    return this.collect(Prototype.K);
339  },
340 
341  zip: function() {
342    var iterator = Prototype.K, args = $A(arguments);
343    if (typeof args.last() == 'function')
344      iterator = args.pop();
345
346    var collections = [this].concat(args).map($A);
347    return this.map(function(value, index) {
348      iterator(value = collections.pluck(index));
349      return value;
350    });
351  }
352}
353
354Object.extend(Enumerable, {
355  map:     Enumerable.collect,
356  find:    Enumerable.detect,
357  select:  Enumerable.findAll,
358  member:  Enumerable.include,
359  entries: Enumerable.toArray
360});
361
362$A = Array.from = function(iterable) {
363  var results = [];
364  for (var i = 0; i < iterable.length; i++)
365    results.push(iterable[i]);
366  return results;
367}
368
369Object.extend(Array.prototype, {
370  _each: function(iterator) {
371    for (var i = 0; i < this.length; i++)
372      iterator(this[i]);
373  },
374 
375  first: function() {
376    return this[0];
377  },
378 
379  last: function() {
380    return this[this.length - 1];
381  }
382});
383
384Object.extend(Array.prototype, Enumerable);
385
386
387var Ajax = {
388  getTransport: function() {
389    return Try.these(
390      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
391      function() {return new ActiveXObject('Microsoft.XMLHTTP')},
392      function() {return new XMLHttpRequest()}
393    ) || false;
394  }
395}
396
397Ajax.Base = function() {};
398Ajax.Base.prototype = {
399  setOptions: function(options) {
400    this.options = {
401      method:       'post',
402      asynchronous: true,
403      parameters:   ''
404    }
405    Object.extend(this.options, options || {});
406  },
407
408  responseIsSuccess: function() {
409    return this.transport.status == undefined
410        || this.transport.status == 0 
411        || (this.transport.status >= 200 && this.transport.status < 300);
412  },
413
414  responseIsFailure: function() {
415    return !this.responseIsSuccess();
416  }
417}
418
419Ajax.Request = Class.create();
420Ajax.Request.Events = 
421  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];
422
423Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
424  initialize: function(url, options) {
425    this.transport = Ajax.getTransport();
426    this.setOptions(options);
427    this.request(url);
428  },
429
430  request: function(url) {
431    var parameters = this.options.parameters || '';
432    if (parameters.length > 0) parameters += '&_=';
433
434    try {
435      if (this.options.method == 'get')
436        url += '?' + parameters;
437
438      this.transport.open(this.options.method, url,
439        this.options.asynchronous);
440
441      if (this.options.asynchronous) {
442        this.transport.onreadystatechange = this.onStateChange.bind(this);
443        setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
444      }
445
446      this.setRequestHeaders();
447
448      var body = this.options.postBody ? this.options.postBody : parameters;
449      this.transport.send(this.options.method == 'post' ? body : null);
450
451    } catch (e) {
452    }
453  },
454
455  setRequestHeaders: function() {
456    var requestHeaders = 
457      ['X-Requested-With', 'XMLHttpRequest',
458       'X-Prototype-Version', Prototype.Version];
459
460    if (this.options.method == 'post') {
461      requestHeaders.push('Content-type', 
462        'application/x-www-form-urlencoded');
463
464      /* Force "Connection: close" for Mozilla browsers to work around
465       * a bug where XMLHttpReqeuest sends an incorrect Content-length
466       * header. See Mozilla Bugzilla #246651.
467       */
468      if (this.transport.overrideMimeType)
469        requestHeaders.push('Connection', 'close');
470    }
471
472    if (this.options.requestHeaders)
473      requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);
474
475    for (var i = 0; i < requestHeaders.length; i += 2)
476      this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
477  },
478
479  onStateChange: function() {
480    var readyState = this.transport.readyState;
481    if (readyState != 1)
482      this.respondToReadyState(this.transport.readyState);
483  },
484
485  respondToReadyState: function(readyState) {
486    var event = Ajax.Request.Events[readyState];
487
488    if (event == 'Complete')
489      (this.options['on' + this.transport.status]
490       || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
491       || Prototype.emptyFunction)(this.transport);
492
493    (this.options['on' + event] || Prototype.emptyFunction)(this.transport);
494
495    /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
496    if (event == 'Complete')
497      this.transport.onreadystatechange = Prototype.emptyFunction;
498  }
499});
500
501Ajax.Updater = Class.create();
502Ajax.Updater.ScriptFragment = '(?:<script.*?>)((\n|.)*?)(?:<\/script>)';
503
504Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
505  initialize: function(container, url, options) {
506    this.containers = {
507      success: container.success ? $(container.success) : $(container),
508      failure: container.failure ? $(container.failure) :
509        (container.success ? null : $(container))
510    }
511
512    this.transport = Ajax.getTransport();
513    this.setOptions(options);
514
515    var onComplete = this.options.onComplete || Prototype.emptyFunction;
516    this.options.onComplete = (function() {
517      this.updateContent();
518      onComplete(this.transport);
519    }).bind(this);
520
521    this.request(url);
522  },
523
524  updateContent: function() {
525    var receiver = this.responseIsSuccess() ?
526      this.containers.success : this.containers.failure;
527
528    var match    = new RegExp(Ajax.Updater.ScriptFragment, 'img');
529    var response = this.transport.responseText.replace(match, '');
530    var scripts  = this.transport.responseText.match(match);
531
532    if (receiver) {
533      if (this.options.insertion) {
534        new this.options.insertion(receiver, response);
535      } else {
536        receiver.innerHTML = response;
537      }
538    }
539
540    if (this.responseIsSuccess()) {
541      if (this.onComplete)
542        setTimeout((function() {this.onComplete(
543          this.transport)}).bind(this), 10);
544    }
545
546    if (this.options.evalScripts && scripts) {
547      match = new RegExp(Ajax.Updater.ScriptFragment, 'im');
548      setTimeout((function() {
549        for (var i = 0; i < scripts.length; i++)
550          eval(scripts[i].match(match)[1]);
551      }).bind(this), 10);
552    }
553  }
554});
555
556Ajax.PeriodicalUpdater = Class.create();
557Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
558  initialize: function(container, url, options) {
559    this.setOptions(options);
560    this.onComplete = this.options.onComplete;
561
562    this.frequency = (this.options.frequency || 2);
563    this.decay = 1;
564
565    this.updater = {};
566    this.container = container;
567    this.url = url;
568
569    this.start();
570  },
571
572  start: function() {
573    this.options.onComplete = this.updateComplete.bind(this);
574    this.onTimerEvent();
575  },
576
577  stop: function() {
578    this.updater.onComplete = undefined;
579    clearTimeout(this.timer);
580    (this.onComplete || Ajax.emptyFunction).apply(this, arguments);
581  },
582
583  updateComplete: function(request) {
584    if (this.options.decay) {
585      this.decay = (request.responseText == this.lastText ? 
586        this.decay * this.options.decay : 1);
587
588      this.lastText = request.responseText;
589    }
590    this.timer = setTimeout(this.onTimerEvent.bind(this), 
591      this.decay * this.frequency * 1000);
592  },
593
594  onTimerEvent: function() {
595    this.updater = new Ajax.Updater(this.container, this.url, this.options);
596  }
597});
598
599document.getElementsByClassName = function(className) {
600  var children = document.getElementsByTagName('*') || document.all;
601  var elements = new Array();
602 
603  for (var i = 0; i < children.length; i++) {
604    var child = children[i];
605    var classNames = child.className.split(' ');
606    for (var j = 0; j < classNames.length; j++) {
607      if (classNames[j] == className) {
608        elements.push(child);
609        break;
610      }
611    }
612  }
613 
614  return elements;
615}
616
617/*--------------------------------------------------------------------------*/
618
619if (!window.Element) {
620  var Element = new Object();
621}
622
623Object.extend(Element, {
624  toggle: function() {
625    for (var i = 0; i < arguments.length; i++) {
626      var element = $(arguments[i]);
627      element.style.display = 
628        (element.style.display == 'none' ? '' : 'none');
629    }
630  },
631
632  hide: function() {
633    for (var i = 0; i < arguments.length; i++) {
634      var element = $(arguments[i]);
635      element.style.display = 'none';
636    }
637  },
638
639  show: function() {
640    for (var i = 0; i < arguments.length; i++) {
641      var element = $(arguments[i]);
642      element.style.display = '';
643    }
644  },
645
646  remove: function(element) {
647    element = $(element);
648    element.parentNode.removeChild(element);
649  },
650   
651  getHeight: function(element) {
652    element = $(element);
653    return element.offsetHeight; 
654  },
655
656  hasClassName: function(element, className) {
657    element = $(element);
658    if (!element)
659      return;
660    var a = element.className.split(' ');
661    for (var i = 0; i < a.length; i++) {
662      if (a[i] == className)
663        return true;
664    }
665    return false;
666  },
667
668  addClassName: function(element, className) {
669    element = $(element);
670    Element.removeClassName(element, className);
671    element.className += ' ' + className;
672  },
673
674  removeClassName: function(element, className) {
675    element = $(element);
676    if (!element)
677      return;
678    var newClassName = '';
679    var a = element.className.split(' ');
680    for (var i = 0; i < a.length; i++) {
681      if (a[i] != className) {
682        if (i > 0)
683          newClassName += ' ';
684        newClassName += a[i];
685      }
686    }
687    element.className = newClassName;
688  },
689 
690  // removes whitespace-only text node children
691  cleanWhitespace: function(element) {
692    var element = $(element);
693    for (var i = 0; i < element.childNodes.length; i++) {
694      var node = element.childNodes[i];
695      if (node.nodeType == 3 && !/\S/.test(node.nodeValue)) 
696        Element.remove(node);
697    }
698  }
699});
700
701var Toggle = new Object();
702Toggle.display = Element.toggle;
703
704/*--------------------------------------------------------------------------*/
705
706Abstract.Insertion = function(adjacency) {
707  this.adjacency = adjacency;
708}
709
710Abstract.Insertion.prototype = {
711  initialize: function(element, content) {
712    this.element = $(element);
713    this.content = content;
714   
715    if (this.adjacency && this.element.insertAdjacentHTML) {
716      this.element.insertAdjacentHTML(this.adjacency, this.content);
717    } else {
718      this.range = this.element.ownerDocument.createRange();
719      if (this.initializeRange) this.initializeRange();
720      this.fragment = this.range.createContextualFragment(this.content);
721      this.insertContent();
722    }
723  }
724}
725
726var Insertion = new Object();
727
728Insertion.Before = Class.create();
729Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
730  initializeRange: function() {
731    this.range.setStartBefore(this.element);
732  },
733 
734  insertContent: function() {
735    this.element.parentNode.insertBefore(this.fragment, this.element);
736  }
737});
738
739Insertion.Top = Class.create();
740Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
741  initializeRange: function() {
742    this.range.selectNodeContents(this.element);
743    this.range.collapse(true);
744  },
745 
746  insertContent: function() { 
747    this.element.insertBefore(this.fragment, this.element.firstChild);
748  }
749});
750
751Insertion.Bottom = Class.create();
752Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
753  initializeRange: function() {
754    this.range.selectNodeContents(this.element);
755    this.range.collapse(this.element);
756  },
757 
758  insertContent: function() {
759    this.element.appendChild(this.fragment);
760  }
761});
762
763Insertion.After = Class.create();
764Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
765  initializeRange: function() {
766    this.range.setStartAfter(this.element);
767  },
768 
769  insertContent: function() {
770    this.element.parentNode.insertBefore(this.fragment, 
771      this.element.nextSibling);
772  }
773});
774
775var Field = {
776  clear: function() {
777    for (var i = 0; i < arguments.length; i++)
778      $(arguments[i]).value = '';
779  },
780
781  focus: function(element) {
782    $(element).focus();
783  },
784 
785  present: function() {
786    for (var i = 0; i < arguments.length; i++)
787      if ($(arguments[i]).value == '') return false;
788    return true;
789  },
790 
791  select: function(element) {
792    $(element).select();
793  },
794   
795  activate: function(element) {
796    $(element).focus();
797    $(element).select();
798  }
799}
800
801/*--------------------------------------------------------------------------*/
802
803var Form = {
804  serialize: function(form) {
805    var elements = Form.getElements($(form));
806    var queryComponents = new Array();
807   
808    for (var i = 0; i < elements.length; i++) {
809      var queryComponent = Form.Element.serialize(elements[i]);
810      if (queryComponent)
811        queryComponents.push(queryComponent);
812    }
813   
814    return queryComponents.join('&');
815  },
816 
817  getElements: function(form) {
818    var form = $(form);
819    var elements = new Array();
820
821    for (tagName in Form.Element.Serializers) {
822      var tagElements = form.getElementsByTagName(tagName);
823      for (var j = 0; j < tagElements.length; j++)
824        elements.push(tagElements[j]);
825    }
826    return elements;
827  },
828 
829  getInputs: function(form, typeName, name) {
830    var form = $(form);
831    var inputs = form.getElementsByTagName('input');
832   
833    if (!typeName && !name)
834      return inputs;
835     
836    var matchingInputs = new Array();
837    for (var i = 0; i < inputs.length; i++) {
838      var input = inputs[i];
839      if ((typeName && input.type != typeName) ||
840          (name && input.name != name)) 
841        continue;
842      matchingInputs.push(input);
843    }
844
845    return matchingInputs;
846  },
847
848  disable: function(form) {
849    var elements = Form.getElements(form);
850    for (var i = 0; i < elements.length; i++) {
851      var element = elements[i];
852      element.blur();
853      element.disabled = 'true';
854    }
855  },
856
857  enable: function(form) {
858    var elements = Form.getElements(form);
859    for (var i = 0; i < elements.length; i++) {
860      var element = elements[i];
861      element.disabled = '';
862    }
863  },
864
865  focusFirstElement: function(form) {
866    var form = $(form);
867    var elements = Form.getElements(form);
868    for (var i = 0; i < elements.length; i++) {
869      var element = elements[i];
870      if (element.type != 'hidden' && !element.disabled) {
871        Field.activate(element);
872        break;
873      }
874    }
875  },
876
877  reset: function(form) {
878    $(form).reset();
879  }
880}
881
882Form.Element = {
883  serialize: function(element) {
884    var element = $(element);
885    var method = element.tagName.toLowerCase();
886    var parameter = Form.Element.Serializers[method](element);
887   
888    if (parameter)
889      return encodeURIComponent(parameter[0]) + '=' + 
890        encodeURIComponent(parameter[1]);                   
891  },
892 
893  getValue: function(element) {
894    var element = $(element);
895    var method = element.tagName.toLowerCase();
896    var parameter = Form.Element.Serializers[method](element);
897   
898    if (parameter) 
899      return parameter[1];
900  }
901}
902
903Form.Element.Serializers = {
904  input: function(element) {
905    switch (element.type.toLowerCase()) {
906      case 'submit':
907      case 'hidden':
908      case 'password':
909      case 'text':
910        return Form.Element.Serializers.textarea(element);
911      case 'checkbox': 
912      case 'radio':
913        return Form.Element.Serializers.inputSelector(element);
914    }
915    return false;
916  },
917
918  inputSelector: function(element) {
919    if (element.checked)
920      return [element.name, element.value];
921  },
922
923  textarea: function(element) {
924    return [element.name, element.value];
925  },
926
927  select: function(element) {
928    var value = '';
929    if (element.type == 'select-one') {
930      var index = element.selectedIndex;
931      if (index >= 0)
932        value = element.options[index].value || element.options[index].text;
933    } else {
934      value = new Array();
935      for (var i = 0; i < element.length; i++) {
936        var opt = element.options[i];
937        if (opt.selected)
938          value.push(opt.value || opt.text);
939      }
940    }
941    return [element.name, value];
942  }
943}
944
945/*--------------------------------------------------------------------------*/
946
947var $F = Form.Element.getValue;
948
949/*--------------------------------------------------------------------------*/
950
951Abstract.TimedObserver = function() {}
952Abstract.TimedObserver.prototype = {
953  initialize: function(element, frequency, callback) {
954    this.frequency = frequency;
955    this.element   = $(element);
956    this.callback  = callback;
957   
958    this.lastValue = this.getValue();
959    this.registerCallback();
960  },
961 
962  registerCallback: function() {
963    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
964  },
965 
966  onTimerEvent: function() {
967    var value = this.getValue();
968    if (this.lastValue != value) {
969      this.callback(this.element, value);
970      this.lastValue = value;
971    }
972  }
973}
974
975Form.Element.Observer = Class.create();
976Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
977  getValue: function() {
978    return Form.Element.getValue(this.element);
979  }
980});
981
982Form.Observer = Class.create();
983Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
984  getValue: function() {
985    return Form.serialize(this.element);
986  }
987});
988
989/*--------------------------------------------------------------------------*/
990
991Abstract.EventObserver = function() {}
992Abstract.EventObserver.prototype = {
993  initialize: function(element, callback) {
994    this.element  = $(element);
995    this.callback = callback;
996   
997    this.lastValue = this.getValue();
998    if (this.element.tagName.toLowerCase() == 'form')
999      this.registerFormCallbacks();
1000    else
1001      this.registerCallback(this.element);
1002  },
1003 
1004  onElementEvent: function() {
1005    var value = this.getValue();
1006    if (this.lastValue != value) {
1007      this.callback(this.element, value);
1008      this.lastValue = value;
1009    }
1010  },
1011 
1012  registerFormCallbacks: function() {
1013    var elements = Form.getElements(this.element);
1014    for (var i = 0; i < elements.length; i++)
1015      this.registerCallback(elements[i]);
1016  },
1017 
1018  registerCallback: function(element) {
1019    if (element.type) {
1020      switch (element.type.toLowerCase()) {
1021        case 'checkbox': 
1022        case 'radio':
1023          element.target = this;
1024          element.prev_onclick = element.onclick || Prototype.emptyFunction;
1025          element.onclick = function() {
1026            this.prev_onclick(); 
1027            this.target.onElementEvent();
1028          }
1029          break;
1030        case 'password':
1031        case 'text':
1032        case 'textarea':
1033        case 'select-one':
1034        case 'select-multiple':
1035          element.target = this;
1036          element.prev_onchange = element.onchange || Prototype.emptyFunction;
1037          element.onchange = function() {
1038            this.prev_onchange(); 
1039            this.target.onElementEvent();
1040          }
1041          break;
1042      }
1043    }   
1044  }
1045}
1046
1047Form.Element.EventObserver = Class.create();
1048Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
1049  getValue: function() {
1050    return Form.Element.getValue(this.element);
1051  }
1052});
1053
1054Form.EventObserver = Class.create();
1055Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
1056  getValue: function() {
1057    return Form.serialize(this.element);
1058  }
1059});
1060
1061
1062if (!window.Event) {
1063  var Event = new Object();
1064}
1065
1066Object.extend(Event, {
1067  KEY_BACKSPACE: 8,
1068  KEY_TAB:       9,
1069  KEY_RETURN:   13,
1070  KEY_ESC:      27,
1071  KEY_LEFT:     37,
1072  KEY_UP:       38,
1073  KEY_RIGHT:    39,
1074  KEY_DOWN:     40,
1075  KEY_DELETE:   46,
1076
1077  element: function(event) {
1078    return event.target || event.srcElement;
1079  },
1080
1081  isLeftClick: function(event) {
1082    return (((event.which) && (event.which == 1)) ||
1083            ((event.button) && (event.button == 1)));
1084  },
1085
1086  pointerX: function(event) {
1087    return event.pageX || (event.clientX + 
1088      (document.documentElement.scrollLeft || document.body.scrollLeft));
1089  },
1090
1091  pointerY: function(event) {
1092    return event.pageY || (event.clientY + 
1093      (document.documentElement.scrollTop || document.body.scrollTop));
1094  },
1095
1096  stop: function(event) {
1097    if (event.preventDefault) { 
1098      event.preventDefault(); 
1099      event.stopPropagation(); 
1100    } else {
1101      event.returnValue = false;
1102    }
1103  },
1104
1105  // find the first node with the given tagName, starting from the
1106  // node the event was triggered on; traverses the DOM upwards
1107  findElement: function(event, tagName) {
1108    var element = Event.element(event);
1109    while (element.parentNode && (!element.tagName ||
1110        (element.tagName.toUpperCase() != tagName.toUpperCase())))
1111      element = element.parentNode;
1112    return element;
1113  },
1114
1115  observers: false,
1116 
1117  _observeAndCache: function(element, name, observer, useCapture) {
1118    if (!this.observers) this.observers = [];
1119    if (element.addEventListener) {
1120      this.observers.push([element, name, observer, useCapture]);
1121      element.addEventListener(name, observer, useCapture);
1122    } else if (element.attachEvent) {
1123      this.observers.push([element, name, observer, useCapture]);
1124      element.attachEvent('on' + name, observer);
1125    }
1126  },
1127 
1128  unloadCache: function() {
1129    if (!Event.observers) return;
1130    for (var i = 0; i < Event.observers.length; i++) {
1131      Event.stopObserving.apply(this, Event.observers[i]);
1132      Event.observers[i][0] = null;
1133    }
1134    Event.observers = false;
1135  },
1136
1137  observe: function(element, name, observer, useCapture) {
1138    var element = $(element);
1139    useCapture = useCapture || false;
1140   
1141    if (name == 'keypress' &&
1142        ((/Konqueror|Safari|KHTML/.test(navigator.userAgent)) 
1143        || element.attachEvent))
1144      name = 'keydown';
1145   
1146    this._observeAndCache(element, name, observer, useCapture);
1147  },
1148
1149  stopObserving: function(element, name, observer, useCapture) {
1150    var element = $(element);
1151    useCapture = useCapture || false;
1152   
1153    if (name == 'keypress' &&
1154        ((/Konqueror|Safari|KHTML/.test(navigator.userAgent)) 
1155        || element.detachEvent))
1156      name = 'keydown';
1157   
1158    if (element.removeEventListener) {
1159      element.removeEventListener(name, observer, useCapture);
1160    } else if (element.detachEvent) {
1161      element.detachEvent('on' + name, observer);
1162    }
1163  }
1164});
1165
1166/* prevent memory leaks in IE */
1167Event.observe(window, 'unload', Event.unloadCache, false);
1168
1169var Position = {
1170
1171  // set to true if needed, warning: firefox performance problems
1172  // NOT neeeded for page scrolling, only if draggable contained in
1173  // scrollable elements
1174  includeScrollOffsets: false, 
1175
1176  // must be called before calling withinIncludingScrolloffset, every time the
1177  // page is scrolled
1178  prepare: function() {
1179    this.deltaX =  window.pageXOffset 
1180                || document.documentElement.scrollLeft 
1181                || document.body.scrollLeft 
1182                || 0;
1183    this.deltaY =  window.pageYOffset 
1184                || document.documentElement.scrollTop 
1185                || document.body.scrollTop 
1186                || 0;
1187  },
1188
1189  realOffset: function(element) {
1190    var valueT = 0, valueL = 0;
1191    do {
1192      valueT += element.scrollTop  || 0;
1193      valueL += element.scrollLeft || 0; 
1194      element = element.parentNode;
1195    } while (element);
1196    return [valueL, valueT];
1197  },
1198
1199  cumulativeOffset: function(element) {
1200    var valueT = 0, valueL = 0;
1201    do {
1202      valueT += element.offsetTop  || 0;
1203      valueL += element.offsetLeft || 0;
1204      element = element.offsetParent;
1205    } while (element);
1206    return [valueL, valueT];
1207  },
1208
1209  // caches x/y coordinate pair to use with overlap
1210  within: function(element, x, y) {
1211    if (this.includeScrollOffsets)
1212      return this.withinIncludingScrolloffsets(element, x, y);
1213    this.xcomp = x;
1214    this.ycomp = y;
1215    this.offset = this.cumulativeOffset(element);
1216
1217    return (y >= this.offset[1] &&
1218            y <  this.offset[1] + element.offsetHeight &&
1219            x >= this.offset[0] && 
1220            x <  this.offset[0] + element.offsetWidth);
1221  },
1222
1223  withinIncludingScrolloffsets: function(element, x, y) {
1224    var offsetcache = this.realOffset(element);
1225
1226    this.xcomp = x + offsetcache[0] - this.deltaX;
1227    this.ycomp = y + offsetcache[1] - this.deltaY;
1228    this.offset = this.cumulativeOffset(element);
1229
1230    return (this.ycomp >= this.offset[1] &&
1231            this.ycomp <  this.offset[1] + element.offsetHeight &&
1232            this.xcomp >= this.offset[0] && 
1233            this.xcomp <  this.offset[0] + element.offsetWidth);
1234  },
1235
1236  // within must be called directly before
1237  overlap: function(mode, element) { 
1238    if (!mode) return 0; 
1239    if (mode == 'vertical') 
1240      return ((this.offset[1] + element.offsetHeight) - this.ycomp) / 
1241        element.offsetHeight;
1242    if (mode == 'horizontal')
1243      return ((this.offset[0] + element.offsetWidth) - this.xcomp) / 
1244        element.offsetWidth;
1245  },
1246
1247  clone: function(source, target) {
1248    source = $(source);
1249    target = $(target);
1250    target.style.position = 'absolute';
1251    var offsets = this.cumulativeOffset(source);
1252    target.style.top    = offsets[1] + 'px';
1253    target.style.left   = offsets[0] + 'px';
1254    target.style.width  = source.offsetWidth + 'px';
1255    target.style.height = source.offsetHeight + 'px';
1256  }
1257}
Note: See TracBrowser for help on using the repository browser.