1 /* A few useful utility functions. */
3 var internetExplorer = document.selection && window.ActiveXObject && /MSIE/.test(navigator.userAgent);
4 var webkit = /AppleWebKit/.test(navigator.userAgent);
5 var safari = /Apple Computers, Inc/.test(navigator.vendor);
7 // Capture a method on an object.
8 function method(obj, name) {
9 return function() {obj[name].apply(obj, arguments);};
12 // The value used to signal the end of a sequence in iterators.
13 var StopIteration = {toString: function() {return "StopIteration"}};
15 // Apply a function to each element in a sequence.
16 function forEach(iter, f) {
18 try {while (true) f(iter.next());}
19 catch (e) {if (e != StopIteration) throw e;}
22 for (var i = 0; i < iter.length; i++)
27 // Map a function over a sequence, producing an array of results.
28 function map(iter, f) {
30 forEach(iter, function(val) {accum.push(f(val));});
34 // Create a predicate function that tests a string againsts a given
35 // regular expression. No longer used but might be used by 3rd party
37 function matcher(regexp){
38 return function(value){return regexp.test(value);};
41 // Test whether a DOM node has a certain CSS class. Much faster than
42 // the MochiKit equivalent, for some reason.
43 function hasClass(element, className){
44 var classes = element.className;
45 return classes && new RegExp("(^| )" + className + "($| )").test(classes);
48 // Insert a DOM node after another node.
49 function insertAfter(newNode, oldNode) {
50 var parent = oldNode.parentNode;
51 parent.insertBefore(newNode, oldNode.nextSibling);
55 function removeElement(node) {
57 node.parentNode.removeChild(node);
60 function clearElement(node) {
61 while (node.firstChild)
62 node.removeChild(node.firstChild);
65 // Check whether a node is contained in another one.
66 function isAncestor(node, child) {
67 while (child = child.parentNode) {
74 // The non-breaking space character.
76 var matching = {"{": "}", "[": "]", "(": ")",
77 "}": "{", "]": "[", ")": "("};
79 // Standardize a few unportable event properties.
80 function normalizeEvent(event) {
81 if (!event.stopPropagation) {
82 event.stopPropagation = function() {this.cancelBubble = true;};
83 event.preventDefault = function() {this.returnValue = false;};
86 event.stop = function() {
87 this.stopPropagation();
88 this.preventDefault();
92 if (event.type == "keypress") {
93 event.code = (event.charCode == null) ? event.keyCode : event.charCode;
94 event.character = String.fromCharCode(event.code);
99 // Portably register event handlers.
100 function addEventHandler(node, type, handler, removeFunc) {
101 function wrapHandler(event) {
102 handler(normalizeEvent(event || window.event));
104 if (typeof node.addEventListener == "function") {
105 node.addEventListener(type, wrapHandler, false);
106 if (removeFunc) return function() {node.removeEventListener(type, wrapHandler, false);};
109 node.attachEvent("on" + type, wrapHandler);
110 if (removeFunc) return function() {node.detachEvent("on" + type, wrapHandler);};
114 function nodeText(node) {
115 return node.innerText || node.textContent || node.nodeValue || "";