text: "use strict";
  
  exports.__esModule = true;
  exports.default = void 0;
  
  var _parse = _interopRequireDefault(require("parse5"));
  
  var _className = _interopRequireDefault(require("../../shadow-ui/class-name"));
  
  var _dom = _interopRequireDefault(require("../dom"));
  
  var _parse5DomAdapter = _interopRequireDefault(require("../dom/parse5-dom-adapter"));
  
  var _resourceProcessorBase = _interopRequireDefault(require("./resource-processor-base"));
  
  var parse5Utils = _interopRequireWildcard(require("../../utils/parse5"));
  
  var _getBom = _interopRequireDefault(require("../../utils/get-bom"));
  
  var _internalProperties = _interopRequireDefault(require("../../processing/dom/internal-properties"));
  
  var _getStorageKey = _interopRequireDefault(require("../../utils/get-storage-key"));
  
  var _createSelfRemovingScript = _interopRequireDefault(require("../../utils/create-self-removing-script"));
  
  function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function () { return cache; }; return cache; }
  
  function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
  
  function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
  
  function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
  
  const BODY_CREATED_EVENT_SCRIPT = (0, _createSelfRemovingScript.default)(`
      if (window["${_internalProperties.default.hammerhead}"])
          window["${_internalProperties.default.hammerhead}"].sandbox.node.raiseBodyCreatedEvent();
  `);
  
  class PageProcessor extends _resourceProcessorBase.default {
    constructor() {
      super();
  
      _defineProperty(this, "RESTART_PROCESSING", void 0);
  
      _defineProperty(this, "PARSED_BODY_CREATED_EVENT_SCRIPT", void 0);
  
      const parsedDocumentFragment = _parse.default.parseFragment(BODY_CREATED_EVENT_SCRIPT);
  
      this.RESTART_PROCESSING = Symbol();
      this.PARSED_BODY_CREATED_EVENT_SCRIPT = parsedDocumentFragment.childNodes[0];
    }
  
    _createRestoreStoragesScript(storageKey, storages) {
      const scriptStr = (0, _createSelfRemovingScript.default)(`
              window.localStorage.setItem("${storageKey}", ${JSON.stringify(storages.localStorage)});
              window.sessionStorage.setItem("${storageKey}", ${JSON.stringify(storages.sessionStorage)});
          `);
  
      const parsedDocumentFragment = _parse.default.parseFragment(scriptStr);
  
      return parsedDocumentFragment.childNodes[0];
    }
  
    static _getPageProcessingOptions(ctx, urlReplacer) {
      return {
        crossDomainProxyPort: ctx.serverInfo.crossDomainPort,
        isIframe: ctx.isIframe,
        stylesheets: ctx.getInjectableStyles(),
        scripts: ctx.getInjectableScripts(),
        urlReplacer: urlReplacer,
        isIframeWithImageSrc: ctx.contentInfo && ctx.contentInfo.isIframeWithImageSrc
      };
    }
  
    static _getPageMetas(metaEls, domAdapter) {
      const metas = [];
  
      for (let i = 0; i < metaEls.length; i++) {
        metas.push({
          httpEquiv: domAdapter.getAttr(metaEls[i], 'http-equiv'),
          content: domAdapter.getAttr(metaEls[i], 'content'),
          charset: domAdapter.getAttr(metaEls[i], 'charset')
        });
      }
  
      return metas;
    }
  
    static _addPageResources(head, processingOptions) {
      const result = [];
  
      if (processingOptions.stylesheets) {
        processingOptions.stylesheets.forEach(stylesheetUrl => {
          result.unshift(parse5Utils.createElement('link', [{
            name: 'rel',
            value: 'stylesheet'
          }, {
            name: 'type',
            value: 'text/css'
          }, {
            name: 'class',
            value: _className.default.uiStylesheet
          }, {
            name: 'href',
            value: stylesheetUrl
          }]));
        });
      }
  
      if (processingOptions.scripts) {
        processingOptions.scripts.forEach(scriptUrl => {
          result.push(parse5Utils.createElement('script', [{
            name: 'type',
            value: 'text/javascript'
          }, {
            name: 'class',
            value: _className.default.script
          }, {
            name: 'charset',
            value: 'UTF-8'
          }, {
            name: 'src',
            value: scriptUrl
          }]));
        });
      }
  
      for (let i = result.length - 1; i > -1; i--) parse5Utils.insertBeforeFirstScript(result[i], head);
    }
  
    static _addCharsetInfo(head, charset) {
      parse5Utils.unshiftElement(parse5Utils.createElement('meta', [{
        name: 'class',
        value: _className.default.charset
      }, {
        name: 'charset',
        value: charset
      }]), head);
    }
  
    static _changeMetas(metas, domAdapter) {
      if (metas) {
        metas.forEach(meta => {
          // TODO: Figure out how to emulate the tag behavior.
          if (domAdapter.getAttr(meta, 'name') === 'referrer') parse5Utils.setAttr(meta, 'content', 'unsafe-url');
        });
      }
    }
  
    static _prepareHtml(html, processingOpts) {
      if (processingOpts && processingOpts.iframeImageSrc) return `<html><body><img src="${processingOpts.iframeImageSrc}" /></body></html>`;
      return html;
    }
  
    _addRestoreStoragesScript(ctx, head) {
      const storageKey = (0, _getStorageKey.default)(ctx.session.id, ctx.dest.host);
  
      const restoreStoragesScript = this._createRestoreStoragesScript(storageKey, ctx.restoringStorages);
  
      parse5Utils.insertBeforeFirstScript(restoreStoragesScript, head);
    }
  
    _addBodyCreatedEventScript(body) {
      parse5Utils.unshiftElement(this.PARSED_BODY_CREATED_EVENT_SCRIPT, body);
    }
  
    shouldProcessResource(ctx) {
      // NOTE: In some cases, Firefox sends the default accept header for the script.
      // We should not try to process it as a page in this case.
      return (ctx.isPage || ctx.contentInfo.isIframeWithImageSrc) && !ctx.contentInfo.isScript && !ctx.contentInfo.isFileDownload;
    }
  
    processResource(html, ctx, charset, urlReplacer) {
      const processingOpts = PageProcessor._getPageProcessingOptions(ctx, urlReplacer);
  
      const bom = (0, _getBom.default)(html);
      html = bom ? html.replace(bom, '') : html;
  
      PageProcessor._prepareHtml(html, processingOpts);
  
      const root = _parse.default.parse(html);
  
      const domAdapter = new _parse5DomAdapter.default(processingOpts.isIframe, processingOpts.crossDomainProxyPort);
      const elements = parse5Utils.findElementsByTagNames(root, ['base', 'meta', 'head', 'body', 'frameset']);
      const base = elements.base ? elements.base[0] : null;
      const baseUrl = base ? domAdapter.getAttr(base, 'href') : '';
      const metas = elements.meta;
      const head = elements.head[0];
      const body = elements.body ? elements.body[0] : elements.frameset[0];
      if (metas && charset.fromMeta(PageProcessor._getPageMetas(metas, domAdapter))) return this.RESTART_PROCESSING;
      const domProcessor = new _dom.default(domAdapter);
  
      const replacer = (resourceUrl, resourceType, charsetAttrValue) => urlReplacer(resourceUrl, resourceType, charsetAttrValue, baseUrl);
  
      domProcessor.forceProxySrcForImage = ctx.session.hasRequestEventListeners();
      domProcessor.allowMultipleWindows = ctx.session.allowMultipleWindows;
      parse5Utils.walkElements(root, el => domProcessor.processElement(el, replacer));
  
      if (!ctx.isHtmlImport) {
        PageProcessor._addPageResources(head, processingOpts);
  
        this._addBodyCreatedEventScript(body);
  
        if (ctx.restoringStorages && !processingOpts.isIframe) this._addRestoreStoragesScript(ctx, head);
      }
  
      PageProcessor._changeMetas(metas, domAdapter);
  
      PageProcessor._addCharsetInfo(head, charset.get());
  
      return (bom || '') + _parse.default.serialize(root);
    }
  
  }
  
  var _default = new PageProcessor();
  
  exports.default = _default;
  module.exports = exports.default;