Manual Reference Source Test

src/templates/iframe-modal.js

import {buildRuleFromGradient} from '../helpers/gradient';

const baseId = 'identity-window-iframe';
export const iFrameWrapperId = `${baseId}-wrapper`;

const createElement = (id, elementType = 'div') => {
  const element = document.createElement(elementType);
  element.id = id;
  return element;
};

const createIFrameElement = (url) => {
  const iframe = createElement(baseId, 'iframe');
  iframe.src = url;
  iframe.frameBorder = 0;

  return iframe;
};

const createTopbar = (themeConfig, closeCallback, isManageProfile) => {
  const iconColor = (themeConfig.iFrameModal || {}).iconColor || '#f1f1f1';

  const closeButton = createElement(`${baseId}-close-button`, 'button');
  closeButton.ariaLabel = 'Close NBCUniversal Identity Dialog';
  closeButton.onclick = closeCallback;
  closeButton.innerHTML = `
    <svg xmlns="http://www.w3.org/2000/svg" width="20" height="20" viewBox="0 0 20 20">
      <path
        fill="${iconColor}"
        fill-rule="evenodd"
        d="M.224 17.846L8.75 9.559.224 1.282C.074 1.137 0 .96 0 .75 0 .54.075.363.224.217.374.073.557
0 .772 0c.216 0 .398.073.548.217l8.514 8.287L18.357.217c.15-.144.332-.217.546-.217.214 0
.394.073.54.217.15.146.224.323.224.533 0 .21-.075.387-.224.532L10.929 9.56l8.514
8.287c.15.145.224.321.224.527 0 .207-.075.382-.224.528-.143.149-.323.223-.54.223-.221
0-.403-.074-.546-.223l-8.523-8.277-8.514 8.277c-.153.149-.335.223-.545.223-.214
0-.398-.074-.55-.223-.15-.146-.225-.321-.225-.528 0-.206.075-.382.224-.527z"
      />
    </svg>
  `;

  const topbar = createElement(`${baseId}-topbar`);
  let topbarHeading = createElement(`${baseId}-topbar-spacing`, 'div');

  if (isManageProfile && themeConfig.manageProfile) {
    topbarHeading = createElement(`${baseId}-topbar-heading`, 'h1');
    topbarHeading.innerHTML = themeConfig.manageProfile.iframeTitle;
    topbarHeading.tabIndex = -1;
    topbar.classList.add('is-manage-profile');
  }

  topbar.appendChild(topbarHeading);
  topbar.appendChild(closeButton);

  return topbar;
};

const createTitlebar = (themeConfig, isManageProfile) => {
  if (!isManageProfile || !(themeConfig.manageProfile || {}).iframeHeader) return;

  const titlebar = createElement(`${baseId}-titlebar`);
  const titlebarHeading = createElement(`${baseId}-titlebar-heading`, 'h2');
  titlebarHeading.innerHTML = (themeConfig.manageProfile || {}).iframeHeader;

  titlebar.appendChild(titlebarHeading);

  return titlebar;
};

export const addIFrameModal = (url, themeConfig, closeCallback, isManageProfile) => {
  const existingIframe = document.getElementById(iFrameWrapperId);
  if (existingIframe) return existingIframe.querySelector('iframe');

  const iframe = createIFrameElement(url);
  const topbar = createTopbar(themeConfig, closeCallback, isManageProfile);
  const titlebar = createTitlebar(themeConfig, isManageProfile);

  const inner = createElement(`${baseId}-inner`);
  const modal = createElement(`${baseId}-modal`);
  const wrapper = createElement(iFrameWrapperId);

  inner.appendChild(topbar);
  if (titlebar) inner.appendChild(titlebar);
  inner.appendChild(iframe);
  modal.appendChild(inner);
  wrapper.appendChild(modal);

  document.body.appendChild(wrapper);
  document.body.style.overflow = 'hidden';

  const focusHeading = document.getElementById(`${baseId}-topbar-heading`);
  if (focusHeading) focusHeading.focus();

  return iframe;
};

export const addIFrameModalStyle = (themeConfig) => new Promise((resolve) => {
  const styleId = 'identity-window-style';

  const existingStyleBlock = document.getElementById(styleId);
  if (existingStyleBlock) return resolve(existingStyleBlock);

  const {manageProfile = {}, iFrameModal = {}} = themeConfig;
  const profileGradient = manageProfile.gradient
    && buildRuleFromGradient(manageProfile.gradient);
  const modalBackground = iFrameModal.modalBackground || '#000';
  const fillBackground = iFrameModal.fillBackground || 'rgba(0, 0, 0, 0.75)';
  const topbarColor = manageProfile.titleColor || '#fff';
  const titlebarColor = manageProfile.headerColor || '#fff';
  const titlebarBackground = manageProfile.headerBackgroundColor || '#313134';

  const styleBlock = createElement(styleId, 'style');
  styleBlock.type = 'text/css';
  styleBlock.appendChild(document.createTextNode(`
    #${baseId} {
      width: 100%;
      height: 100%;
      background: ${modalBackground};
    }

    #${baseId}-inner {
      width: 100%;
      height: 100%;
      display: flex;
      flex-direction: column;
      overflow: hidden;
    }

    #${baseId}-modal {
      height: 100%;
      width: 100%;
      max-width: 100%;
      background: ${modalBackground};
      box-sizing: border-box;
    }

    #${baseId}-wrapper {
      position: fixed;
      top: 0;
      left: 0;
      display: flex;
      align-items: flex-start;
      justify-content: center;
      width: 100vw;
      height: 100%;
      background: ${fillBackground};
      z-index: 9999999;
    }

    #${baseId}-topbar {
      display: flex;
      align-items: center;
      justify-content: space-between;
      height: 58px;
      width: 100%;
      background: ${modalBackground};
    }

    #${baseId}-topbar.is-manage-profile {
      background: ${profileGradient}
    }

    #${baseId}-topbar-heading {
      margin: 0;
      padding: 0 15px;
      font-family: 'Source Sans Pro', sans-serif;
      font-size: 20px;
      font-weight: 400;
      color: ${topbarColor};
    }

    #${baseId}-topbar-heading:focus {
      outline: none;
      box-shadow: none;
    }

    #${baseId}-close-button {
      width: 54px;
      height: 58px;
      margin: 0;
      padding: 8px;
      appearance: none;
      -webkit-appearance: none;
      background: none;
      border: none;
      cursor: pointer;
    }

    #${baseId}-titlebar {
      padding: 6px 15px 12px;
      width: 100%;
      background: ${titlebarBackground};
      box-sizing: border-box;
    }

    #${baseId}-titlebar-heading {
      margin: 0;
      font-family: 'Source Sans Pro', sans-serif;
      font-size: 16px;
      font-weight: normal;
      line-height: 1.6;
      color: ${titlebarColor};
    }

    @media screen and (min-width: 376px) {
      #${baseId}-modal {
        margin-top: 30px;
        height: calc(100% - 70px);
        max-height: 825px;
        width: 375px;
      }
    }
  `));

  styleBlock.addEventListener('load', () => resolve(styleBlock));

  document.head.appendChild(styleBlock);
});