import Morph from "morph/morph";

var xhtmlNamespace = "http://www.w3.org/1999/xhtml";

/*
 * A class wrapping DOM functions to address environment compatibility,
 * namespaces, contextual elements for morph un-escaped content
 * insertion.
 *
 * When entering a template, a DOMHelper should be passed to provide
 * context to the template. The context is most easily expressed as
 * an element:
 *
 *   template(context, { hooks: hooks, dom: new DOMHelper(element) });
 *
 * In this case, the namespace and ownerDocument of the element will
 * provide context.
 *
 * During fragment creation, a new namespace may be needed. In these
 * cases, a dom helper will be created for the new namespace:
 *
 *   dom1 = new dom0.constructor(null, dom0.document, someNamespaceURI);
 *
 * In this case the namespace and document are passed explicitly,
 * as decided by the parser at compile time, instead of asking the
 * DOMHelper to determine them. There is no contextual element passed,
 * but the contextual element should only be required by the morphs
 * at the root of a document anyway.
 *
 * Helpers and hooks can pass a new DOMHelper or another object as
 * is appropriate:
 *
 *   var svg = document.createElementNS(svgNamespace, 'svg');
 *   morph.render(context, {hooks: env.hooks, dom: new DOMHelper(svg)});
 *
 * TODO: support foreignObject as a passed contextual element. It has
 * a namespace (svg) that does not match its internal namespace
 * (xhtml).
 *
 * @class DOMHelper
 * @constructor
 * @param {HTMLDocument} _document The document DOM methods are proxied to
 */
function DOMHelper(_document){
  this.document = _document || window.document;
}

var prototype = DOMHelper.prototype;
prototype.constructor = DOMHelper;

prototype.appendChild = function(element, childElement) {
  element.appendChild(childElement);
};

prototype.appendText = function(element, text) {
  element.appendChild(this.document.createTextNode(text));
};

prototype.setAttribute = function(element, name, value) {
  element.setAttribute(name, value);
};

prototype.createElement = function(tagName) {
  if (this.namespaceURI) {
    return this.document.createElementNS(this.namespaceURI, tagName);
  } else {
    return this.document.createElement(tagName);
  }
};

prototype.createDocumentFragment = function(){
  return this.document.createDocumentFragment();
};

prototype.createTextNode = function(text){
  return this.document.createTextNode(text);
};

prototype.cloneNode = function(element, deep){
  return element.cloneNode(!!deep);
};

prototype.createMorph = function(parent, start, end, contextualElement){
  if (!contextualElement && parent.nodeType === Node.ELEMENT_NODE) {
    contextualElement = parent;
  }
  if (!contextualElement) {
    contextualElement = this.document.body;
  }
  return new Morph(parent, start, end, this, contextualElement);
};

// This helper is just to keep the templates good looking,
// passing integers instead of element references.
prototype.createMorphAt = function(parent, startIndex, endIndex, contextualElement){
  var childNodes = parent.childNodes,
      start = startIndex === -1 ? null : childNodes[startIndex],
      end = endIndex === -1 ? null : childNodes[endIndex];
  return this.createMorph(parent, start, end, contextualElement);
};

prototype.parseHTML = function(html, contextualElement){
  var element = this.cloneNode(contextualElement, false);
  element.innerHTML = html;
  return element.childNodes;
};

export default DOMHelper;

@@ -298,1014 +298,73 @@
 ssed
- to provide%0A * context to the template. The context is most easily expressed as%0A * an element:%0A *%0A *   template(context, %7B hooks: hooks, dom: new DOMHelper(element) %7D);%0A *%0A * In this case, the namespace and ownerDocument of the element will%0A * provide context.%0A *%0A * During fragment creation, a new namespace may be needed. In these%0A * cases, a dom helper will be created for the new namespace:%0A *%0A *   dom1 = new dom0.constructor(null, dom0.document, someNamespaceURI);%0A *%0A * In this case the namespace and document are passed explicitly,%0A * as decided by the parser at compile time, instead of asking the%0A * DOMHelper to determine them. There is no contextual element passed,%0A * but the contextual element should only be required by the morphs%0A * at the root of a document anyway.%0A *%0A * Helpers and hooks can pass a new DOMHelper or another object as%0A * is appropriate:%0A *%0A *   var svg = document.createElementNS(svgNamespace, 'svg');%0A *   morph.render(context, %7Bhooks: env.hooks, dom: new DOMHelper(svg)
+:%0A *%0A *   template(context, %7B hooks: hooks, dom: new DOMHelper() 
 %7D);%0A

Update dom helper documentation