/[webpac2]/Webpacus/root/js/prototype.js
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /Webpacus/root/js/prototype.js

Parent Directory Parent Directory | Revision Log Revision Log


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

  ViewVC Help
Powered by ViewVC 1.1.26