Home Reference Source

src/formats/vignette.js

import { cpexLog, addIframe, addStyle, addElement, setCookie } from '../utils.js'

/**
 * Wraps an HTML banner and slides it from the bottom up, with a close button. Moreover it blocks content of the website.
 * It requires vignette settings (with a target elementId) to be present.
 */
export default class Vignette {
  constructor (elementId, adUnit, main, width, height) {
    this.main = main
    this.type = 'vignette'
    this.adUnit = adUnit
    this.elementId = elementId
    this.settings = main.settings.formats.vignette
    this.loaded = false
    this.width = width
    this.height = height
    this.iframeCSS = 'margin:auto; border:none; display:block; overflow:hidden; position:relative; top:50%; transform:translateY(-50%);' // Needed for HB reRender
    cpexLog('Vignette: Caught Vignette custom format, in elementId ' + elementId)
  }

  resize () {
    if (this.width > document.documentElement.clientWidth) {
      const scale = document.documentElement.clientWidth / this.width
      this.iframe.style.transform = `scale(${scale}) translateY(-50%)` // needed for HB rerender
      this.iframe.style.transformOrigin = 'left top'
    }
  }

  /**
   * Places the vignette container into the page
   */
  renderIframe () {
    const backgroundEl = this.settings.backgroundEl || document.body

    // Add wrapper element
    this.element = addElement('div', backgroundEl, { id: 'cpex-vignette' })
    this.element.style.cssText = 'position: fixed; top: 0px; left: 0px; width: 100%; height: 100%; text-align: center'

    // Label the original element as moved, for tag rendering
    const targetEl = document.getElementById(this.elementId)
    targetEl.setAttribute('data-target-id-moved', this.element.id)
    targetEl.style.display = 'none'

    // Style wrapper
    addStyle(document, (typeof this.settings !== 'undefined' && this.settings.css) || defaultCSS)

    // Header (just an optional background, hidden by default)
    this.header = addElement('div', this.element, { id: 'cpex-vignette-header', innerHTML: 'reklama' })

    // Close button
    this.closeButton = addElement('button', this.element, { id: 'cpex-vignette-close', tabIndex: 0, innerHTML: this.main.texts.vignetteClose || this.main.texts.interstitialClose || 'Zavřít reklamu' })
    this.closeButton.focus()
    this.closeButton.addEventListener('click', () => { this.reset() })
    this.closeButton.addEventListener('keyup', (event) => { if (event.key === 'Enter' || event.key === 'Spacebar' || event.key === 'Escape') { this.reset() } })

    // Add iframe
    this.iframe = addIframe(this.element, { id: this.elementId + '-iframe', width: 1, height: 1 }, () => { // onload callback
      this.loaded = true
      cpexLog('Vignette: Rendered')
      // Respond to prevent failsafe rendering
      const response = { response: 'cpexHTML5', caf: true }
      this.iframe.contentWindow.postMessage(response, '*')
    })
    this.iframe.style.cssText = this.iframeCSS
    this.iframe.style.width = this.width + 'px'
    this.iframe.style.height = this.height + 'px'
    // Resizing
    this.resize()
    window.addEventListener('resize', () => this.resize())

    // Set cookie
    if (this.settings.cookieName && this.settings.cookieDuration) {
      setCookie(this.settings.cookieName, this.settings.cookieDuration)
    }

    return this.iframe
  }

  /**
   * Returns the page to its original state
   */
  reset () {
    // trigger custom event on window
    window.dispatchEvent(new window.Event('cpex:vignette:close')) // used by vlm
    const ads = window.cpexPackage.customAds
    if (ads) { delete ads[this.elementId] }
    this.element.remove()
  }
}

const defaultCSS = `
  #cpex-vignette {
    background-color: #000D;
    z-index: 999999;
  }
    #cpex-vignette-header {
      display: none;
    }
    #cpex-vignette-close {
      position: fixed;
      right: 20px;
      top: 20px;
      box-sizing: border-box;
      display: inline-block;
      cursor: pointer;
      height: 40px;
      padding: 10px;
      font-size: 12pt;
      border: none;
      background-color: #FFFC;
      border-radius: 4px;
      color: #000;
      z-index: 9999999;
    }
      #cpex-vignette-close:hover {
        background-color: #FFF;
      }
`

// the span is a fake button, the link wrapper is triggered on click