util.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. /* A few useful utility functions. */
  2. // Capture a method on an object.
  3. function method(obj, name) {
  4. return function() {obj[name].apply(obj, arguments);};
  5. }
  6. // The value used to signal the end of a sequence in iterators.
  7. var StopIteration = {toString: function() {return "StopIteration"}};
  8. // Apply a function to each element in a sequence.
  9. function forEach(iter, f) {
  10. if (iter.next) {
  11. try {while (true) f(iter.next());}
  12. catch (e) {if (e != StopIteration) throw e;}
  13. }
  14. else {
  15. for (var i = 0; i < iter.length; i++)
  16. f(iter[i]);
  17. }
  18. }
  19. // Map a function over a sequence, producing an array of results.
  20. function map(iter, f) {
  21. var accum = [];
  22. forEach(iter, function(val) {accum.push(f(val));});
  23. return accum;
  24. }
  25. // Create a predicate function that tests a string againsts a given
  26. // regular expression. No longer used but might be used by 3rd party
  27. // parsers.
  28. function matcher(regexp){
  29. return function(value){return regexp.test(value);};
  30. }
  31. // Test whether a DOM node has a certain CSS class.
  32. function hasClass(element, className) {
  33. var classes = element.className;
  34. return classes && new RegExp("(^| )" + className + "($| )").test(classes);
  35. }
  36. function removeClass(element, className) {
  37. element.className = element.className.replace(new RegExp(" " + className + "\\b", "g"), "");
  38. return element;
  39. }
  40. // Insert a DOM node after another node.
  41. function insertAfter(newNode, oldNode) {
  42. var parent = oldNode.parentNode;
  43. parent.insertBefore(newNode, oldNode.nextSibling);
  44. return newNode;
  45. }
  46. function removeElement(node) {
  47. if (node.parentNode)
  48. node.parentNode.removeChild(node);
  49. }
  50. function clearElement(node) {
  51. while (node.firstChild)
  52. node.removeChild(node.firstChild);
  53. }
  54. // Check whether a node is contained in another one.
  55. function isAncestor(node, child) {
  56. while (child = child.parentNode) {
  57. if (node == child)
  58. return true;
  59. }
  60. return false;
  61. }
  62. // The non-breaking space character.
  63. var nbsp = "\u00a0";
  64. var matching = {"{": "}", "[": "]", "(": ")",
  65. "}": "{", "]": "[", ")": "("};
  66. // Standardize a few unportable event properties.
  67. function normalizeEvent(event) {
  68. if (!event.stopPropagation) {
  69. event.stopPropagation = function() {this.cancelBubble = true;};
  70. event.preventDefault = function() {this.returnValue = false;};
  71. }
  72. if (!event.stop) {
  73. event.stop = function() {
  74. this.stopPropagation();
  75. this.preventDefault();
  76. };
  77. }
  78. if (event.type == "keypress") {
  79. event.code = (event.charCode == null) ? event.keyCode : event.charCode;
  80. event.character = String.fromCharCode(event.code);
  81. }
  82. return event;
  83. }
  84. // Portably register event handlers.
  85. function addEventHandler(node, type, handler, removeFunc) {
  86. function wrapHandler(event) {
  87. handler(normalizeEvent(event || window.event));
  88. }
  89. if (typeof node.addEventListener == "function") {
  90. node.addEventListener(type, wrapHandler, false);
  91. if (removeFunc) return function() {node.removeEventListener(type, wrapHandler, false);};
  92. }
  93. else {
  94. node.attachEvent("on" + type, wrapHandler);
  95. if (removeFunc) return function() {node.detachEvent("on" + type, wrapHandler);};
  96. }
  97. }
  98. function nodeText(node) {
  99. return node.textContent || node.innerText || node.nodeValue || "";
  100. }
  101. function nodeTop(node) {
  102. var top = 0;
  103. while (node.offsetParent) {
  104. top += node.offsetTop;
  105. node = node.offsetParent;
  106. }
  107. return top;
  108. }
  109. function isBR(node) {
  110. var nn = node.nodeName;
  111. return nn == "BR" || nn == "br";
  112. }
  113. function isSpan(node) {
  114. var nn = node.nodeName;
  115. return nn == "SPAN" || nn == "span";
  116. }