| OLD | NEW |
| (Empty) |
| 1 // Copyright 2005 Google | |
| 2 // | |
| 3 // Functions that handle the DOM. Partly, these merely wrap methods in | |
| 4 // DOM interfaces in order to allow them to be obfuscated. Partly, | |
| 5 // they wrap cross browser differences, and partly they provide | |
| 6 // functionality beyond what is available directly in the DOM. | |
| 7 | |
| 8 | |
| 9 // These constants will be condensed away by jscompiler, other than | |
| 10 // the corresponding properties of Node. Based on | |
| 11 // <http://www.w3.org/TR/2000/ REC-DOM-Level-2-Core-20001113/ | |
| 12 // core.html#ID-1950641247>. | |
| 13 var DOM_ELEMENT_NODE = 1; | |
| 14 var DOM_ATTRIBUTE_NODE = 2; | |
| 15 var DOM_TEXT_NODE = 3; | |
| 16 var DOM_CDATA_SECTION_NODE = 4; | |
| 17 var DOM_ENTITY_REFERENCE_NODE = 5; | |
| 18 var DOM_ENTITY_NODE = 6; | |
| 19 var DOM_PROCESSING_INSTRUCTION_NODE = 7; | |
| 20 var DOM_COMMENT_NODE = 8; | |
| 21 var DOM_DOCUMENT_NODE = 9; | |
| 22 var DOM_DOCUMENT_TYPE_NODE = 10; | |
| 23 var DOM_DOCUMENT_FRAGMENT_NODE = 11; | |
| 24 var DOM_NOTATION_NODE = 12; | |
| 25 | |
| 26 /** | |
| 27 * Traverses the element nodes in the DOM tree underneath the given | |
| 28 * node and finds the first node with elemId, or null if there is no such | |
| 29 * element. Traversal is in depth-first order. | |
| 30 * | |
| 31 * NOTE: The reason this is not combined with the elem() function is | |
| 32 * that the implementations are different. | |
| 33 * elem() is a wrapper for the built-in document.getElementById() function, | |
| 34 * whereas this function performs the traversal itself. | |
| 35 * Modifying elem() to take an optional root node is a possibility, | |
| 36 * but the in-built function would perform better than using our own traversal. | |
| 37 * | |
| 38 * @param {Element} node Root element of subtree to traverse. | |
| 39 * @param {String} elemId The id of the element to search for. | |
| 40 * @return {Element|Null} The corresponding element, or null if not found. | |
| 41 */ | |
| 42 function nodeGetElementById(node, elemId) { | |
| 43 for (var c = node.firstChild; c; c = c.nextSibling) { | |
| 44 if (c.id == elemId) { | |
| 45 return c; | |
| 46 } | |
| 47 if (c.nodeType == DOM_ELEMENT_NODE) { | |
| 48 var n = arguments.callee.call(this, c, elemId); | |
| 49 if (n) { | |
| 50 return n; | |
| 51 } | |
| 52 } | |
| 53 } | |
| 54 return null; | |
| 55 } | |
| 56 | |
| 57 // These wrapper functions make the underlying Node methods condense | |
| 58 // better: the wrapper function can be condensed by the compiler, | |
| 59 // while the method cannot. | |
| 60 | |
| 61 /** | |
| 62 * Get an attribute from the DOM. Simple redirect, exists to compress code. | |
| 63 * | |
| 64 * @param {Element} node Element to interrogate. | |
| 65 * @param {String} name Name of parameter to extract. | |
| 66 * @return {String} Resulting attribute. | |
| 67 */ | |
| 68 function domGetAttribute(node, name) { | |
| 69 return node.getAttribute(name); | |
| 70 // NOTE: Neither in IE nor in Firefox, HTML DOM attributes | |
| 71 // implement namespaces. All items in the attribute collection have | |
| 72 // null localName and namespaceURI attribute values. In IE, we even | |
| 73 // encounter DIV elements that don't implement the method | |
| 74 // getAttributeNS(). | |
| 75 } | |
| 76 | |
| 77 /** | |
| 78 * Set an attribute in the DOM. Simple redirect to compress code. | |
| 79 * | |
| 80 * @param {Element} node Element to interrogate. | |
| 81 * @param {String} name Name of parameter to set. | |
| 82 * @param {String} value Set attribute to this value. | |
| 83 */ | |
| 84 function domSetAttribute(node, name, value) { | |
| 85 node.setAttribute(name, value); | |
| 86 } | |
| 87 | |
| 88 /** | |
| 89 * Remove an attribute from the DOM. Simple redirect to compress code. | |
| 90 * | |
| 91 * @param {Element} node Element to interrogate. | |
| 92 * @param {String} name Name of parameter to remove. | |
| 93 */ | |
| 94 function domRemoveAttribute(node, name) { | |
| 95 node.removeAttribute(name); | |
| 96 } | |
| 97 | |
| 98 /** | |
| 99 * Clone a node in the DOM. | |
| 100 * | |
| 101 * @param {Node} node Node to clone. | |
| 102 * @return {Node} Cloned node. | |
| 103 */ | |
| 104 function domCloneNode(node) { | |
| 105 return node.cloneNode(true); | |
| 106 // NOTE: we never so far wanted to use cloneNode(false), | |
| 107 // hence the default. | |
| 108 } | |
| 109 | |
| 110 | |
| 111 /** | |
| 112 * Return a safe string for the className of a node. | |
| 113 * If className is not a string, returns "". | |
| 114 * | |
| 115 * @param {Element} node DOM element to query. | |
| 116 * @return {String} | |
| 117 */ | |
| 118 function domClassName(node) { | |
| 119 return node.className ? "" + node.className : ""; | |
| 120 } | |
| 121 | |
| 122 /** | |
| 123 * Adds a class name to the class attribute of the given node. | |
| 124 * | |
| 125 * @param {Element} node DOM element to modify. | |
| 126 * @param {String} className Class name to add. | |
| 127 */ | |
| 128 function domAddClass(node, className) { | |
| 129 var name = domClassName(node); | |
| 130 if (name) { | |
| 131 var cn = name.split(/\s+/); | |
| 132 var found = false; | |
| 133 for (var i = 0; i < jsLength(cn); ++i) { | |
| 134 if (cn[i] == className) { | |
| 135 found = true; | |
| 136 break; | |
| 137 } | |
| 138 } | |
| 139 | |
| 140 if (!found) { | |
| 141 cn.push(className); | |
| 142 } | |
| 143 | |
| 144 node.className = cn.join(' '); | |
| 145 } else { | |
| 146 node.className = className; | |
| 147 } | |
| 148 } | |
| 149 | |
| 150 /** | |
| 151 * Removes a class name from the class attribute of the given node. | |
| 152 * | |
| 153 * @param {Element} node DOM element to modify. | |
| 154 * @param {String} className Class name to remove. | |
| 155 */ | |
| 156 function domRemoveClass(node, className) { | |
| 157 // Don't touch the class name if we won't find anything to change | |
| 158 // anyway. | |
| 159 var c = domClassName(node); | |
| 160 if (!c || c.indexOf(className) == -1) { | |
| 161 return; | |
| 162 } | |
| 163 var cn = c.split(/\s+/); | |
| 164 for (var i = 0; i < jsLength(cn); ++i) { | |
| 165 if (cn[i] == className) { | |
| 166 cn.splice(i--, 1); | |
| 167 } | |
| 168 } | |
| 169 node.className = cn.join(' '); | |
| 170 } | |
| 171 | |
| 172 /** | |
| 173 * Checks if a node belongs to a style class. | |
| 174 * | |
| 175 * @param {Element} node DOM element to test. | |
| 176 * @param {String} className Class name to check for. | |
| 177 * @return {Boolean} Node belongs to style class. | |
| 178 */ | |
| 179 function domTestClass(node, className) { | |
| 180 var cn = domClassName(node).split(/\s+/); | |
| 181 for (var i = 0; i < jsLength(cn); ++i) { | |
| 182 if (cn[i] == className) { | |
| 183 return true; | |
| 184 } | |
| 185 } | |
| 186 return false; | |
| 187 } | |
| 188 | |
| 189 /** | |
| 190 * Inserts a new child before a given sibling. | |
| 191 * | |
| 192 * @param {Node} newChild Node to insert. | |
| 193 * @param {Node} oldChild Sibling node. | |
| 194 * @return {Node} Reference to new child. | |
| 195 */ | |
| 196 function domInsertBefore(newChild, oldChild) { | |
| 197 return oldChild.parentNode.insertBefore(newChild, oldChild); | |
| 198 } | |
| 199 | |
| 200 /** | |
| 201 * Appends a new child to the specified (parent) node. | |
| 202 * | |
| 203 * @param {Element} node Parent element. | |
| 204 * @param {Node} child Child node to append. | |
| 205 * @return {Node} Newly appended node. | |
| 206 */ | |
| 207 function domAppendChild(node, child) { | |
| 208 return node.appendChild(child); | |
| 209 } | |
| 210 | |
| 211 /** | |
| 212 * Remove a new child from the specified (parent) node. | |
| 213 * | |
| 214 * @param {Element} node Parent element. | |
| 215 * @param {Node} child Child node to remove. | |
| 216 * @return {Node} Removed node. | |
| 217 */ | |
| 218 function domRemoveChild(node, child) { | |
| 219 return node.removeChild(child); | |
| 220 } | |
| 221 | |
| 222 /** | |
| 223 * Replaces an old child node with a new child node. | |
| 224 * | |
| 225 * @param {Node} newChild New child to append. | |
| 226 * @param {Node} oldChild Old child to remove. | |
| 227 * @return {Node} Replaced node. | |
| 228 */ | |
| 229 function domReplaceChild(newChild, oldChild) { | |
| 230 return oldChild.parentNode.replaceChild(newChild, oldChild); | |
| 231 } | |
| 232 | |
| 233 /** | |
| 234 * Removes a node from the DOM. | |
| 235 * | |
| 236 * @param {Node} node The node to remove. | |
| 237 * @return {Node} The removed node. | |
| 238 */ | |
| 239 function domRemoveNode(node) { | |
| 240 return domRemoveChild(node.parentNode, node); | |
| 241 } | |
| 242 | |
| 243 /** | |
| 244 * Creates a new text node in the given document. | |
| 245 * | |
| 246 * @param {Document} doc Target document. | |
| 247 * @param {String} text Text composing new text node. | |
| 248 * @return {Text} Newly constructed text node. | |
| 249 */ | |
| 250 function domCreateTextNode(doc, text) { | |
| 251 return doc.createTextNode(text); | |
| 252 } | |
| 253 | |
| 254 /** | |
| 255 * Creates a new node in the given document | |
| 256 * | |
| 257 * @param {Document} doc Target document. | |
| 258 * @param {String} name Name of new element (i.e. the tag name).. | |
| 259 * @return {Element} Newly constructed element. | |
| 260 */ | |
| 261 function domCreateElement(doc, name) { | |
| 262 return doc.createElement(name); | |
| 263 } | |
| 264 | |
| 265 /** | |
| 266 * Creates a new attribute in the given document. | |
| 267 * | |
| 268 * @param {Document} doc Target document. | |
| 269 * @param {String} name Name of new attribute. | |
| 270 * @return {Attr} Newly constructed attribute. | |
| 271 */ | |
| 272 function domCreateAttribute(doc, name) { | |
| 273 return doc.createAttribute(name); | |
| 274 } | |
| 275 | |
| 276 /** | |
| 277 * Creates a new comment in the given document. | |
| 278 * | |
| 279 * @param {Document} doc Target document. | |
| 280 * @param {String} text Comment text. | |
| 281 * @return {Comment} Newly constructed comment. | |
| 282 */ | |
| 283 function domCreateComment(doc, text) { | |
| 284 return doc.createComment(text); | |
| 285 } | |
| 286 | |
| 287 /** | |
| 288 * Creates a document fragment. | |
| 289 * | |
| 290 * @param {Document} doc Target document. | |
| 291 * @return {DocumentFragment} Resulting document fragment node. | |
| 292 */ | |
| 293 function domCreateDocumentFragment(doc) { | |
| 294 return doc.createDocumentFragment(); | |
| 295 } | |
| 296 | |
| 297 /** | |
| 298 * Redirect to document.getElementById | |
| 299 * | |
| 300 * @param {Document} doc Target document. | |
| 301 * @param {String} id Id of requested node. | |
| 302 * @return {Element|Null} Resulting element. | |
| 303 */ | |
| 304 function domGetElementById(doc, id) { | |
| 305 return doc.getElementById(id); | |
| 306 } | |
| 307 | |
| 308 /** | |
| 309 * Redirect to window.setInterval | |
| 310 * | |
| 311 * @param {Window} win Target window. | |
| 312 * @param {Function} fun Callback function. | |
| 313 * @param {Number} time Time in milliseconds. | |
| 314 * @return {Object} Contract id. | |
| 315 */ | |
| 316 function windowSetInterval(win, fun, time) { | |
| 317 return win.setInterval(fun, time); | |
| 318 } | |
| 319 | |
| 320 /** | |
| 321 * Redirect to window.clearInterval | |
| 322 * | |
| 323 * @param {Window} win Target window. | |
| 324 * @param {object} id Contract id. | |
| 325 * @return {any} NOTE: Return type unknown? | |
| 326 */ | |
| 327 function windowClearInterval(win, id) { | |
| 328 return win.clearInterval(id); | |
| 329 } | |
| 330 | |
| 331 /** | |
| 332 * Determines whether one node is recursively contained in another. | |
| 333 * @param parent The parent node. | |
| 334 * @param child The node to look for in parent. | |
| 335 * @return parent recursively contains child | |
| 336 */ | |
| 337 function containsNode(parent, child) { | |
| 338 while (parent != child && child.parentNode) { | |
| 339 child = child.parentNode; | |
| 340 } | |
| 341 return parent == child; | |
| 342 }; | |
| OLD | NEW |