import { DOM_ATTRIBUTE_SIZE, HAIR_SPACE_CHAR, SPACER_SIZE_TAB } from './SpacerMarkSpec.js';
import patchAnchorElements from './patchAnchorElements.js';
import patchBreakElements from './patchBreakElements.js';
import patchElementInlineStyles from './patchElementInlineStyles.js';
import patchListElements from './patchListElements.js';
import patchMathElements from './patchMathElements.js';
import patchParagraphElements from './patchParagraphElements.js';
import patchStyleElements from './patchStyleElements.js';
import patchTableElements from './patchTableElements.js';
import toSafeHTMLDocument from './toSafeHTMLDocument.js';
var HTML_BODY_PATTERN = /<body[\s>]/i;
var 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.
var LONG_TAB_SPACE_PATTERN = /(\&nbsp;){6}/g;
var TAB_SPACER_HTML = new Array(6).join("<span ".concat(DOM_ATTRIBUTE_SIZE, "=\"").concat(SPACER_SIZE_TAB, "\">").concat(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>".concat(String(matched), "</nobr> ");
  }
  return matched;
}
export default function normalizeHTML(html) {
  var body = null;
  var 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);
  var doc = toSafeHTMLDocument(html);
  if (doc) {
    // styles.
    patchStyleElements(doc);
    patchElementInlineStyles(doc);
    // contents.
    patchAnchorElements(doc);
    patchBreakElements(doc);
    patchListElements(doc);
    patchParagraphElements(doc);
    patchTableElements(doc);
    patchMathElements(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.
      var 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>';
}