PageRenderTime 48ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/ajax/scripts/dom.js

http://showslow.googlecode.com/
JavaScript | 355 lines | 290 code | 43 blank | 22 comment | 137 complexity | cb091a4428f4b2f297c16e8d8860b55a MD5 | raw file
  1. /*==================================================
  2. * DOM Utility Functions
  3. *==================================================
  4. */
  5. SimileAjax.DOM = new Object();
  6. SimileAjax.DOM.registerEventWithObject = function(elmt, eventName, obj, handlerName) {
  7. SimileAjax.DOM.registerEvent(elmt, eventName, function(elmt2, evt, target) {
  8. return obj[handlerName].call(obj, elmt2, evt, target);
  9. });
  10. };
  11. SimileAjax.DOM.registerEvent = function(elmt, eventName, handler) {
  12. var handler2 = function(evt) {
  13. evt = (evt) ? evt : ((event) ? event : null);
  14. if (evt) {
  15. var target = (evt.target) ?
  16. evt.target : ((evt.srcElement) ? evt.srcElement : null);
  17. if (target) {
  18. target = (target.nodeType == 1 || target.nodeType == 9) ?
  19. target : target.parentNode;
  20. }
  21. return handler(elmt, evt, target);
  22. }
  23. return true;
  24. }
  25. if (SimileAjax.Platform.browser.isIE) {
  26. elmt.attachEvent("on" + eventName, handler2);
  27. } else {
  28. elmt.addEventListener(eventName, handler2, false);
  29. }
  30. };
  31. SimileAjax.DOM.getPageCoordinates = function(elmt) {
  32. var left = 0;
  33. var top = 0;
  34. if (elmt.nodeType != 1) {
  35. elmt = elmt.parentNode;
  36. }
  37. var elmt2 = elmt;
  38. while (elmt2 != null) {
  39. left += elmt2.offsetLeft;
  40. top += elmt2.offsetTop;
  41. elmt2 = elmt2.offsetParent;
  42. }
  43. var body = document.body;
  44. while (elmt != null && elmt != body) {
  45. if ("scrollLeft" in elmt) {
  46. left -= elmt.scrollLeft;
  47. top -= elmt.scrollTop;
  48. }
  49. elmt = elmt.parentNode;
  50. }
  51. return { left: left, top: top };
  52. };
  53. SimileAjax.DOM.getSize = function(elmt) {
  54. var w = this.getStyle(elmt,"width");
  55. var h = this.getStyle(elmt,"height");
  56. if (w.indexOf("px") > -1) w = w.replace("px","");
  57. if (h.indexOf("px") > -1) h = h.replace("px","");
  58. return {
  59. w: w,
  60. h: h
  61. }
  62. }
  63. SimileAjax.DOM.getStyle = function(elmt, styleProp) {
  64. if (elmt.currentStyle) { // IE
  65. var style = elmt.currentStyle[styleProp];
  66. } else if (window.getComputedStyle) { // standard DOM
  67. var style = document.defaultView.getComputedStyle(elmt, null).getPropertyValue(styleProp);
  68. } else {
  69. var style = "";
  70. }
  71. return style;
  72. }
  73. SimileAjax.DOM.getEventRelativeCoordinates = function(evt, elmt) {
  74. if (SimileAjax.Platform.browser.isIE) {
  75. if (evt.type == "mousewheel") {
  76. var coords = SimileAjax.DOM.getPageCoordinates(elmt);
  77. return {
  78. x: evt.clientX - coords.left,
  79. y: evt.clientY - coords.top
  80. };
  81. } else {
  82. return {
  83. x: evt.offsetX,
  84. y: evt.offsetY
  85. };
  86. }
  87. } else {
  88. var coords = SimileAjax.DOM.getPageCoordinates(elmt);
  89. if ((evt.type == "DOMMouseScroll") &&
  90. SimileAjax.Platform.browser.isFirefox &&
  91. (SimileAjax.Platform.browser.majorVersion == 2)) {
  92. // Due to: https://bugzilla.mozilla.org/show_bug.cgi?id=352179
  93. return {
  94. x: evt.screenX - coords.left,
  95. y: evt.screenY - coords.top
  96. };
  97. } else {
  98. return {
  99. x: evt.pageX - coords.left,
  100. y: evt.pageY - coords.top
  101. };
  102. }
  103. }
  104. };
  105. SimileAjax.DOM.getEventPageCoordinates = function(evt) {
  106. if (SimileAjax.Platform.browser.isIE) {
  107. var scrOfY = 0;
  108. var scrOfX = 0;
  109. if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
  110. //DOM compliant
  111. scrOfY = document.body.scrollTop;
  112. scrOfX = document.body.scrollLeft;
  113. } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
  114. //IE6 standards compliant mode
  115. scrOfY = document.documentElement.scrollTop;
  116. scrOfX = document.documentElement.scrollLeft;
  117. }
  118. return { x: evt.clientX + scrOfX, y: evt.clientY + scrOfY };
  119. } else {
  120. return {
  121. x: evt.pageX,
  122. y: evt.pageY
  123. };
  124. }
  125. };
  126. SimileAjax.DOM.hittest = function(x, y, except) {
  127. return SimileAjax.DOM._hittest(document.body, x, y, except);
  128. };
  129. SimileAjax.DOM._hittest = function(elmt, x, y, except) {
  130. var childNodes = elmt.childNodes;
  131. outer: for (var i = 0; i < childNodes.length; i++) {
  132. var childNode = childNodes[i];
  133. for (var j = 0; j < except.length; j++) {
  134. if (childNode == except[j]) {
  135. continue outer;
  136. }
  137. }
  138. if (childNode.offsetWidth == 0 && childNode.offsetHeight == 0) {
  139. /*
  140. * Sometimes SPAN elements have zero width and height but
  141. * they have children like DIVs that cover non-zero areas.
  142. */
  143. var hitNode = SimileAjax.DOM._hittest(childNode, x, y, except);
  144. if (hitNode != childNode) {
  145. return hitNode;
  146. }
  147. } else {
  148. var top = 0;
  149. var left = 0;
  150. var node = childNode;
  151. while (node) {
  152. top += node.offsetTop;
  153. left += node.offsetLeft;
  154. node = node.offsetParent;
  155. }
  156. if (left <= x && top <= y && (x - left) < childNode.offsetWidth && (y - top) < childNode.offsetHeight) {
  157. return SimileAjax.DOM._hittest(childNode, x, y, except);
  158. } else if (childNode.nodeType == 1 && childNode.tagName == "TR") {
  159. /*
  160. * Table row might have cells that span several rows.
  161. */
  162. var childNode2 = SimileAjax.DOM._hittest(childNode, x, y, except);
  163. if (childNode2 != childNode) {
  164. return childNode2;
  165. }
  166. }
  167. }
  168. }
  169. return elmt;
  170. };
  171. SimileAjax.DOM.cancelEvent = function(evt) {
  172. evt.returnValue = false;
  173. evt.cancelBubble = true;
  174. if ("preventDefault" in evt) {
  175. evt.preventDefault();
  176. }
  177. };
  178. SimileAjax.DOM.appendClassName = function(elmt, className) {
  179. var classes = elmt.className.split(" ");
  180. for (var i = 0; i < classes.length; i++) {
  181. if (classes[i] == className) {
  182. return;
  183. }
  184. }
  185. classes.push(className);
  186. elmt.className = classes.join(" ");
  187. };
  188. SimileAjax.DOM.createInputElement = function(type) {
  189. var div = document.createElement("div");
  190. div.innerHTML = "<input type='" + type + "' />";
  191. return div.firstChild;
  192. };
  193. SimileAjax.DOM.createDOMFromTemplate = function(template) {
  194. var result = {};
  195. result.elmt = SimileAjax.DOM._createDOMFromTemplate(template, result, null);
  196. return result;
  197. };
  198. SimileAjax.DOM._createDOMFromTemplate = function(templateNode, result, parentElmt) {
  199. if (templateNode == null) {
  200. /*
  201. var node = doc.createTextNode("--null--");
  202. if (parentElmt != null) {
  203. parentElmt.appendChild(node);
  204. }
  205. return node;
  206. */
  207. return null;
  208. } else if (typeof templateNode != "object") {
  209. var node = document.createTextNode(templateNode);
  210. if (parentElmt != null) {
  211. parentElmt.appendChild(node);
  212. }
  213. return node;
  214. } else {
  215. var elmt = null;
  216. if ("tag" in templateNode) {
  217. var tag = templateNode.tag;
  218. if (parentElmt != null) {
  219. if (tag == "tr") {
  220. elmt = parentElmt.insertRow(parentElmt.rows.length);
  221. } else if (tag == "td") {
  222. elmt = parentElmt.insertCell(parentElmt.cells.length);
  223. }
  224. }
  225. if (elmt == null) {
  226. elmt = tag == "input" ?
  227. SimileAjax.DOM.createInputElement(templateNode.type) :
  228. document.createElement(tag);
  229. if (parentElmt != null) {
  230. parentElmt.appendChild(elmt);
  231. }
  232. }
  233. } else {
  234. elmt = templateNode.elmt;
  235. if (parentElmt != null) {
  236. parentElmt.appendChild(elmt);
  237. }
  238. }
  239. for (var attribute in templateNode) {
  240. var value = templateNode[attribute];
  241. if (attribute == "field") {
  242. result[value] = elmt;
  243. } else if (attribute == "className") {
  244. elmt.className = value;
  245. } else if (attribute == "id") {
  246. elmt.id = value;
  247. } else if (attribute == "title") {
  248. elmt.title = value;
  249. } else if (attribute == "type" && elmt.tagName == "input") {
  250. // do nothing
  251. } else if (attribute == "style") {
  252. for (n in value) {
  253. var v = value[n];
  254. if (n == "float") {
  255. n = SimileAjax.Platform.browser.isIE ? "styleFloat" : "cssFloat";
  256. }
  257. elmt.style[n] = v;
  258. }
  259. } else if (attribute == "children") {
  260. for (var i = 0; i < value.length; i++) {
  261. SimileAjax.DOM._createDOMFromTemplate(value[i], result, elmt);
  262. }
  263. } else if (attribute != "tag" && attribute != "elmt") {
  264. elmt.setAttribute(attribute, value);
  265. }
  266. }
  267. return elmt;
  268. }
  269. }
  270. SimileAjax.DOM._cachedParent = null;
  271. SimileAjax.DOM.createElementFromString = function(s) {
  272. if (SimileAjax.DOM._cachedParent == null) {
  273. SimileAjax.DOM._cachedParent = document.createElement("div");
  274. }
  275. SimileAjax.DOM._cachedParent.innerHTML = s;
  276. return SimileAjax.DOM._cachedParent.firstChild;
  277. };
  278. SimileAjax.DOM.createDOMFromString = function(root, s, fieldElmts) {
  279. var elmt = typeof root == "string" ? document.createElement(root) : root;
  280. elmt.innerHTML = s;
  281. var dom = { elmt: elmt };
  282. SimileAjax.DOM._processDOMChildrenConstructedFromString(dom, elmt, fieldElmts != null ? fieldElmts : {} );
  283. return dom;
  284. };
  285. SimileAjax.DOM._processDOMConstructedFromString = function(dom, elmt, fieldElmts) {
  286. var id = elmt.id;
  287. if (id != null && id.length > 0) {
  288. elmt.removeAttribute("id");
  289. if (id in fieldElmts) {
  290. var parentElmt = elmt.parentNode;
  291. parentElmt.insertBefore(fieldElmts[id], elmt);
  292. parentElmt.removeChild(elmt);
  293. dom[id] = fieldElmts[id];
  294. return;
  295. } else {
  296. dom[id] = elmt;
  297. }
  298. }
  299. if (elmt.hasChildNodes()) {
  300. SimileAjax.DOM._processDOMChildrenConstructedFromString(dom, elmt, fieldElmts);
  301. }
  302. };
  303. SimileAjax.DOM._processDOMChildrenConstructedFromString = function(dom, elmt, fieldElmts) {
  304. var node = elmt.firstChild;
  305. while (node != null) {
  306. var node2 = node.nextSibling;
  307. if (node.nodeType == 1) {
  308. SimileAjax.DOM._processDOMConstructedFromString(dom, node, fieldElmts);
  309. }
  310. node = node2;
  311. }
  312. };