1 /* See license.txt for terms of usage */ 2 3 define([ 4 "firebug/lib/trace", 5 "firebug/lib/deprecated", 6 "firebug/lib/css", 7 "firebug/lib/array", 8 "firebug/lib/xml", 9 "firebug/lib/wrapper", 10 ], 11 function(FBTrace, Deprecated, Css, Arr, Xml, Wrapper) { 12 "use strict"; 13 14 // ********************************************************************************************* // 15 // Constants 16 17 var Ci = Components.interfaces; 18 var Cc = Components.classes; 19 20 /** 21 * @name Dom 22 * @lib Utility for Nodes 23 */ 24 var Dom = {}; 25 26 var domMemberCache = null; 27 var domMemberMap = {}; 28 var domMappedData = new WeakMap(); 29 30 Dom.domUtils = Cc["@mozilla.org/inspector/dom-utils;1"].getService(Ci.inIDOMUtils); 31 32 // ********************************************************************************************* // 33 // DOM APIs 34 35 // xxxFlorent: [SELECTOR_API2-FIND]; node.find() or document.querySelector + ":scope" pseudo-class 36 // could make this method deprecated soon. 37 // see also: 38 // - http://dev.w3.org/2006/webapi/selectors-api2/#findelements-relative 39 // - http://www.w3.org/TR/selectors-api2/#the-scope-pseudo-class 40 41 /** 42 * Selects the first child element which matches with the first classname, 43 * then the first child of it which matches with the second classname, and so on... 44 * 45 * @param {Element} elt The initial parent element 46 * @param {String} ...classnames the classnames 47 * 48 * @return {Element} the element matching with the last classname or null 49 */ 50 Dom.getChildByClass = function(elt/*, ...classnames*/) 51 { 52 if (!elt) 53 { 54 FBTrace.sysout("dom.getChildByClass; ERROR, no parent element!"); 55 return null; 56 } 57 58 for (var i = 1; i < arguments.length && elt; ++i) 59 { 60 var className = arguments[i]; 61 var child = elt.firstChild; 62 elt = null; 63 for (; child; child = child.nextSibling) 64 { 65 if (Css.hasClass(child, className)) 66 { 67 elt = child; 68 break; 69 } 70 } 71 } 72 73 return elt; 74 }; 75 76 /** 77 * Gets the ancestor of a node with a specific class name 78 * @param {Node} node Child node, for which to search the ancestor 79 * @param {String} className Class name of ancestor node 80 * @returns {Node} Ancestor node 81 */ 82 Dom.getAncestorByClass = function(node, className) 83 { 84 for (var parent = node; parent; parent = parent.parentNode) 85 { 86 if (Css.hasClass(parent, className)) 87 return parent; 88 } 89 90 return null; 91 }; 92 93 /** 94 * Gets the ancestor of a node with a specific tag name 95 * @param {Node} node Child node, for which to search the ancestor 96 * @param {String} tagName Tag name of the ancestor node 97 * @returns {Node} Ancestor node 98 */ 99 Dom.getAncestorByTagName = function(node, tagName) 100 { 101 for (var parent = node; parent; parent = parent.parentNode) 102 { 103 if (parent.localName && parent.tagName.toLowerCase() == tagName) 104 return parent; 105 } 106 107 return null; 108 }; 109 110 /** 111 * @deprecated Use native Firefox node.getElementsByClassName(names).item(0) 112 */ 113 Dom.getElementByClass = Deprecated.deprecated("Use node.getElementsByClassName(names)"+ 114 ".item(0) or node.querySelector('.class') instead", 115 function(node, className) // className, className, ... 116 { 117 return Dom.getElementsByClass.apply(this,arguments).item(0); 118 }); 119 120 /** 121 * @deprecated Use native Firefox node.getElementsByClassName(names) 122 */ 123 Dom.getElementsByClass = Deprecated.deprecated("Use node.getElementsByClassName(names)", 124 function(node, className) // className, className, ... 125 { 126 return node.getElementsByClassName(Array.prototype.slice.call(arguments, 1).join(" ")); 127 }); 128 129 /** 130 * @deprecated Use native Firefox node.getElementsByClassName("[attrName=attrValue]") 131 */ 132 Dom.getElementsByAttribute = Deprecated.deprecated("Use node.querySelectorAll(\"[attrName=attrValue]\") instead", 133 function(node, attrName, attrValue) 134 { 135 function iteratorHelper(node, attrName, attrValue, result) 136 { 137 for (var child = node.firstElementChild; child; child = child.nextElementSibling) 138 { 139 if (child.getAttribute(attrName) == attrValue) 140 result.push(child); 141 142 if (child.hasChildNodes()) 143 iteratorHelper(child, attrName, attrValue, result); 144 } 145 } 146 147 var result = []; 148 iteratorHelper(node, attrName, attrValue, result); 149 return result; 150 }); 151 152 /** 153 * Checks whether a node is an ancestor of another node 154 * @param {Node} node Child node, for which to check the ancestor 155 * @param {Node} potentialAncestor Node to check 156 * @returns {Boolean} True if 'potentialAncestor' is an ancestor of 'node', otherwise false 157 */ 158 Dom.isAncestor = function(node, potentialAncestor) 159 { 160 for (var parent = node; parent; parent = parent.parentNode) 161 { 162 if (parent == potentialAncestor) 163 return true; 164 } 165 166 return false; 167 }; 168 169 /** 170 * Gets the next element node 171 * @param {Node} node Node, for which to get the next element node 172 * @returns {Node} Next element node 173 */ 174 Dom.getNextElement = function(node) 175 { 176 while (node && node.nodeType != Node.ELEMENT_NODE) 177 node = node.nextSibling; 178 179 return node; 180 }; 181 182 /** 183 * Gets the previous element node 184 * @param {Node} node Node, for which to get the previous element node 185 * @returns {Node} Previous element node 186 */ 187 Dom.getPreviousElement = function(node) 188 { 189 while (node && node.nodeType != Node.ELEMENT_NODE) 190 node = node.previousSibling; 191 192 return node; 193 }; 194 195 /** 196 * Gets the body element of an HTML document or the document element for non-HTML documents 197 * @param {Document} doc Document, for which to get the body element or document element 198 * @returns {Node} Body element or document element 199 */ 200 Dom.getBody = function(doc) 201 { 202 if (doc.body) 203 return doc.body; 204 205 var body = doc.getElementsByTagName("body")[0]; 206 if (body) 207 return body; 208 209 return doc.documentElement; // For non-HTML docs 210 }; 211 212 // ********************************************************************************************* // 213 // DOM Modification 214 215 /** 216 * Insert the new node after the reference node. 217 * 218 * @param {Node} newNode The node to insert 219 * @param {Node} referenceNode The node after which we insert the new node 220 * 221 * @return {Node} the new node if the insertion succeeded 222 */ 223 Dom.insertAfter = function(newNode, referenceNode) 224 { 225 if (!referenceNode.parentNode) 226 return; 227 228 if (referenceNode.nextSibling) 229 return referenceNode.parentNode.insertBefore(newNode, referenceNode.nextSibling); 230 else 231 return referenceNode.parentNode.appendChild(newNode); 232 } 233 234 /** 235 * Insert a script element in the document 236 * 237 * @param {DocumentElement} doc The document 238 * @param {String} id The id of the script to insert 239 * @param {String} content The content of the script (evaluated once the script is inserted) 240 * 241 * @return {Element} the inserted script 242 */ 243 Dom.addScript = function(doc, id, src) 244 { 245 var element = doc.createElementNS("http://www.w3.org/1999/xhtml", "html:script"); 246 element.setAttribute("type", "text/javascript"); 247 element.setAttribute("id", id); 248 249 if (!FBTrace.DBG_CONSOLE) 250 Firebug.setIgnored(element); 251 252 element.textContent = src; 253 254 if (doc.documentElement) 255 { 256 doc.documentElement.appendChild(element); 257 } 258 else 259 { 260 // See issue 1079, the svg test case gives this error 261 if (FBTrace.DBG_ERRORS) 262 FBTrace.sysout("lib.addScript doc has no documentElement (" + 263 doc.readyState + ") " + doc.location, doc); 264 return; 265 } 266 return element; 267 } 268 269 /** 270 * Set the outerHTML of kind of element 271 * 272 * @deprecated since Firefox 20, we can use outerHTML instead, even for non-HTML elements 273 */ 274 Dom.setOuterHTML = Deprecated.deprecated("Since Firefox 20, use outerHTML instead, "+ 275 "even with non-HTML elements", function(element, html) 276 { 277 try 278 { 279 var fragment = Dom.markupToDocFragment(html, element); 280 281 var first = fragment.firstChild; 282 var last = fragment.lastChild; 283 element.parentNode.replaceChild(fragment, element); 284 return [first, last]; 285 } 286 catch (e) 287 { 288 return [element, element]; 289 } 290 }); 291 292 /** 293 * Converts a chunk of HTML code into DOM elements (stored in a document fragment) 294 * 295 * @param {String} markup The HTML code 296 * @param {Element} the Reference element (often the element which will receive the fragment) 297 * 298 * @return {DocumentFragment} the document fragment having the generated elements 299 */ 300 Dom.markupToDocFragment = function(markup, referenceElement) 301 { 302 var doc = referenceElement.ownerDocument; 303 var range = doc.createRange(); 304 range.selectNode(referenceElement || doc.documentElement); 305 306 return range.createContextualFragment(markup); 307 }; 308 309 Dom.appendInnerHTML = Deprecated.deprecated("Since Firefox 20, use "+ 310 "insertAdjacentHTML(\"beforeEnd\", html) instead, even with non-HTML elements", 311 function(element, html, referenceElement) 312 { 313 var firstGeneratedChild = null; 314 // using insertAdjacentHTML is safer for HTML elements: 315 if (element instanceof HTMLElement) 316 { 317 var lastChild = element.lastChild; 318 element.insertAdjacentHTML("beforeEnd", html); 319 firstGeneratedChild = (lastChild ? lastChild.nextSibling : element.firstChild); 320 } 321 else 322 { 323 var fragment = Dom.markupToDocFragment(html, referenceElement); 324 firstGeneratedChild = fragment.firstChild; 325 element.insertBefore(fragment, referenceElement); 326 } 327 return firstGeneratedChild; 328 }); 329 330 /** 331 * TODO... 332 */ 333 Dom.insertTextIntoElement = function(element, text) 334 { 335 // xxxFlorent: could this be replaced with the following code? : 336 // var textNode = element.ownerDocument.createTextNode(text); 337 // element.appendChild(text); 338 var command = "cmd_insertText"; 339 340 var controller = element.controllers.getControllerForCommand(command); 341 if (!controller || !controller.isCommandEnabled(command)) 342 return; 343 344 var params = Cc["@mozilla.org/embedcomp/command-params;1"].createInstance(Ci.nsICommandParams); 345 params.setStringValue("state_data", text); 346 347 if (controller instanceof Ci.nsICommandController) 348 controller.doCommandWithParams(command, params); 349 }; 350 351 // ********************************************************************************************* // 352 353 /** 354 * @deprecated 355 * xxxFlorent: hide XUL elements?? (TODO) 356 */ 357 Dom.collapse = function(elt, collapsed) 358 { 359 if (!elt) 360 { 361 FBTrace.sysout("Dom.collapse; ERROR null element."); 362 return; 363 } 364 365 elt.setAttribute("collapsed", collapsed ? "true" : "false"); 366 }; 367 368 /** 369 * @deprecated 370 * TODO 371 */ 372 Dom.isCollapsed = function(elt) 373 { 374 return elt.getAttribute("collapsed") === "true"; 375 }; 376 377 /** 378 * Hide or display an element 379 * 380 * @param {Element} elt The element 381 * @param {Boolean} hidden If set to true, hide the element, otherwise display it 382 * 383 * @deprecated set elt.style.visibility instead 384 */ 385 Dom.hide = Deprecated.deprecated("set elt.style.visibility instead", function(elt, hidden) 386 { 387 elt.style.visibility = (hidden ? "hidden" : "visible"); 388 }); 389 390 /** 391 * Clears a node 392 * 393 * @param {Node} node The node to clear 394 * 395 * @deprecated use the following instead: <code>node.textContent = "";</code> 396 */ 397 Dom.clearNode = Deprecated.deprecated("use the following instead: `node.textContent = \"\";`", 398 function(node) 399 { 400 node.textContent = ""; 401 }); 402 403 /** 404 * Erases a node 405 * 406 * @param {Node} the Node to erase 407 */ 408 Dom.eraseNode = function(node) 409 { 410 while (node.lastChild) 411 node.removeChild(node.lastChild); 412 }; 413 414 // ********************************************************************************************* // 415 416 /** 417 * Returns true if the passed object is a node 418 * 419 * @param {Object} obj The object to test 420 * 421 * @return {Boolean} true if the passed object is a node, false otherwise 422 */ 423 Dom.isNode = function(obj) 424 { 425 try 426 { 427 return obj && obj instanceof window.Node; 428 } 429 catch (ex) 430 { 431 // xxxFlorent: useful? 432 return false; 433 } 434 }; 435 // xxxFlorent: I'm too lazy... I guess we should deprecate them 436 Dom.isElement = function(o) 437 { 438 try { 439 return o && o instanceof window.Element; 440 } 441 catch (ex) { 442 return false; 443 } 444 }; 445 446 Dom.isRange = function(o) 447 { 448 try { 449 return o && o instanceof window.Range; 450 } 451 catch (ex) { 452 return false; 453 } 454 }; 455 456 Dom.hasChildElements = function(node) 457 { 458 if (node.contentDocument) // iframes 459 return true; 460 461 for (var child = node.firstChild; child; child = child.nextSibling) 462 { 463 if (child.nodeType == Node.ELEMENT_NODE) 464 return true; 465 } 466 467 return false; 468 }; 469 470 // ********************************************************************************************* // 471 // xxxFlorent: [SELECTOR_API2-FIND] 472 Dom.getNextByClass = function(root, state) 473 { 474 function iter(node) { return node.nodeType == Node.ELEMENT_NODE && Css.hasClass(node, state); } 475 return Dom.findNext(root, iter); 476 }; 477 478 // xxxFlorent: [SELECTOR_API2-FIND] 479 Dom.getPreviousByClass = function(root, state) 480 { 481 function iter(node) { return node.nodeType == Node.ELEMENT_NODE && Css.hasClass(node, state); } 482 return Dom.findPrevious(root, iter); 483 }; 484 485 Dom.findNextDown = function(node, criteria) 486 { 487 if (!node) 488 return null; 489 490 for (var child = node.firstChild; child; child = child.nextSibling) 491 { 492 if (criteria(child)) 493 return child; 494 495 var next = Dom.findNextDown(child, criteria); 496 if (next) 497 return next; 498 } 499 }; 500 501 Dom.findPreviousUp = function(node, criteria) 502 { 503 if (!node) 504 return null; 505 506 for (var child = node.lastChild; child; child = child.previousSibling) 507 { 508 var next = Dom.findPreviousUp(child, criteria); 509 if (next) 510 return next; 511 512 if (criteria(child)) 513 return child; 514 } 515 }; 516 517 Dom.findNext = function(node, criteria, upOnly, maxRoot) 518 { 519 if (!node) 520 return null; 521 522 if (!upOnly) 523 { 524 var next = Dom.findNextDown(node, criteria); 525 if (next) 526 return next; 527 } 528 529 for (var sib = node.nextSibling; sib; sib = sib.nextSibling) 530 { 531 if (criteria(sib)) 532 return sib; 533 534 var next = Dom.findNextDown(sib, criteria); 535 if (next) 536 return next; 537 } 538 539 if (node.parentNode && node.parentNode != maxRoot) 540 { 541 return Dom.findNext(node.parentNode, criteria, true, maxRoot); 542 } 543 return null; 544 }; 545 546 Dom.findPrevious = function(node, criteria, downOnly, maxRoot) 547 { 548 if (!node) 549 return null; 550 551 for (var sib = node.previousSibling; sib; sib = sib.previousSibling) 552 { 553 var prev = Dom.findPreviousUp(sib, criteria); 554 if (prev) 555 return prev; 556 557 if (criteria(sib)) 558 return sib; 559 } 560 561 if (!downOnly) 562 { 563 var next = Dom.findPreviousUp(node, criteria); 564 if (next) 565 return next; 566 } 567 568 if (node.parentNode && node.parentNode != maxRoot) 569 { 570 if (criteria(node.parentNode)) 571 return node.parentNode; 572 573 return Dom.findPrevious(node.parentNode, criteria, true, maxRoot); 574 } 575 return null; 576 }; 577 578 // ********************************************************************************************* // 579 // Graphics 580 581 Dom.getClientOffset = function(elt) 582 { 583 function addOffset(elt, coords, view) 584 { 585 var p = elt.offsetParent; 586 587 var style = view.getComputedStyle(elt, ""); 588 589 if (elt.offsetLeft) 590 coords.x += elt.offsetLeft + parseInt(style.borderLeftWidth); 591 if (elt.offsetTop) 592 coords.y += elt.offsetTop + parseInt(style.borderTopWidth); 593 594 if (p) 595 { 596 if (p.nodeType == Node.ELEMENT_NODE) 597 addOffset(p, coords, view); 598 } 599 else if (elt.ownerDocument.defaultView.frameElement) 600 { 601 addOffset(elt.ownerDocument.defaultView.frameElement, coords, 602 elt.ownerDocument.defaultView); 603 } 604 } 605 606 var coords = {x: 0, y: 0}; 607 if (elt) 608 { 609 var view = elt.ownerDocument.defaultView; 610 addOffset(elt, coords, view); 611 } 612 613 return coords; 614 }; 615 616 /** 617 * Gets layout info about an element 618 * @param {Object} elt Element to get the info for 619 * @returns {Object} Layout information including "left", "top", "right", "bottom", 620 * "width" and "height" 621 */ 622 Dom.getLTRBWH = function(elt) 623 { 624 var bcrect; 625 var dims = {"left": 0, "top": 0, "right": 0, "bottom": 0, "width": 0, "height": 0}; 626 627 if (elt) 628 { 629 bcrect = elt.getBoundingClientRect(); 630 dims.left = bcrect.left; 631 dims.top = bcrect.top; 632 dims.right = bcrect.right; 633 dims.bottom = bcrect.bottom; 634 635 if (bcrect.width) 636 { 637 dims.width = bcrect.width; 638 dims.height = bcrect.height; 639 } 640 else 641 { 642 dims.width = dims.right - dims.left; 643 dims.height = dims.bottom - dims.top; 644 } 645 } 646 return dims; 647 }; 648 649 /** 650 * Gets the offset size of an element 651 * @param {Object} elt Element to move 652 * @returns {Object} Offset width and height of the element 653 */ 654 Dom.getOffsetSize = function(elt) 655 { 656 return {width: elt.offsetWidth, height: elt.offsetHeight}; 657 }; 658 659 /** 660 * Gets the next scrollable ancestor 661 * @param {Object} element Element to search the ancestor for 662 * @returns {Object} Scrollable ancestor 663 */ 664 Dom.getOverflowParent = function(element) 665 { 666 for (var scrollParent = element.parentNode; scrollParent; 667 scrollParent = scrollParent.offsetParent) 668 { 669 if (scrollParent.scrollHeight > scrollParent.offsetHeight) 670 return scrollParent; 671 } 672 }; 673 674 /** 675 * Checks whether an element is scrolled to the bottom 676 * @param {Object} element Element to check 677 * @returns {Boolean} True, if element is scrolled to the bottom, otherwise false 678 */ 679 Dom.isScrolledToBottom = function(element) 680 { 681 var onBottom = (element.scrollTop + element.offsetHeight) == element.scrollHeight; 682 683 if (FBTrace.DBG_CONSOLE) 684 { 685 FBTrace.sysout("Dom.isScrolledToBottom offsetHeight: " + element.offsetHeight + 686 ", scrollTop: " + element.scrollTop + ", scrollHeight: " + element.scrollHeight + 687 ", onBottom: " + onBottom); 688 } 689 690 return onBottom; 691 }; 692 693 /** 694 * Scrolls a scrollable element to the bottom 695 * @param {Object} element Element to scroll 696 * @returns {Boolean} True, if the element could be scrolled to the bottom, otherwise false 697 */ 698 Dom.scrollToBottom = function(element) 699 { 700 element.scrollTop = element.scrollHeight; 701 702 if (FBTrace.DBG_CONSOLE) 703 { 704 FBTrace.sysout("scrollToBottom reset scrollTop " + element.scrollTop + " = " + 705 element.scrollHeight); 706 707 if (element.scrollHeight == element.offsetHeight) 708 { 709 FBTrace.sysout("scrollToBottom attempt to scroll non-scrollable element " + 710 element, element); 711 } 712 } 713 714 return (element.scrollTop == element.scrollHeight); 715 }; 716 717 /** 718 * Moves an element 719 * @param {Object} element Element to move 720 * @param {Number} x New horizontal position 721 * @param {Number} y New vertical position 722 */ 723 Dom.move = function(element, x, y) 724 { 725 element.style.left = x + "px"; 726 element.style.top = y + "px"; 727 }; 728 729 /** 730 * Resizes an element 731 * @param {Object} element Element to resize 732 * @param {Number} w New width 733 * @param {Number} h New height 734 */ 735 Dom.resize = function(element, w, h) 736 { 737 element.style.width = w + "px"; 738 element.style.height = h + "px"; 739 }; 740 741 Dom.linesIntoCenterView = function(element, scrollBox) // {before: int, after: int} 742 { 743 if (!scrollBox) 744 scrollBox = Dom.getOverflowParent(element); 745 746 if (!scrollBox) 747 return; 748 749 var offset = Dom.getClientOffset(element); 750 751 var topSpace = offset.y - scrollBox.scrollTop; 752 var bottomSpace = (scrollBox.scrollTop + scrollBox.clientHeight) - 753 (offset.y + element.offsetHeight); 754 755 if (topSpace < 0 || bottomSpace < 0) 756 { 757 var split = (scrollBox.clientHeight/2); 758 var centerY = offset.y - split; 759 scrollBox.scrollTop = centerY; 760 topSpace = split; 761 bottomSpace = split - element.offsetHeight; 762 } 763 764 return { 765 before: Math.round((topSpace/element.offsetHeight) + 0.5), 766 after: Math.round((bottomSpace/element.offsetHeight) + 0.5) 767 } 768 }; 769 770 // xxxFlorent: read the code and see if that could not be replaced with scrollIntoView 771 772 /** 773 * Scrolls an element into view 774 * @param {Element} element Element to scroll to 775 * @param {Object} scrollBox Scrolled element (Must be an ancestor of "element" or 776 * null for automatically determining the ancestor) 777 * @param {String} alignmentX Horizontal alignment for the element 778 * (valid values: "centerOrLeft", "left", "middle", "right", "none") 779 * @param {String} alignmentY Vertical alignment for the element 780 * (valid values: "centerOrTop", "top", "middle", "bottom", "none") 781 * @param {Boolean} scrollWhenVisible Specifies whether "scrollBox" should be scrolled even when 782 * "element" is completely visible 783 */ 784 Dom.scrollTo = function(element, scrollBox, alignmentX, alignmentY, scrollWhenVisible) 785 { 786 if (!element) 787 return; 788 789 if (!scrollBox) 790 scrollBox = Dom.getOverflowParent(element); 791 792 if (!scrollBox) 793 return; 794 795 var offset = Dom.getClientOffset(element); 796 797 if (!alignmentX) 798 alignmentX = "centerOrLeft"; 799 800 if (!alignmentY) 801 alignmentY = "centerOrTop"; 802 803 if (alignmentY) 804 { 805 var topSpace = offset.y - scrollBox.scrollTop; 806 var bottomSpace = (scrollBox.scrollTop + scrollBox.clientHeight) - 807 (offset.y + element.offsetHeight); 808 809 // Element is vertically not completely visible or scrolling is enforced 810 if (topSpace < 0 || bottomSpace < 0 || scrollWhenVisible) 811 { 812 switch (alignmentY) 813 { 814 case "top": 815 scrollBox.scrollTop = offset.y; 816 break; 817 818 case "center": 819 case "centerOrTop": 820 var elementFitsIntoScrollBox = element.offsetHeight <= scrollBox.clientHeight; 821 var y = elementFitsIntoScrollBox || alignmentY != "centerOrTop" ? 822 offset.y - (scrollBox.clientHeight - element.offsetHeight) / 2 : 823 offset.y; 824 scrollBox.scrollTop = y; 825 break; 826 827 case "bottom": 828 var y = offset.y + element.offsetHeight - scrollBox.clientHeight; 829 scrollBox.scrollTop = y; 830 break; 831 } 832 } 833 } 834 835 if (alignmentX) 836 { 837 var leftSpace = offset.x - scrollBox.scrollLeft; 838 var rightSpace = (scrollBox.scrollLeft + scrollBox.clientWidth) - 839 (offset.x + element.clientWidth); 840 841 // Element is horizontally not completely visible or scrolling is enforced 842 if (leftSpace < 0 || rightSpace < 0 || scrollWhenVisible) 843 { 844 switch (alignmentX) 845 { 846 case "left": 847 scrollBox.scrollLeft = offset.x; 848 break; 849 850 case "center": 851 case "centerOrLeft": 852 var elementFitsIntoScrollBox = element.offsetWidth <= scrollBox.clientWidth; 853 var x = elementFitsIntoScrollBox || alignmentX != "centerOrLeft" ? 854 offset.x - (scrollBox.clientWidth - element.offsetWidth) / 2 : 855 offset.x; 856 scrollBox.scrollLeft = x; 857 break; 858 859 case "right": 860 var x = offset.x + element.offsetWidth - scrollBox.clientWidth; 861 scrollBox.scrollLeft = x; 862 break; 863 } 864 } 865 } 866 867 if (FBTrace.DBG_PANELS) 868 FBTrace.sysout("dom.scrollTo", element.innerHTML); 869 }; 870 871 // xxxFlorent: read it (same as Dom.scrollTo) 872 873 /** 874 * Centers an element inside a scrollable area 875 * @param {Object} element Element to scroll to 876 * @param {Object} scrollBox Scrolled element (Must be an ancestor of "element" or 877 * null for automatically determining the ancestor) 878 * @param {Boolean} notX Specifies whether the element should be centered horizontally 879 * @param {Boolean} notY Specifies whether the element should be centered vertically 880 */ 881 Dom.scrollIntoCenterView = function(element, scrollBox, notX, notY) 882 { 883 Dom.scrollTo(element, scrollBox, notX ? "none" : "centerOrLeft", 884 notY ? "none" : "centerOrTop"); 885 }; 886 887 /** 888 * Scrolls an element of a menu popup into view. 889 * 890 * @popup {XULElement} the menu popup 891 * @item {XULElement} the item of the popup 892 */ 893 Dom.scrollMenupopup = function(popup, item) 894 { 895 var doc = popup.ownerDocument; 896 var box = doc.getAnonymousNodes(popup)[0]; 897 var scrollBox = doc.getAnonymousNodes(box)[1]; 898 899 if (item == undefined) 900 { 901 scrollBox.scrollTop = scrollBox.scrollHeight + 100; 902 } 903 else if (item == 0) 904 { 905 scrollBox.scrollTop = 0; 906 } 907 else 908 { 909 var popupRect = popup.getBoundingClientRect(); 910 var itemRect = item.getBoundingClientRect(); 911 912 if (itemRect.top < popupRect.top + itemRect.height) 913 { 914 scrollBox.scrollTop += itemRect.top - popupRect.top - itemRect.height; 915 } 916 else if (itemRect.bottom + itemRect.height > popupRect.bottom) 917 { 918 scrollBox.scrollTop -= popupRect.bottom - itemRect.bottom - itemRect.height; 919 } 920 } 921 } 922 923 // ********************************************************************************************* // 924 // MappedData 925 926 function getNodeData(element) 927 { 928 var elementData; 929 930 // force element to be wrapped: 931 element = new XPCNativeWrapper(element); 932 933 if (!domMappedData.has(element)) 934 { 935 elementData = {}; 936 domMappedData.set(element, elementData); 937 } 938 else 939 elementData = domMappedData.get(element); 940 941 return elementData; 942 } 943 944 /** 945 * Returns stored data about a node. 946 * 947 * @param {Node} node The node 948 * @param {*} key The key 949 * 950 * @return {*} the data 951 */ 952 Dom.getMappedData = function(node, key) 953 { 954 var nodeData = getNodeData(node); 955 return nodeData[key]; 956 } 957 958 /** 959 * Stores a data about the given node. 960 * 961 * @param {Node} node The node 962 * @param {*} key The key 963 * @param {*} value The data to store 964 * 965 */ 966 Dom.setMappedData = function(node, key, value) 967 { 968 if (!Dom.isNode(node)) 969 throw new TypeError("expected an node as the first argument"); 970 971 if (typeof key !== "string") 972 throw new TypeError("the key argument must be a string"); 973 974 var nodeData = getNodeData(node); 975 nodeData[key] = value; 976 } 977 978 /** 979 * Deletes the data about the given node. 980 * 981 * @param {Node} node The node 982 * @param {*} key The key 983 * 984 */ 985 Dom.deleteMappedData = function(node, key) 986 { 987 var nodeData = getNodeData(node); 988 delete nodeData[key]; 989 } 990 991 // ********************************************************************************************* // 992 // DOM Members 993 994 Dom.getDOMMembers = function(object) 995 { 996 if (!domMemberCache) 997 { 998 domMemberCache = {}; 999 1000 for (var name in domMemberMap) 1001 { 1002 var builtins = domMemberMap[name]; 1003 var cache = domMemberCache[name] = {}; 1004 1005 for (var i = 0; i < builtins.length; ++i) 1006 cache[builtins[i]] = i; 1007 } 1008 } 1009 1010 if (object instanceof Window) 1011 { return domMemberCache.Window; } 1012 else if (object instanceof Document || object instanceof XMLDocument) 1013 { return domMemberCache.Document; } 1014 else if (object instanceof Location) 1015 { return domMemberCache.Location; } 1016 else if (object instanceof HTMLImageElement) 1017 { return domMemberCache.HTMLImageElement; } 1018 else if (object instanceof HTMLAnchorElement) 1019 { return domMemberCache.HTMLAnchorElement; } 1020 else if (object instanceof HTMLInputElement) 1021 { return domMemberCache.HTMLInputElement; } 1022 else if (object instanceof HTMLButtonElement) 1023 { return domMemberCache.HTMLButtonElement; } 1024 else if (object instanceof HTMLFormElement) 1025 { return domMemberCache.HTMLFormElement; } 1026 else if (object instanceof HTMLBodyElement) 1027 { return domMemberCache.HTMLBodyElement; } 1028 else if (object instanceof HTMLHtmlElement) 1029 { return domMemberCache.HTMLHtmlElement; } 1030 else if (object instanceof HTMLScriptElement) 1031 { return domMemberCache.HTMLScriptElement; } 1032 else if (object instanceof HTMLTableElement) 1033 { return domMemberCache.HTMLTableElement; } 1034 else if (object instanceof HTMLTableRowElement) 1035 { return domMemberCache.HTMLTableRowElement; } 1036 else if (object instanceof HTMLTableCellElement) 1037 { return domMemberCache.HTMLTableCellElement; } 1038 else if (object instanceof HTMLIFrameElement) 1039 { return domMemberCache.HTMLIFrameElement; } 1040 else if (object instanceof SVGSVGElement) 1041 { return domMemberCache.SVGSVGElement; } 1042 else if (object instanceof SVGElement) 1043 { return domMemberCache.SVGElement; } 1044 else if (object instanceof Element) 1045 { return domMemberCache.Element; } 1046 else if (object instanceof Text || object instanceof CDATASection) 1047 { return domMemberCache.Text; } 1048 else if (object instanceof Attr) 1049 { return domMemberCache.Attr; } 1050 else if (object instanceof Node) 1051 { return domMemberCache.Node; } 1052 else if (object instanceof Event || object instanceof Dom.EventCopy) 1053 { return domMemberCache.Event; } 1054 else if (object instanceof Object) 1055 { return domMemberCache.Object; } 1056 1057 return null; 1058 }; 1059 1060 Dom.isDOMMember = function(object, propName) 1061 { 1062 var members = Dom.getDOMMembers(object); 1063 return members && propName in members; 1064 }; 1065 1066 Dom.isDOMConstant = function(object, name) 1067 { 1068 if (name == undefined) 1069 return Dom.isDOMConstantDep({},object); 1070 1071 // The constant map has also its own prototype, but it isn't considered to be a constant. 1072 if (name == "__proto__") 1073 return false; 1074 1075 // object isn't recognized as such when using ===, 1076 // so use this as workaround 1077 var str = Object.prototype.toString.call(object); 1078 var isDOMProperty = ["[object Window]", "[object Node]", "[object Location]", 1079 "[object Event]"].indexOf(str) !== -1; 1080 1081 if (!(object === window.Window || 1082 object === window.Object || 1083 object === window.Node || 1084 object === window.Location || 1085 object === window.Event || 1086 object === Dom.EventCopy || 1087 object instanceof window.Window || 1088 object instanceof window.Node || 1089 object instanceof window.Location || 1090 object instanceof window.Event || 1091 object instanceof Dom.EventCopy || 1092 isDOMProperty)) 1093 { 1094 return false; 1095 } 1096 1097 return Dom.domConstantMap.hasOwnProperty(name); 1098 } 1099 1100 Dom.isInlineEventHandler = function(name) 1101 { 1102 return !!Dom.domInlineEventHandlersMap[name]; 1103 } 1104 1105 Dom.EventCopy = function(event) 1106 { 1107 // ensure Dom.EventCopy is called as a constructor 1108 if (! (this instanceof Dom.EventCopy)) 1109 throw new Error("Dom.EventCopy is a constructor"); 1110 1111 // Because event objects are destroyed arbitrarily by Gecko, we must make a copy of them to 1112 // represent them long term in the inspector. 1113 for (var name in event) 1114 { 1115 try { 1116 this[name] = event[name]; 1117 } catch (exc) { } 1118 } 1119 } 1120 1121 var isDOMConstantDep = Deprecated.deprecated( 1122 "isDOMConstant(name) signature changed (object,name)", 1123 Dom.isDOMConstant); 1124 1125 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 1126 1127 domMemberMap.Window = 1128 [ 1129 "document", 1130 "frameElement", 1131 1132 "innerWidth", 1133 "innerHeight", 1134 "outerWidth", 1135 "outerHeight", 1136 "screenX", 1137 "screenY", 1138 "mozInnerScreenX", 1139 "mozInnerScreenY", 1140 "pageXOffset", 1141 "pageYOffset", 1142 "scrollX", 1143 "scrollY", 1144 "scrollMaxX", 1145 "scrollMaxY", 1146 1147 "URL", //FF4.0 1148 "mozAnimationStartTime", //FF4.0 1149 "mozPaintCount", //FF4.0 1150 "mozRequestAnimationFrame", //FF4.0 1151 "mozCancelAnimationFrame", 1152 "mozCancelRequestAnimationFrame", 1153 1154 "mozCancelAnimationFrame", 1155 "mozCancelRequestAnimationFrame", 1156 "indexedDB", 1157 1158 "status", 1159 "defaultStatus", 1160 1161 "parent", 1162 "opener", 1163 "top", 1164 "window", 1165 "content", 1166 "self", 1167 1168 "location", 1169 "history", 1170 "frames", 1171 "navigator", 1172 "screen", 1173 "menubar", 1174 "toolbar", 1175 "locationbar", 1176 "personalbar", 1177 "statusbar", 1178 "directories", 1179 "scrollbars", 1180 "fullScreen", 1181 "netscape", 1182 "console", 1183 "Components", 1184 "controllers", 1185 "closed", 1186 "crypto", 1187 "pkcs11", 1188 1189 "name", 1190 "property", 1191 "length", 1192 1193 "sessionStorage", 1194 1195 "setTimeout", 1196 "setInterval", 1197 "clearTimeout", 1198 "clearInterval", 1199 "addEventListener", 1200 "removeEventListener", 1201 "dispatchEvent", 1202 "getComputedStyle", 1203 "captureEvents", 1204 "releaseEvents", 1205 "routeEvent", 1206 "enableExternalCapture", 1207 "disableExternalCapture", 1208 "moveTo", 1209 "moveBy", 1210 "resizeTo", 1211 "resizeBy", 1212 "scroll", 1213 "scrollTo", 1214 "scrollBy", 1215 "scrollByLines", 1216 "scrollByPages", 1217 "sizeToContent", 1218 "setResizable", 1219 "getSelection", 1220 "open", 1221 "openDialog", 1222 "close", 1223 "alert", 1224 "confirm", 1225 "prompt", 1226 "dump", 1227 "focus", 1228 "blur", 1229 "find", 1230 "back", 1231 "forward", 1232 "home", 1233 "stop", 1234 "print", 1235 "atob", 1236 "btoa", 1237 "updateCommands", 1238 "XPCNativeWrapper", 1239 "GeckoActiveXObject", 1240 "applicationCache", // FF3 1241 "GetWeakReference", // Gecko 1242 "XPCSafeJSObjectWrapper", // Gecko 1243 "postMessage", 1244 "localStorage", // FF3.5 1245 "showModalDialog", // FF 3.0, MS IE4 1246 1247 "InstallTrigger", 1248 1249 "performance", // https://developer.mozilla.org/en/Navigation_timing 1250 "matchMedia", // https://developer.mozilla.org/en/DOM/window.matchMedia 1251 1252 "getInterface", 1253 1254 "BarProp", 1255 "Controllers", 1256 "Crypto", 1257 "DOMException", 1258 "DOMStringList", 1259 "EventTarget", 1260 "History", 1261 "MimeTypeArray", 1262 "MozURLProperty", 1263 "Navigator", 1264 "NodeList", 1265 "OfflineResourceList", 1266 "Screen", 1267 "Storage", 1268 "XULControllers", 1269 "Document", 1270 "Element", 1271 "Attr", 1272 "CharacterData", 1273 "DOMTokenList", 1274 "Text", 1275 1276 "HTMLAnchorElement", 1277 "HTMLAudioElement", 1278 "HTMLBaseElement", 1279 "HTMLButtonElement", 1280 "HTMLCollection", 1281 "HTMLCanvasElement", 1282 "HTMLDataListElement", 1283 "HTMLDListElement", 1284 "HTMLDocument", 1285 "HTMLElement", 1286 "HTMLEmbedElement", 1287 "HTMLHtmlElement", 1288 "HTMLBRElement", 1289 "HTMLBodyElement", 1290 "HTMLCollection", 1291 "HTMLDivElement", 1292 "HTMLDocument", 1293 "HTMLElement", 1294 "HTMLFormElement", 1295 "HTMLHRElement", 1296 "HTMLHeadElement", 1297 "HTMLHeadingElement", 1298 "HTMLHtmlElement", 1299 "HTMLIFrameElement", 1300 "HTMLImageElement", 1301 "HTMLInputElement", 1302 "HTMLLabelElement", 1303 "HTMLLegendElement", 1304 "HTMLLinkElement", 1305 "HTMLMapElement", 1306 "HTMLMediaElement", 1307 "HTMLMenuElement", 1308 "HTMLMetaElement", 1309 "HTMLMeterElement", 1310 "HTMLModElement", 1311 "HTMLObjectElement", 1312 "HTMLOListElement", 1313 "HTMLOptionElement", 1314 "HTMLOptionsCollection", 1315 "HTMLOutputElement", 1316 "HTMLPreElement", 1317 "HTMLProgressElement", 1318 "HTMLQuoteElement", 1319 "HTMLScriptElement", 1320 "HTMLSelectElement", 1321 "HTMLSourceElement", 1322 "HTMLSpanElement", 1323 "HTMLStyleElement", 1324 "HTMLTableCellElement", 1325 "HTMLTableElement", 1326 "HTMLTableRowElement", 1327 "HTMLTableSectionElement", 1328 "HTMLTextAreaElement", 1329 "HTMLTitleElement", 1330 "HTMLUListElement", 1331 "HTMLUnknownElement", 1332 "HTMLVideoElement", 1333 1334 "Infinity", 1335 "JSON", 1336 "Location", 1337 "Math", 1338 "NaN", 1339 "Node", 1340 "StopIteration", 1341 "Window", 1342 "XULElement", 1343 "undefined", 1344 "CSS2Properties", 1345 "CSSStyleDeclaration", 1346 "Error", 1347 "EvalError", 1348 "InternalError", 1349 "Namespace", 1350 "QName", 1351 "RangeError", 1352 "ReferenceError", 1353 "SyntaxError", 1354 "TypeError", 1355 "URIError", 1356 "Array", 1357 "ArrayBuffer", 1358 "Boolean", 1359 "DataView", 1360 "Date", 1361 "Float32Array", 1362 "Float64Array", 1363 "Function", 1364 "Int16Array", 1365 "Int32Array", 1366 "Int8Array", 1367 "Iterator", 1368 "Map", 1369 "Number", 1370 "Object", 1371 "ParallelArray", 1372 "QueryInterface", 1373 "RegExp", 1374 "Set", 1375 "String", 1376 "Uint16Array", 1377 "Uint32Array", 1378 "Uint8Array", 1379 "Uint8ClampedArray", 1380 "WeakMap", 1381 "XML", 1382 "XMLList", 1383 "decodeURI", 1384 "decodeURIComponent", 1385 "dumpProfile", 1386 "encodeURI", 1387 "encodeURIComponent", 1388 "escape", 1389 "isFinite", 1390 "isNaN", 1391 "isXMLName", 1392 "parseFloat", 1393 "parseInt", 1394 "pauseProfilers", 1395 "resumeProfilers", 1396 "startProfiling", 1397 "stopProfiling", 1398 "unescape", 1399 "uneval", 1400 "Performance", 1401 "PerformanceNavigation", 1402 "PerformanceTiming" 1403 ]; 1404 1405 domMemberMap.Object = 1406 [ 1407 "arguments", 1408 "caller", 1409 "length", 1410 "name", 1411 "__defineGetter__", 1412 "__defineSetter__", 1413 "__lookupGetter__", 1414 "__lookupSetter__", 1415 "apply", 1416 "bind", 1417 "call", 1418 "constructor", 1419 "create", 1420 "defineProperties", 1421 "defineProperty", 1422 "freeze", 1423 "getOwnPropertyDescriptor", 1424 "getOwnPropertyNames", 1425 "getPrototypeOf", 1426 "hasOwnProperty", 1427 "isExtensible", 1428 "isFrozen", 1429 "isGenerator", 1430 "isPrototypeOf", 1431 "isSealed", 1432 "keys", 1433 "preventExtensions", 1434 "propertyIsEnumerable", 1435 "seal", 1436 "toLocaleString", 1437 "toSource", 1438 "toString", 1439 "unwatch", 1440 "valueOf", 1441 "watch" 1442 ]; 1443 1444 domMemberMap.Location = 1445 [ 1446 "href", 1447 "protocol", 1448 "host", 1449 "hostname", 1450 "port", 1451 "pathname", 1452 "search", 1453 "hash", 1454 1455 "assign", 1456 "reload", 1457 "replace", 1458 1459 "QueryInterface" 1460 ]; 1461 1462 domMemberMap.Node = 1463 [ 1464 "id", 1465 "className", 1466 1467 "nodeType", 1468 "tagName", 1469 "nodeName", 1470 "localName", 1471 "prefix", 1472 "namespaceURI", 1473 "nodeValue", 1474 1475 "ownerDocument", 1476 "parentNode", 1477 "offsetParent", 1478 "nextSibling", 1479 "previousSibling", 1480 "firstChild", 1481 "lastChild", 1482 "childNodes", 1483 "attributes", 1484 1485 "dir", 1486 "baseURI", 1487 "textContent", 1488 "innerHTML", 1489 1490 "addEventListener", 1491 "removeEventListener", 1492 "dispatchEvent", 1493 "cloneNode", 1494 "appendChild", 1495 "insertBefore", 1496 "replaceChild", 1497 "removeChild", 1498 "compareDocumentPosition", 1499 "hasAttributes", 1500 "hasChildNodes", 1501 "lookupNamespaceURI", 1502 "lookupPrefix", 1503 "normalize", 1504 "isDefaultNamespace", 1505 "isEqualNode", 1506 "isSameNode", 1507 "isSupported", 1508 "getFeature", 1509 "getUserData", 1510 "setUserData", 1511 1512 "QueryInterface" 1513 ]; 1514 1515 domMemberMap.Document = Arr.extendArray(domMemberMap.Node, 1516 [ 1517 "documentElement", 1518 "body", 1519 "title", 1520 "location", 1521 "referrer", 1522 "cookie", 1523 "contentType", 1524 "lastModified", 1525 "characterSet", 1526 "inputEncoding", 1527 "xmlEncoding", 1528 "xmlStandalone", 1529 "xmlVersion", 1530 "strictErrorChecking", 1531 "documentURI", 1532 "URL", 1533 1534 "defaultView", 1535 "doctype", 1536 "implementation", 1537 "styleSheets", 1538 "images", 1539 "links", 1540 "forms", 1541 "anchors", 1542 "embeds", 1543 "plugins", 1544 "applets", 1545 1546 "width", 1547 "height", 1548 1549 "designMode", 1550 "compatMode", 1551 "async", 1552 "readyState", 1553 1554 "preferredStyleSheetSet", 1555 "lastStyleSheetSet", 1556 "styleSheetSets", 1557 "selectedStyleSheetSet", 1558 "enableStyleSheetsForSet", 1559 1560 "elementFromPoint", 1561 "hasFocus", 1562 "activeElement", 1563 1564 /* These are also in domMemberMap.Element, but it reflects the real interface definition */ 1565 "getElementsByClassName", 1566 "querySelector", 1567 "querySelectorAll", 1568 1569 "alinkColor", 1570 "linkColor", 1571 "vlinkColor", 1572 "bgColor", 1573 "fgColor", 1574 "domain", 1575 1576 "addEventListener", 1577 "removeEventListener", 1578 "dispatchEvent", 1579 "captureEvents", 1580 "releaseEvents", 1581 "routeEvent", 1582 "clear", 1583 "open", 1584 "close", 1585 "execCommand", 1586 "execCommandShowHelp", 1587 "getElementsByName", 1588 "getSelection", 1589 "queryCommandEnabled", 1590 "queryCommandIndeterm", 1591 "queryCommandState", 1592 "queryCommandSupported", 1593 "queryCommandText", 1594 "queryCommandValue", 1595 "write", 1596 "writeln", 1597 "adoptNode", 1598 "appendChild", 1599 "removeChild", 1600 "renameNode", 1601 "cloneNode", 1602 "compareDocumentPosition", 1603 "createAttribute", 1604 "createAttributeNS", 1605 "createCDATASection", 1606 "createComment", 1607 "createDocumentFragment", 1608 "createElement", 1609 "createElementNS", 1610 "createEntityReference", 1611 "createEvent", 1612 "createExpression", 1613 "createNSResolver", 1614 "createNodeIterator", 1615 "createProcessingInstruction", 1616 "createRange", 1617 "createTextNode", 1618 "createTreeWalker", 1619 "domConfig", 1620 "evaluate", 1621 "evaluateFIXptr", 1622 "evaluateXPointer", 1623 "getAnonymousElementByAttribute", 1624 "getAnonymousNodes", 1625 "addBinding", 1626 "removeBinding", 1627 "getBindingParent", 1628 "getBoxObjectFor", 1629 "setBoxObjectFor", 1630 "getElementById", 1631 "getElementsByTagName", 1632 "getElementsByTagNameNS", 1633 "hasAttributes", 1634 "hasChildNodes", 1635 "importNode", 1636 "insertBefore", 1637 "isDefaultNamespace", 1638 "isEqualNode", 1639 "isSameNode", 1640 "isSupported", 1641 "load", 1642 "loadBindingDocument", 1643 "lookupNamespaceURI", 1644 "lookupPrefix", 1645 "normalize", 1646 "normalizeDocument", 1647 "getFeature", 1648 "getUserData", 1649 "setUserData" 1650 ]); 1651 1652 domMemberMap.Element = Arr.extendArray(domMemberMap.Node, 1653 [ 1654 "clientWidth", 1655 "clientHeight", 1656 "offsetLeft", 1657 "offsetTop", 1658 "offsetWidth", 1659 "offsetHeight", 1660 "scrollLeft", 1661 "scrollTop", 1662 "scrollWidth", 1663 "scrollHeight", 1664 1665 "style", 1666 1667 "tabIndex", 1668 "title", 1669 "lang", 1670 "align", 1671 "spellcheck", 1672 1673 "addEventListener", 1674 "removeEventListener", 1675 "dispatchEvent", 1676 "focus", 1677 "blur", 1678 "cloneNode", 1679 "appendChild", 1680 "insertBefore", 1681 "replaceChild", 1682 "removeChild", 1683 "compareDocumentPosition", 1684 "getElementsByTagName", 1685 "getElementsByTagNameNS", 1686 "getAttribute", 1687 "getAttributeNS", 1688 "getAttributeNode", 1689 "getAttributeNodeNS", 1690 "setAttribute", 1691 "setAttributeNS", 1692 "setAttributeNode", 1693 "setAttributeNodeNS", 1694 "removeAttribute", 1695 "removeAttributeNS", 1696 "removeAttributeNode", 1697 "hasAttribute", 1698 "hasAttributeNS", 1699 "hasAttributes", 1700 "hasChildNodes", 1701 "lookupNamespaceURI", 1702 "lookupPrefix", 1703 "normalize", 1704 "isDefaultNamespace", 1705 "isEqualNode", 1706 "isSameNode", 1707 "isSupported", 1708 "getFeature", 1709 "getUserData", 1710 "setUserData", 1711 1712 "childElementCount", 1713 "children", 1714 "classList", 1715 "clientLeft", 1716 "clientTop", 1717 "contentEditable", 1718 "draggable", 1719 "firstElementChild", 1720 "lastElementChild", 1721 "nextElementSibling", 1722 "previousElementSibling", 1723 1724 "getBoundingClientRect", 1725 "getClientRects", 1726 "getElementsByClassName", 1727 "mozMatchesSelector", 1728 "querySelector", 1729 "querySelectorAll", 1730 "scrollIntoView", 1731 1732 "onLoad",//FF4.0 1733 "hidden",//FF4.0 1734 "setCapture",//FF4.0 1735 "releaseCapture"//FF4.0 1736 ]); 1737 1738 domMemberMap.SVGElement = Arr.extendArray(domMemberMap.Element, 1739 [ 1740 "x", 1741 "y", 1742 "width", 1743 "height", 1744 "rx", 1745 "ry", 1746 "transform", 1747 "href", 1748 1749 "ownerSVGElement", 1750 "viewportElement", 1751 "farthestViewportElement", 1752 "nearestViewportElement", 1753 1754 "getBBox", 1755 "getCTM", 1756 "getScreenCTM", 1757 "getTransformToElement", 1758 "getPresentationAttribute", 1759 "preserveAspectRatio" 1760 ]); 1761 1762 domMemberMap.SVGSVGElement = Arr.extendArray(domMemberMap.Element, 1763 [ 1764 "x", 1765 "y", 1766 "width", 1767 "height", 1768 "rx", 1769 "ry", 1770 "transform", 1771 1772 "viewBox", 1773 "viewport", 1774 "currentView", 1775 "useCurrentView", 1776 "pixelUnitToMillimeterX", 1777 "pixelUnitToMillimeterY", 1778 "screenPixelToMillimeterX", 1779 "screenPixelToMillimeterY", 1780 "currentScale", 1781 "currentTranslate", 1782 "zoomAndPan", 1783 1784 "ownerSVGElement", 1785 "viewportElement", 1786 "farthestViewportElement", 1787 "nearestViewportElement", 1788 "contentScriptType", 1789 "contentStyleType", 1790 1791 "getBBox", 1792 "getCTM", 1793 "getScreenCTM", 1794 "getTransformToElement", 1795 "getEnclosureList", 1796 "getIntersectionList", 1797 "getViewboxToViewportTransform", 1798 "getPresentationAttribute", 1799 "getElementById", 1800 "checkEnclosure", 1801 "checkIntersection", 1802 "createSVGAngle", 1803 "createSVGLength", 1804 "createSVGMatrix", 1805 "createSVGNumber", 1806 "createSVGPoint", 1807 "createSVGRect", 1808 "createSVGString", 1809 "createSVGTransform", 1810 "createSVGTransformFromMatrix", 1811 "deSelectAll", 1812 "preserveAspectRatio", 1813 "forceRedraw", 1814 "suspendRedraw", 1815 "unsuspendRedraw", 1816 "unsuspendRedrawAll", 1817 "getCurrentTime", 1818 "setCurrentTime", 1819 "animationsPaused", 1820 "pauseAnimations", 1821 "unpauseAnimations" 1822 ]); 1823 1824 domMemberMap.HTMLImageElement = Arr.extendArray(domMemberMap.Element, 1825 [ 1826 "src", 1827 "naturalWidth", 1828 "naturalHeight", 1829 "width", 1830 "height", 1831 "x", 1832 "y", 1833 "name", 1834 "alt", 1835 "longDesc", 1836 "lowsrc", 1837 "border", 1838 "complete", 1839 "hspace", 1840 "vspace", 1841 "isMap", 1842 "useMap", 1843 ]); 1844 1845 domMemberMap.HTMLAnchorElement = Arr.extendArray(domMemberMap.Element, 1846 [ 1847 "name", 1848 "target", 1849 "accessKey", 1850 "href", 1851 "protocol", 1852 "host", 1853 "hostname", 1854 "port", 1855 "pathname", 1856 "search", 1857 "hash", 1858 "hreflang", 1859 "coords", 1860 "shape", 1861 "text", 1862 "type", 1863 "rel", 1864 "rev", 1865 "charset" 1866 ]); 1867 1868 domMemberMap.HTMLIFrameElement = Arr.extendArray(domMemberMap.Element, 1869 [ 1870 "contentDocument", 1871 "contentWindow", 1872 "frameBorder", 1873 "height", 1874 "longDesc", 1875 "marginHeight", 1876 "marginWidth", 1877 "name", 1878 "scrolling", 1879 "src", 1880 "width" 1881 ]); 1882 1883 domMemberMap.HTMLTableElement = Arr.extendArray(domMemberMap.Element, 1884 [ 1885 "bgColor", 1886 "border", 1887 "caption", 1888 "cellPadding", 1889 "cellSpacing", 1890 "frame", 1891 "rows", 1892 "rules", 1893 "summary", 1894 "tBodies", 1895 "tFoot", 1896 "tHead", 1897 "width", 1898 1899 "createCaption", 1900 "createTFoot", 1901 "createTHead", 1902 "deleteCaption", 1903 "deleteRow", 1904 "deleteTFoot", 1905 "deleteTHead", 1906 "insertRow" 1907 ]); 1908 1909 domMemberMap.HTMLTableRowElement = Arr.extendArray(domMemberMap.Element, 1910 [ 1911 "bgColor", 1912 "cells", 1913 "ch", 1914 "chOff", 1915 "rowIndex", 1916 "sectionRowIndex", 1917 "vAlign", 1918 1919 "deleteCell", 1920 "insertCell" 1921 ]); 1922 1923 domMemberMap.HTMLTableCellElement = Arr.extendArray(domMemberMap.Element, 1924 [ 1925 "abbr", 1926 "axis", 1927 "bgColor", 1928 "cellIndex", 1929 "ch", 1930 "chOff", 1931 "colSpan", 1932 "headers", 1933 "height", 1934 "noWrap", 1935 "rowSpan", 1936 "scope", 1937 "vAlign", 1938 "width" 1939 1940 ]); 1941 1942 domMemberMap.HTMLScriptElement = Arr.extendArray(domMemberMap.Element, 1943 [ 1944 "src" 1945 ]); 1946 1947 domMemberMap.HTMLButtonElement = Arr.extendArray(domMemberMap.Element, 1948 [ 1949 "accessKey", 1950 "disabled", 1951 "form", 1952 "name", 1953 "type", 1954 "value", 1955 1956 "click" 1957 ]); 1958 1959 domMemberMap.HTMLInputElement = Arr.extendArray(domMemberMap.Element, 1960 [ 1961 "type", 1962 "value", 1963 "checked", 1964 "accept", 1965 "accessKey", 1966 "alt", 1967 "autocomplete", 1968 "autofocus", 1969 "controllers", 1970 "defaultChecked", 1971 "defaultValue", 1972 "disabled", 1973 "form", 1974 "formAction", 1975 "formEnctype", 1976 "formMethod", 1977 "formNoValidate", 1978 "formTarget", 1979 "maxLength", 1980 "name", 1981 "readOnly", 1982 "selectionEnd", 1983 "selectionStart", 1984 "size", 1985 "src", 1986 "textLength", 1987 "useMap", 1988 1989 "files", 1990 "indeterminate", 1991 "multiple", 1992 "list", 1993 "mozGetFileNameArray", 1994 "mozSetFileNameArray", 1995 1996 "pattern", 1997 "placeholder", 1998 "required", 1999 2000 "click", 2001 "select", 2002 "setSelectionRange" 2003 ]); 2004 2005 domMemberMap.HTMLFormElement = Arr.extendArray(domMemberMap.Element, 2006 [ 2007 "acceptCharset", 2008 "action", 2009 "author", 2010 "elements", 2011 "encoding", 2012 "enctype", 2013 "entry_id", 2014 "length", 2015 "method", 2016 "name", 2017 "post", 2018 "target", 2019 "text", 2020 "url", 2021 2022 "reset", 2023 "submit" 2024 ]); 2025 2026 domMemberMap.HTMLBodyElement = Arr.extendArray(domMemberMap.Element, 2027 [ 2028 "aLink", 2029 "background", 2030 "bgColor", 2031 "link", 2032 "text", 2033 "vLink" 2034 ]); 2035 2036 domMemberMap.HTMLHtmlElement = Arr.extendArray(domMemberMap.Element, 2037 [ 2038 "version" 2039 ]); 2040 2041 domMemberMap.Text = Arr.extendArray(domMemberMap.Node, 2042 [ 2043 "data", 2044 "length", 2045 2046 "appendData", 2047 "deleteData", 2048 "insertData", 2049 "replaceData", 2050 "splitText", 2051 "substringData" 2052 ]); 2053 2054 domMemberMap.Attr = Arr.extendArray(domMemberMap.Node, 2055 [ 2056 "name", 2057 "value", 2058 "specified", 2059 "ownerElement" 2060 ]); 2061 2062 domMemberMap.Event = 2063 [ 2064 "type", 2065 "target", 2066 "currentTarget", 2067 "originalTarget", 2068 "explicitOriginalTarget", 2069 "relatedTarget", 2070 "rangeParent", 2071 "rangeOffset", 2072 "view", 2073 2074 "keyCode", 2075 "charCode", 2076 "screenX", 2077 "screenY", 2078 "clientX", 2079 "clientY", 2080 "layerX", 2081 "layerY", 2082 "pageX", 2083 "pageY", 2084 2085 "detail", 2086 "button", 2087 "which", 2088 "ctrlKey", 2089 "shiftKey", 2090 "altKey", 2091 "metaKey", 2092 2093 "eventPhase", 2094 "timeStamp", 2095 "bubbles", 2096 "cancelable", 2097 "cancelBubble", 2098 2099 "isTrusted", 2100 "isChar", 2101 2102 "getPreventDefault", 2103 "initEvent", 2104 "initMouseEvent", 2105 "initKeyEvent", 2106 "initUIEvent", 2107 "preventBubble", 2108 "preventCapture", 2109 "preventDefault", 2110 "stopPropagation" 2111 ]; 2112 2113 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // 2114 2115 var domConstantMap = Dom.domConstantMap = 2116 { 2117 "ELEMENT_NODE": 1, 2118 "ATTRIBUTE_NODE": 1, 2119 "TEXT_NODE": 1, 2120 "CDATA_SECTION_NODE": 1, 2121 "ENTITY_REFERENCE_NODE": 1, 2122 "ENTITY_NODE": 1, 2123 "PROCESSING_INSTRUCTION_NODE": 1, 2124 "COMMENT_NODE": 1, 2125 "DOCUMENT_NODE": 1, 2126 "DOCUMENT_TYPE_NODE": 1, 2127 "DOCUMENT_FRAGMENT_NODE": 1, 2128 "NOTATION_NODE": 1, 2129 2130 "DOCUMENT_POSITION_DISCONNECTED": 1, 2131 "DOCUMENT_POSITION_PRECEDING": 1, 2132 "DOCUMENT_POSITION_FOLLOWING": 1, 2133 "DOCUMENT_POSITION_CONTAINS": 1, 2134 "DOCUMENT_POSITION_CONTAINED_BY": 1, 2135 "DOCUMENT_POSITION_IMPLEMENTATION_SPECIFIC": 1, 2136 2137 "UNKNOWN_RULE": 1, 2138 "STYLE_RULE": 1, 2139 "CHARSET_RULE": 1, 2140 "IMPORT_RULE": 1, 2141 "MEDIA_RULE": 1, 2142 "FONT_FACE_RULE": 1, 2143 "PAGE_RULE": 1, 2144 2145 "CAPTURING_PHASE": 1, 2146 "AT_TARGET": 1, 2147 "BUBBLING_PHASE": 1, 2148 2149 "SCROLL_PAGE_UP": 1, 2150 "SCROLL_PAGE_DOWN": 1, 2151 2152 "MOUSEUP": 1, 2153 "MOUSEDOWN": 1, 2154 "MOUSEOVER": 1, 2155 "MOUSEOUT": 1, 2156 "MOUSEMOVE": 1, 2157 "MOUSEDRAG": 1, 2158 "CLICK": 1, 2159 "DBLCLICK": 1, 2160 "KEYDOWN": 1, 2161 "KEYUP": 1, 2162 "KEYPRESS": 1, 2163 "DRAGDROP": 1, 2164 "FOCUS": 1, 2165 "BLUR": 1, 2166 "SELECT": 1, 2167 "CHANGE": 1, 2168 "RESET": 1, 2169 "SUBMIT": 1, 2170 "SCROLL": 1, 2171 "LOAD": 1, 2172 "UNLOAD": 1, 2173 "XFER_DONE": 1, 2174 "ABORT": 1, 2175 "ERROR": 1, 2176 "LOCATE": 1, 2177 "MOVE": 1, 2178 "RESIZE": 1, 2179 "FORWARD": 1, 2180 "HELP": 1, 2181 "BACK": 1, 2182 "TEXT": 1, 2183 2184 "ALT_MASK": 1, 2185 "CONTROL_MASK": 1, 2186 "SHIFT_MASK": 1, 2187 "META_MASK": 1, 2188 2189 "DOM_VK_TAB": 1, 2190 "DOM_VK_PAGE_UP": 1, 2191 "DOM_VK_PAGE_DOWN": 1, 2192 "DOM_VK_UP": 1, 2193 "DOM_VK_DOWN": 1, 2194 "DOM_VK_LEFT": 1, 2195 "DOM_VK_RIGHT": 1, 2196 "DOM_VK_CANCEL": 1, 2197 "DOM_VK_HELP": 1, 2198 "DOM_VK_BACK_SPACE": 1, 2199 "DOM_VK_CLEAR": 1, 2200 "DOM_VK_RETURN": 1, 2201 "DOM_VK_ENTER": 1, 2202 "DOM_VK_SHIFT": 1, 2203 "DOM_VK_CONTROL": 1, 2204 "DOM_VK_ALT": 1, 2205 "DOM_VK_PAUSE": 1, 2206 "DOM_VK_CAPS_LOCK": 1, 2207 "DOM_VK_ESCAPE": 1, 2208 "DOM_VK_SPACE": 1, 2209 "DOM_VK_END": 1, 2210 "DOM_VK_HOME": 1, 2211 "DOM_VK_PRINTSCREEN": 1, 2212 "DOM_VK_INSERT": 1, 2213 "DOM_VK_DELETE": 1, 2214 "DOM_VK_0": 1, 2215 "DOM_VK_1": 1, 2216 "DOM_VK_2": 1, 2217 "DOM_VK_3": 1, 2218 "DOM_VK_4": 1, 2219 "DOM_VK_5": 1, 2220 "DOM_VK_6": 1, 2221 "DOM_VK_7": 1, 2222 "DOM_VK_8": 1, 2223 "DOM_VK_9": 1, 2224 "DOM_VK_SEMICOLON": 1, 2225 "DOM_VK_EQUALS": 1, 2226 "DOM_VK_A": 1, 2227 "DOM_VK_B": 1, 2228 "DOM_VK_C": 1, 2229 "DOM_VK_D": 1, 2230 "DOM_VK_E": 1, 2231 "DOM_VK_F": 1, 2232 "DOM_VK_G": 1, 2233 "DOM_VK_H": 1, 2234 "DOM_VK_I": 1, 2235 "DOM_VK_J": 1, 2236 "DOM_VK_K": 1, 2237 "DOM_VK_L": 1, 2238 "DOM_VK_M": 1, 2239 "DOM_VK_N": 1, 2240 "DOM_VK_O": 1, 2241 "DOM_VK_P": 1, 2242 "DOM_VK_Q": 1, 2243 "DOM_VK_R": 1, 2244 "DOM_VK_S": 1, 2245 "DOM_VK_T": 1, 2246 "DOM_VK_U": 1, 2247 "DOM_VK_V": 1, 2248 "DOM_VK_W": 1, 2249 "DOM_VK_X": 1, 2250 "DOM_VK_Y": 1, 2251 "DOM_VK_Z": 1, 2252 "DOM_VK_CONTEXT_MENU": 1, 2253 "DOM_VK_NUMPAD0": 1, 2254 "DOM_VK_NUMPAD1": 1, 2255 "DOM_VK_NUMPAD2": 1, 2256 "DOM_VK_NUMPAD3": 1, 2257 "DOM_VK_NUMPAD4": 1, 2258 "DOM_VK_NUMPAD5": 1, 2259 "DOM_VK_NUMPAD6": 1, 2260 "DOM_VK_NUMPAD7": 1, 2261 "DOM_VK_NUMPAD8": 1, 2262 "DOM_VK_NUMPAD9": 1, 2263 "DOM_VK_MULTIPLY": 1, 2264 "DOM_VK_ADD": 1, 2265 "DOM_VK_SEPARATOR": 1, 2266 "DOM_VK_SUBTRACT": 1, 2267 "DOM_VK_DECIMAL": 1, 2268 "DOM_VK_DIVIDE": 1, 2269 "DOM_VK_F1": 1, 2270 "DOM_VK_F2": 1, 2271 "DOM_VK_F3": 1, 2272 "DOM_VK_F4": 1, 2273 "DOM_VK_F5": 1, 2274 "DOM_VK_F6": 1, 2275 "DOM_VK_F7": 1, 2276 "DOM_VK_F8": 1, 2277 "DOM_VK_F9": 1, 2278 "DOM_VK_F10": 1, 2279 "DOM_VK_F11": 1, 2280 "DOM_VK_F12": 1, 2281 "DOM_VK_F13": 1, 2282 "DOM_VK_F14": 1, 2283 "DOM_VK_F15": 1, 2284 "DOM_VK_F16": 1, 2285 "DOM_VK_F17": 1, 2286 "DOM_VK_F18": 1, 2287 "DOM_VK_F19": 1, 2288 "DOM_VK_F20": 1, 2289 "DOM_VK_F21": 1, 2290 "DOM_VK_F22": 1, 2291 "DOM_VK_F23": 1, 2292 "DOM_VK_F24": 1, 2293 "DOM_VK_NUM_LOCK": 1, 2294 "DOM_VK_SCROLL_LOCK": 1, 2295 "DOM_VK_COMMA": 1, 2296 "DOM_VK_PERIOD": 1, 2297 "DOM_VK_SLASH": 1, 2298 "DOM_VK_BACK_QUOTE": 1, 2299 "DOM_VK_OPEN_BRACKET": 1, 2300 "DOM_VK_BACK_SLASH": 1, 2301 "DOM_VK_CLOSE_BRACKET": 1, 2302 "DOM_VK_QUOTE": 1, 2303 "DOM_VK_META": 1, 2304 2305 "SVG_ZOOMANDPAN_DISABLE": 1, 2306 "SVG_ZOOMANDPAN_MAGNIFY": 1, 2307 "SVG_ZOOMANDPAN_UNKNOWN": 1 2308 }; 2309 2310 // ********************************************************************************************* // 2311 // Inline Event Handlers (introduced in Firefox 9) 2312 2313 /** 2314 * List of event handlers that are settable via on* DOM properties. 2315 */ 2316 Dom.domInlineEventHandlersMap = 2317 { 2318 "onabort": 1, 2319 "onafterprint": 1, 2320 "onafterscriptexecute": 1, 2321 "onbeforeprint": 1, 2322 "onbeforescriptexecute": 1, 2323 "onbeforeunload": 1, 2324 "onblur": 1, 2325 "oncanplay": 1, 2326 "oncanplaythrough": 1, 2327 "onchange": 1, 2328 "onclick": 1, 2329 "oncontextmenu": 1, 2330 "oncopy": 1, 2331 "oncut": 1, 2332 "ondblclick": 1, 2333 "ondevicemotion": 1, 2334 "ondeviceorientation": 1, 2335 "ondrag": 1, 2336 "ondragend": 1, 2337 "ondragenter": 1, 2338 "ondragleave": 1, 2339 "ondragover": 1, 2340 "ondragstart": 1, 2341 "ondrop": 1, 2342 "ondurationchange": 1, 2343 "onemptied": 1, 2344 "onended": 1, 2345 "onerror": 1, 2346 "onfocus": 1, 2347 "onhashchange": 1, 2348 "oninput": 1, 2349 "oninvalid": 1, 2350 "onkeydown": 1, 2351 "onkeypress": 1, 2352 "onkeyup": 1, 2353 "onload": 1, 2354 "onloadeddata": 1, 2355 "onloadedmetadata": 1, 2356 "onloadstart": 1, 2357 "onmessage": 1, 2358 "onmousedown": 1, 2359 "onmousemove": 1, 2360 "onmouseout": 1, 2361 "onmouseover": 1, 2362 "onmouseup": 1, 2363 "onoffline": 1, 2364 "ononline": 1, 2365 "onpagehide": 1, 2366 "onpageshow": 1, 2367 "onpaste": 1, 2368 "onpause": 1, 2369 "onplay": 1, 2370 "onplaying": 1, 2371 "onpopstate": 1, 2372 "onprogress": 1, 2373 "onratechange": 1, 2374 "onreadystatechange": 1, 2375 "onreset": 1, 2376 "onresize": 1, 2377 "onscroll": 1, 2378 "onseeked": 1, 2379 "onseeking": 1, 2380 "onselect": 1, 2381 "onshow": 1, 2382 "onstalled": 1, 2383 "onsubmit": 1, 2384 "onsuspend": 1, 2385 "ontimeupdate": 1, 2386 "onunload": 1, 2387 "onvolumechange": 1, 2388 "onwaiting": 1, 2389 "onmozfullscreenchange": 1, 2390 "ondevicelight": 1, 2391 "ondeviceproximity": 1, 2392 "onmouseenter": 1, 2393 "onmouseleave": 1, 2394 "onmozfullscreenerror": 1, 2395 "onmozpointerlockchange": 1, 2396 "onmozpointerlockerror": 1, 2397 "onuserproximity": 1, 2398 "onwheel": 1 2399 } 2400 2401 // ********************************************************************************************* // 2402 // Registration 2403 2404 return Dom; 2405 2406 // ********************************************************************************************* // 2407 }); 2408