"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports.default = normalizeHTML;
var _SpacerMarkSpec = require("./SpacerMarkSpec");
var _patchAnchorElements = _interopRequireDefault(require("./patchAnchorElements"));
var _patchBreakElements = _interopRequireDefault(require("./patchBreakElements"));
var _patchElementInlineStyles = _interopRequireDefault(require("./patchElementInlineStyles"));
var _patchListElements = _interopRequireDefault(require("./patchListElements"));
var _patchMathElements = _interopRequireDefault(require("./patchMathElements"));
var _patchParagraphElements = _interopRequireDefault(require("./patchParagraphElements"));
var _patchStyleElements = _interopRequireDefault(require("./patchStyleElements"));
var _patchTableElements = _interopRequireDefault(require("./patchTableElements"));
var _toSafeHTMLDocument = _interopRequireDefault(require("./toSafeHTMLDocument"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
const HTML_BODY_PATTERN = /<body[\s>]/i;
const LONG_UNDERLINE_PATTERN = /_+/g;

// This is a workround to convert "&nbsp;&nbsp;......&nbsp;" into wider tab
// tab spacers. For every 6 "&nbsp;", they will be converted into tab spacers.
const LONG_TAB_SPACE_PATTERN = /(\&nbsp;){6}/g;
const TAB_SPACER_HTML = new Array(6).join(`<span ${_SpacerMarkSpec.DOM_ATTRIBUTE_SIZE}="${_SpacerMarkSpec.SPACER_SIZE_TAB}">${_SpacerMarkSpec.HAIR_SPACE_CHAR}</span>`);
function replaceNOBR(matched) {
  // This is a workround to convert "_______" into none-wrapped text
  // that apppears like a horizontal line.
  if (matched && matched.length >= 20) {
    // needs extra space after it so user can escape the <nobr />.
    matched = `<nobr>${String(matched)}</nobr> `;
  }
  return matched;
}
function normalizeHTML(html) {
  let body = null;
  const sourceIsPage = HTML_BODY_PATTERN.test(html);
  html = html.replace(LONG_UNDERLINE_PATTERN, replaceNOBR);

  // Convert every two consecutive "&nbsp;" into a spacer tab.
  html = html.replace(LONG_TAB_SPACE_PATTERN, TAB_SPACER_HTML);
  const doc = (0, _toSafeHTMLDocument.default)(html);
  if (doc) {
    // styles.
    (0, _patchStyleElements.default)(doc);
    (0, _patchElementInlineStyles.default)(doc);
    // contents.
    (0, _patchAnchorElements.default)(doc);
    (0, _patchBreakElements.default)(doc);
    (0, _patchListElements.default)(doc);
    (0, _patchParagraphElements.default)(doc);
    (0, _patchTableElements.default)(doc);
    (0, _patchMathElements.default)(doc);
    body = doc.getElementsByTagName('body')[0];
    if (body && sourceIsPage) {
      // Source HTML contains <body />, assumes this to be a complete
      // page HTML. Assume this <body /> may contain the style that indicates
      // page's layout.
      const frag = doc.createElement('html');
      frag.appendChild(body);
      return frag.innerHTML;
    }
  }
  if (!body) {
    // <body /> should alway be generated by doc.
    return 'Unsupported HTML content';
  }

  // HTML snippet only.
  return '<body>' + body.innerHTML + '</body>';
}