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