define(["exports", "deps/beautify-html", "core/beautify-options", "core/utils"], function (exports, _beautifyHtml, _beautifyOptions, _utils) {
  "use strict";

  Object.defineProperty(exports, "__esModule", {
    value: true
  });
  exports.name = undefined;
  exports.run = run;

  var _beautifyHtml2 = _interopRequireDefault(_beautifyHtml);

  function _interopRequireDefault(obj) {
    return obj && obj.__esModule ? obj : {
      default: obj
    };
  }

  function _classCallCheck(instance, Constructor) {
    if (!(instance instanceof Constructor)) {
      throw new TypeError("Cannot call a class as a function");
    }
  }

  var _createClass = function () {
    function defineProperties(target, props) {
      for (var i = 0; i < props.length; i++) {
        var descriptor = props[i];
        descriptor.enumerable = descriptor.enumerable || false;
        descriptor.configurable = true;
        if ("value" in descriptor) descriptor.writable = true;
        Object.defineProperty(target, descriptor.key, descriptor);
      }
    }

    return function (Constructor, protoProps, staticProps) {
      if (protoProps) defineProperties(Constructor.prototype, protoProps);
      if (staticProps) defineProperties(Constructor, staticProps);
      return Constructor;
    };
  }();

  var name = exports.name = "core/markdown";

  function processElements(selector) {
    return function (element) {
      var elements = Array.from(element.querySelectorAll(selector));
      elements.reverse().forEach(function (element) {
        element.innerHTML = (0, _utils.markdownToHtml)(element.innerHTML);
      });
      return elements;
    };
  }

  var Builder = function () {
    function Builder(doc) {
      _classCallCheck(this, Builder);

      this.doc = doc;
      this.root = doc.createDocumentFragment();
      this.stack = [this.root];
      this.current = this.root;
    }

    _createClass(Builder, [{
      key: "findPosition",
      value: function findPosition(header) {
        return parseInt(header.tagName.charAt(1), 10);
      }
    }, {
      key: "findParent",
      value: function findParent(position) {
        var parent = void 0;
        while (position > 0) {
          position--;
          parent = this.stack[position];
          if (parent) return parent;
        }
      }
    }, {
      key: "findHeader",
      value: function findHeader(_ref) {
        var node = _ref.firstChild;

        while (node) {
          if (/H[1-6]/.test(node.tagName)) {
            return node;
          }
          node = node.nextSibling;
        }
        return null;
      }
    }, {
      key: "addHeader",
      value: function addHeader(header) {
        var section = this.doc.createElement("section");
        var position = this.findPosition(header);

        section.appendChild(header);
        this.findParent(position).appendChild(section);
        this.stack[position] = section;
        this.stack.length = position + 1;
        this.current = section;
      }
    }, {
      key: "addSection",
      value: function addSection(node, process) {
        var header = this.findHeader(node);
        var position = header ? this.findPosition(header) : 1;
        var parent = this.findParent(position);

        if (header) {
          node.removeChild(header);
        }

        node.appendChild(process(node));

        if (header) {
          node.insertBefore(header, node.firstChild);
        }

        parent.appendChild(node);
        this.current = parent;
      }
    }, {
      key: "addElement",
      value: function addElement(node) {
        this.current.appendChild(node);
      }
    }]);

    return Builder;
  }();

  function structure(fragment, doc) {
    function process(root) {
      var stack = new Builder(doc);
      while (root.firstChild) {
        var node = root.firstChild;
        if (node.nodeType !== Node.ELEMENT_NODE) {
          root.removeChild(node);
          continue;
        }
        switch (node.localName) {
          case "h1":
          case "h2":
          case "h3":
          case "h4":
          case "h5":
          case "h6":
            stack.addHeader(node);
            break;
          case "section":
            stack.addSection(node, process);
            break;
          default:
            stack.addElement(node);
        }
      }
      return stack.root;
    }
    return process(fragment);
  }

  function substituteWithTextNodes(elements) {
    Array.from(elements).forEach(function (element) {
      var textNode = element.ownerDocument.createTextNode(element.textContent);
      element.parentElement.replaceChild(textNode, element);
    });
  }

  var processMDSections = processElements("[data-format='markdown']:not(body)");
  var processBlockLevelElements = processElements("[data-format=markdown]:not(body), section, div, address, article, aside, figure, header, main, body");

  function run(conf, doc, cb) {
    var hasMDSections = !!doc.querySelector("[data-format=markdown]:not(body)");
    var isMDFormat = conf.format === "markdown";
    if (!isMDFormat && !hasMDSections) {
      return cb(); // Nothing to be done
    }
    // Only has markdown-format sections
    if (!isMDFormat) {
      processMDSections(doc.body).map(function (elem) {
        var structuredInternals = structure(elem, elem.ownerDocument);
        return {
          structuredInternals: structuredInternals,
          elem: elem
        };
      }).forEach(function (_ref2) {
        var elem = _ref2.elem,
            structuredInternals = _ref2.structuredInternals;

        elem.setAttribute("aria-busy", "true");
        if (structuredInternals.firstElementChild.localName === "section" && elem.localName === "section") {
          var section = structuredInternals.firstElementChild;
          section.remove();
          while (section.hasChildNodes()) {
            elem.appendChild(section.firstChild);
          }
        } else {
          elem.innerHTML = "";
        }
        elem.appendChild(structuredInternals);
        elem.setAttribute("aria-busy", "false");
      });
      return cb();
    }
    // We transplant the UI to do the markdown processing
    var rsUI = doc.getElementById("respec-ui");
    rsUI.remove();
    // The new body will replace the old body
    var newHTML = doc.createElement("html");
    var newBody = doc.createElement("body");
    newBody.innerHTML = doc.body.innerHTML;
    // Marked expects markdown be flush against the left margin
    // so we need to normalize the inner text of some block
    // elements.
    newHTML.appendChild(newBody);
    processBlockLevelElements(newHTML);
    // Process root level text nodes
    var cleanHTML = newBody.innerHTML
    // Markdown parsing sometimes inserts empty p tags
    .replace(/<p>\s*<\/p>/gm, "");
    var beautifulHTML = _beautifyHtml2.default.html_beautify(cleanHTML, _beautifyOptions.beautifyOps)
    // beautifer has a bad time with "\n&quot;<element"
    // https://github.com/beautify-web/js-beautify/issues/943
    .replace(/&quot;\n\s+\</gm, '"<');

    newBody.innerHTML = beautifulHTML;
    // Remove links where class .nolinks
    substituteWithTextNodes(newBody.querySelectorAll(".nolinks a[href]"));
    // Restructure the document properly
    var fragment = structure(newBody, doc);
    // Frankenstein the whole thing back together
    newBody.appendChild(fragment);
    newBody.insertAdjacentElement("afterbegin", rsUI);
    doc.body.parentNode.replaceChild(newBody, doc.body);
    cb();
  }
});
//# sourceMappingURL=markdown.js.map