/**
 * outerHTML.js
 *
 * @version 1.4
 * @author think49
 */

if (!('outerHTML' in document.createElement('p')) && 'innerHTML' in document.createElement('p') && (typeof HTMLElement === 'function' || typeof HTMLElement === 'object')) {
  (function () {
    var _Node = (typeof Node === 'function' || typeof Node === 'object') ? Node : {
      ELEMENT_NODE: 1,
      ATTRIBUTE_NODE: 2,
      TEXT_NODE: 3,
      CDATA_SECTION_NODE: 4,
      ENTITY_REFERENCE_NODE: 5,
      ENTITY_NODE: 6,
      PROCESSING_INSTRUCTION_NODE: 7,
      COMMENT_NODE: 8,
      DOCUMENT_NODE: 9,
      DOCUMENT_TYPE_NODE: 10,
      DOCUMENT_FRAGMENT_NODE: 11,
      NOTATION_NODE: 12
    };

    function getOuterHTML () {
      var node;

      node = this.ownerDocument.createElement('body');
      node.appendChild(this.cloneNode(true));

      return node.innerHTML;
    }

    function setOuterHTML (htmlString) {
      var doc, parentNode, node, df;

      parentNode = this.parentNode;

      if (!parentNode) { // HTML5 3.5.6 (step2)
        return;
      }

      if (parentNode.nodeType === _Node.DOCUMENT_NODE) { // HTML5 3.5.6 (step3)
        throw new Error('NO_MODIFICATION_ALLOWED_ERR');
      }

      doc = this.ownerDocument;
      node = doc.createElement('body');
      node.innerHTML = htmlString;
      node = node.firstChild;
      df = doc.createDocumentFragment();

      while (node) {
        df.appendChild(node);
        node = node.nextSibling;
      }

      parentNode.replaceChild(df, this);
    }

    if ('defineProperty' in Object) { // ECMAScript 5
      Object.defineProperty(this, 'outerHTML', {get: getOuterHTML, set: setOuterHTML});
      return;
    }

    if ('__defineGetter__' in this && '__defineSetter__' in this) { // for Firefox
      this.__defineGetter__('outerHTML', getOuterHTML);
      this.__defineSetter__('outerHTML', setOuterHTML);
    }
  }).call(HTMLElement.prototype);
}


