// ffcombat.js: Mozilla/Firefox compatibility layer
// Extensions to the built-in objects of Mozilla/Firefox 
// to emulate some of the good IE features.
// There is no need to include this file in IE downloads
// but it also doesn't hurt.
// Copyright by Matthias Hertel, http://www.mathertel.de
// This work is licensed under a Creative Commons Attribution 2.0 Germany License.
// See http://creativecommons.org/licenses/by/2.0/de/
// ----- 
// 12.08.2005 created by Matthias Hertel
// 12.11.2005 FireFox compatibility and scrolling fixed

var isIE = (window.navigator.userAgent.indexOf("MSIE") > 0);

// ----- make FF more IE compatible -----

if (! isIE) {

  // ----- HTML objects -----
  HTMLElement.prototype.__defineGetter__("innerText", function () { return(this.textContent); });
  HTMLElement.prototype.__defineSetter__("innerText", function (txt) { this.textContent = txt; });

  // Hint: This is no perfect optimization. "obj.children" in IE contains no text nodes.
  HTMLElement.prototype.__defineGetter__("children", function () { return(this.childNodes); });

  HTMLElement.prototype.__defineGetter__("XMLDocument", function () { 
    return ((new DOMParser()).parseFromString(this.innerHTML, "text/xml"));
  });



  // ----- Event objects -----
  // We need a wrapper method, because we need to store the actual event object on every call
  // to window.event.

  HTMLElement.prototype.attachEvent = function (eventName, fHandler) {
    fHandler._wrapHandler = function (e) {
       window.event = e;
       fHandler();
       return (e.returnValue);
      };
    this.addEventListener(eventName.substr(2), fHandler._wrapHandler, false);
  };


  HTMLElement.prototype.detachEvent = function (eventName, fHandler) {
    if (fHandler._wrapHandler != null)
      this.removeEventListener(eventName.substr(2), fHandler._wrapHandler, false);
  };


  // enable using evt.srcElement in Mozilla/Firefox
  Event.prototype.__defineGetter__("srcElement", function () {
    var node = this.target;
    while (node.nodeType != 1) node = node.parentNode;
    // test this:
    if (node != this.target) alert("Unexpected event.target!") // it still happens sometime, why ?
    return node;
  });

  // enable using event.cancelBubble=true in Mozilla/Firefox
  Event.prototype.__defineSetter__("cancelBubble", function (b) {
    if (b) this.stopPropagation();
  });


  // enable using event.returnValue=false in Mozilla/Firefox
  // Hint: event.returnValue=true doesn't work !
  Event.prototype.__defineSetter__("returnValue", function (b) {
    if (!b) this.preventDefault();
    this._returnValue = b;
    return(b);
  });

  // enable querying event.returnValue in Mozilla/Firefox
  Event.prototype.__defineGetter__("returnValue", function () {
    return (this._returnValue);
  });


  // ----- XML objects -----
  
  // select the first node that matches the XPath expression
  // xPath: the XPath expression to use
  XMLDocument.prototype.selectSingleNode = function(xPath) {
    var doc = this;
    if (doc.nodeType != 9)
      doc = doc.ownerDocument;
    if (doc.nsResolver == null) doc.nsResolver = function(prefix) { return(null); };
    var node = doc.evaluate(xPath, this, doc.nsResolver, XPathResult.ANY_UNORDERED_NODE_TYPE, null);
    if (node != null) node = node.singleNodeValue;
    return(node);
  }; // selectSingleNode

  Node.prototype.__defineGetter__("text", function () {
    return(this.textContent);
  }); // text
}

// ----- End -----

