| /* |
| * Element Traversal methods from Juriy Zaytsev (kangax) |
| * used to emulate Prototype up/down/previous/next methods |
| */ |
| |
| (function(D){ |
| |
| // TODO: all of this needs tests |
| var match = D.match, select = D.select, root = document.documentElement, |
| |
| // Use the Element Traversal API if available. |
| nextElement = 'nextElementSibling', |
| previousElement = 'previousElementSibling', |
| parentElement = 'parentElement'; |
| |
| // Fall back to the DOM Level 1 API. |
| if (!(nextElement in root)) nextElement = 'nextSibling'; |
| if (!(previousElement in root)) previousElement = 'previousSibling'; |
| if (!(parentElement in root)) parentElement = 'parentNode'; |
| |
| function walkElements(property, element, expr) { |
| var i = 0, isIndex = typeof expr == 'number'; |
| if (typeof expr == 'undefined') { |
| isIndex = true; |
| expr = 0; |
| } |
| while ((element = element[property])) { |
| if (element.nodeType != 1) continue; |
| if (isIndex) { |
| ++i; |
| if (i == expr) return element; |
| } else if (match(element, expr)) { |
| return element; |
| } |
| } |
| return null; |
| } |
| |
| /** |
| * @method up |
| * @param {HTMLElement} element element to walk from |
| * @param {String | Number} expr CSS expression or an index |
| * @return {HTMLElement | null} |
| */ |
| function up(element, expr) { |
| return walkElements(parentElement, element, expr); |
| } |
| /** |
| * @method next |
| * @param {HTMLElement} element element to walk from |
| * @param {String | Number} expr CSS expression or an index |
| * @return {HTMLElement | null} |
| */ |
| function next(element, expr) { |
| return walkElements(nextElement, element, expr); |
| } |
| /** |
| * @method previous |
| * @param {HTMLElement} element element to walk from |
| * @param {String | Number} expr CSS expression or an index |
| * @return {HTMLElement | null} |
| */ |
| function previous(element, expr) { |
| return walkElements(previousElement, element, expr); |
| } |
| /** |
| * @method down |
| * @param {HTMLElement} element element to walk from |
| * @param {String | Number} expr CSS expression or an index |
| * @return {HTMLElement | null} |
| */ |
| function down(element, expr) { |
| var isIndex = typeof expr == 'number', descendants, index, descendant; |
| if (expr === null) { |
| element = element.firstChild; |
| while (element && element.nodeType != 1) element = element[nextElement]; |
| return element; |
| } |
| if (!isIndex && match(element, expr) || isIndex && expr === 0) return element; |
| descendants = select('*', element); |
| if (isIndex) return descendants[expr] || null; |
| index = 0; |
| while ((descendant = descendants[index]) && !match(descendant, expr)) { ++index; } |
| return descendant || null; |
| } |
| D.up = up; |
| D.down = down; |
| D.next = next; |
| D.previous = previous; |
| })(NW.Dom); |