1329 lines
44 KiB
JavaScript
1329 lines
44 KiB
JavaScript
(function() {
|
|
'use strict';
|
|
|
|
const AIOVGTemplate = document.createElement( 'template' );
|
|
|
|
AIOVGTemplate.innerHTML = `
|
|
<style>
|
|
:host {
|
|
display: block;
|
|
width: 100%;
|
|
contain: content;
|
|
}
|
|
|
|
:host([hidden]) {
|
|
display: none;
|
|
}
|
|
|
|
#root {
|
|
display: block;
|
|
position: relative;
|
|
cursor: pointer;
|
|
padding-bottom: calc(100% / (16 / 9));
|
|
width: 100%;
|
|
height: 0;
|
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
|
|
}
|
|
|
|
#posterimage,
|
|
iframe {
|
|
position: absolute;
|
|
top: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 100%;
|
|
}
|
|
|
|
#posterimage {
|
|
object-fit: cover;
|
|
transition: 0.3s;
|
|
opacity: 1;
|
|
}
|
|
|
|
iframe {
|
|
z-index: 1;
|
|
border: 0;
|
|
}
|
|
|
|
#playbutton {
|
|
display: none;
|
|
}
|
|
|
|
/* YouTube */
|
|
.youtube > #playbutton {
|
|
display: block;
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate3d(-50%, -50%, 0);
|
|
transition: all 0.2s cubic-bezier(0, 0, 0.2, 1);
|
|
z-index: 1;
|
|
border: 0;
|
|
background: center/72px 48px no-repeat url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 72 48'%3E%3Cpath fill='%23f00' fill-opacity='.9' d='M66.5 7.7c-.8-2.9-2.5-5.4-5.4-6.2C55.8.1 34 0 34 0S12.2.1 6.9 1.6c-3 .7-4.6 3.2-5.4 6.1a89.6 89.6 0 000 32.5c.8 3 2.5 5.5 5.4 6.3C12.2 47.9 34 48 34 48s21.8-.1 27.1-1.6c3-.7 4.6-3.2 5.4-6.1C68 35 68 24 68 24s0-11-1.5-16.3z'/%3E%3Cpath fill='%23fff' d='M45 24L27 14v20'/%3E%3C/svg%3E");
|
|
cursor: pointer;
|
|
width: 72px;
|
|
height: 48px;
|
|
filter: grayscale(1);
|
|
}
|
|
|
|
.youtube:hover > #playbutton,
|
|
.youtube > #playbutton:focus {
|
|
filter: none;
|
|
}
|
|
|
|
/* Vimeo */
|
|
.vimeo > #playbutton {
|
|
display: flex;
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
align-items: center;
|
|
justify-content: center;
|
|
transform: translate3d(-50%, -50%, 0);
|
|
transition: all 0.2s cubic-bezier(0, 0, 0.2, 1);
|
|
opacity: 0.8;
|
|
z-index: 1;
|
|
border: 0;
|
|
border-radius: 8px;
|
|
background: rgba(23, 35, 34, .75);
|
|
cursor: pointer;
|
|
width: 72px;
|
|
height: 48px;
|
|
}
|
|
|
|
.vimeo > #playbutton:after {
|
|
border-width: 10px 0 10px 20px;
|
|
border-style: solid;
|
|
border-color: transparent transparent transparent #fff;
|
|
content: "";
|
|
}
|
|
|
|
.vimeo:hover > #playbutton,
|
|
.vimeo > #playbutton:focus {
|
|
opacity: 1;
|
|
background: rgb(98, 175, 237);
|
|
}
|
|
|
|
/* Dailymotion */
|
|
.dailymotion > #playbutton {
|
|
display: block;
|
|
position: absolute;
|
|
top: 50%;
|
|
left: 50%;
|
|
transform: translate3d(-50%, -50%, 0);
|
|
transition: all 0.2s cubic-bezier(0, 0, 0.2, 1);
|
|
opacity: 1;
|
|
z-index: 1;
|
|
border: 0;
|
|
border-radius: 40px;
|
|
background-color: rgba(13, 13, 13, 0.6);
|
|
background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8.56047 5.09337C8.34001 4.9668 8.07015 4.96875 7.85254 5.10019C7.63398 5.23162 7.5 5.47113 7.5 5.73011L7.5 18.2698C7.5 18.5298 7.63398 18.7693 7.85254 18.9007C7.96372 18.9669 8.0882 19 8.21268 19C8.33241 19 8.45309 18.9688 8.56047 18.9075L18.1351 12.6377C18.3603 12.5082 18.5 12.2648 18.5 12C18.5 11.7361 18.3603 11.4917 18.1351 11.3632L8.56047 5.09337Z' fill='%23fff'%3E%3C/path%3E%3C/svg%3E");
|
|
background-position: center;
|
|
background-size: 64px;
|
|
cursor: pointer;
|
|
width: 80px;
|
|
height: 80px;
|
|
}
|
|
|
|
.dailymotion:hover > #playbutton,
|
|
.dailymotion > #playbutton:focus {
|
|
opacity: 0.8;
|
|
}
|
|
|
|
/* Cookie consent */
|
|
#cookieconsent-modal {
|
|
display: none;
|
|
position: absolute;
|
|
inset: 0;
|
|
z-index: 1;
|
|
align-items: flex-start;
|
|
justify-content: center;
|
|
background-color: rgba(0, 0, 0, 0.85);
|
|
width: 100%;
|
|
height: 100%;
|
|
overflow-y: auto;
|
|
line-height: 1.5;
|
|
color: #fff;
|
|
font-size: 14px;
|
|
}
|
|
|
|
#root.cookieconsent {
|
|
cursor: unset;
|
|
}
|
|
|
|
#root.cookieconsent > #playbutton {
|
|
display: none;
|
|
}
|
|
|
|
#root.cookieconsent > #cookieconsent-modal {
|
|
display: flex;
|
|
}
|
|
|
|
.cookieconsent-block {
|
|
box-sizing: border-box;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
margin: auto;
|
|
padding: 16px 24px;
|
|
width: 100%;
|
|
max-width: 480px;
|
|
text-align: center;
|
|
}
|
|
|
|
.cookieconsent-button,
|
|
.cookieconsent-button:hover,
|
|
.cookieconsent-button:focus {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border: 0;
|
|
border-radius: 3px;
|
|
box-shadow: none;
|
|
background: none;
|
|
background-color: var(--aiovg-color-primary, #3b82f6);
|
|
background-image: none;
|
|
cursor: pointer;
|
|
padding: 0 20px;
|
|
min-height: 44px;
|
|
line-height: 1;
|
|
color: #fff;
|
|
font-family: inherit;
|
|
font-size: 1em;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.cookieconsent-button:hover {
|
|
opacity: 0.85;
|
|
}
|
|
|
|
/* Email Capture */
|
|
#email-capture-modal {
|
|
display: none;
|
|
position: absolute;
|
|
inset: 0;
|
|
z-index: 2;
|
|
align-items: flex-start;
|
|
justify-content: center;
|
|
background-color: rgba(0, 0, 0, 0.85);
|
|
width: 100%;
|
|
height: 100%;
|
|
overflow-y: auto;
|
|
line-height: 1.5;
|
|
color: #fff;
|
|
font-size: 14px;
|
|
}
|
|
|
|
#root.email-capture {
|
|
cursor: unset;
|
|
}
|
|
|
|
#root.email-capture > #playbutton {
|
|
display: none;
|
|
}
|
|
|
|
#root.email-capture > #email-capture-modal {
|
|
display: flex;
|
|
}
|
|
|
|
.email-capture {
|
|
display: contents;
|
|
}
|
|
|
|
.email-capture-block {
|
|
box-sizing: border-box;
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 12px;
|
|
margin: auto;
|
|
padding: 16px 24px;
|
|
width: 100%;
|
|
max-width: 480px;
|
|
}
|
|
|
|
.email-capture-header {
|
|
text-align: center;
|
|
text-shadow: 0 1px 4px rgba(0, 0, 0, 0.8);
|
|
font-size: 1.15em;
|
|
}
|
|
|
|
.email-capture-fields {
|
|
display: flex;
|
|
flex-direction: column;
|
|
gap: 8px;
|
|
}
|
|
|
|
.email-capture-fields input {
|
|
box-sizing: border-box;
|
|
display: block;
|
|
border: 1px solid rgba(255, 255, 255, 0.3);
|
|
border-radius: 3px;
|
|
background: rgba(255, 255, 255, 0.12);
|
|
padding: 0 12px;
|
|
width: 100%;
|
|
min-height: 44px;
|
|
line-height: 1;
|
|
color: #fff;
|
|
font-family: inherit;
|
|
font-size: 1em;
|
|
}
|
|
|
|
.email-capture-fields input::placeholder {
|
|
color: rgba(255, 255, 255, 0.5);
|
|
}
|
|
|
|
.email-capture-fields input:focus {
|
|
outline: none;
|
|
border-color: rgba(255, 255, 255, 0.6);
|
|
background: rgba(255, 255, 255, 0.18);
|
|
}
|
|
|
|
.email-capture-email.is-invalid {
|
|
border-color: #ff7070;
|
|
}
|
|
|
|
.email-capture-error {
|
|
display: none;
|
|
margin-top: -4px;
|
|
color: #ff7070;
|
|
font-size: 0.875em;
|
|
}
|
|
|
|
.email-capture-error::before {
|
|
content: "⚠";
|
|
margin-right: 5px;
|
|
}
|
|
|
|
.email-capture-footer {
|
|
margin-top: -4px;
|
|
line-height: 1.4;
|
|
color: rgba(255, 255, 255, 0.55);
|
|
font-size: 0.875em;
|
|
}
|
|
|
|
.email-capture-footer a {
|
|
color: rgba(255, 255, 255, 0.75);
|
|
text-decoration: underline;
|
|
}
|
|
|
|
.email-capture-actions {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
align-items: center;
|
|
justify-content: center;
|
|
gap: 12px;
|
|
}
|
|
|
|
.email-capture-submit,
|
|
.email-capture-submit:hover,
|
|
.email-capture-submit:focus {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
border: 0;
|
|
border-radius: 3px;
|
|
box-shadow: none;
|
|
background: none;
|
|
background-color: var(--aiovg-color-primary, #3b82f6);
|
|
background-image: none;
|
|
cursor: pointer;
|
|
padding: 0 20px;
|
|
min-height: 44px;
|
|
line-height: 1;
|
|
color: #fff;
|
|
font-family: inherit;
|
|
font-size: 1em;
|
|
font-weight: 600;
|
|
}
|
|
|
|
.email-capture-submit:hover {
|
|
opacity: 0.85;
|
|
}
|
|
|
|
.email-capture-skip {
|
|
display: inline-flex;
|
|
align-items: center;
|
|
cursor: pointer;
|
|
text-decoration: underline;
|
|
color: rgba(255, 255, 255, 0.6);
|
|
font-size: 0.875em;
|
|
}
|
|
|
|
.email-capture-skip:hover {
|
|
color: #fff;
|
|
}
|
|
|
|
@keyframes spin {
|
|
to { transform: rotate( 360deg ); }
|
|
}
|
|
|
|
.is-loading .email-capture-block * {
|
|
display: none !important;
|
|
}
|
|
|
|
.is-loading .email-capture-block {
|
|
pointer-events: none;
|
|
margin: auto;
|
|
border: 3px solid rgba( 255, 255, 255, 0.25 );
|
|
border-radius: 50%;
|
|
border-top-color: #fff;
|
|
padding: 0;
|
|
width: 36px;
|
|
height: 36px;
|
|
animation: spin 0.7s linear infinite;
|
|
}
|
|
|
|
/* Post-click styles */
|
|
#root.initialized {
|
|
cursor: unset;
|
|
}
|
|
|
|
#root.initialized > #posterimage,
|
|
#root.initialized > #playbutton {
|
|
pointer-events: none;
|
|
opacity: 0;
|
|
}
|
|
</style>
|
|
<div id="root">
|
|
<img id="posterimage" src="data:image/gif;base64,R0lGODlhAQABAIAAAAUEBAAAACwAAAAAAQABAAACAkQBADs=" alt="" referrerpolicy="origin" />
|
|
<button type="button" id="playbutton" aria-label="Play Video"></button>
|
|
<div id="cookieconsent-modal">
|
|
<div class="cookieconsent-block">
|
|
<div><slot name="cookieconsent-message"></slot></div>
|
|
<div>
|
|
<button type="button" id="cookieconsent-button" class="cookieconsent-button">
|
|
<slot name="cookieconsent-button-label">I Agree</slot>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div id="email-capture-modal"></div>
|
|
</div>
|
|
`;
|
|
|
|
class AIOVGBaseElement extends HTMLElement {
|
|
|
|
/**
|
|
* Element created.
|
|
*/
|
|
constructor() {
|
|
super();
|
|
|
|
// Attach Shadow DOM to the component
|
|
const shadowDom = this.attachShadow({ mode: 'open' });
|
|
this.shadowRoot.appendChild( AIOVGTemplate.content.cloneNode( true ) );
|
|
|
|
// Set references to the DOM elements from the component's template
|
|
this.$root = shadowDom.querySelector( '#root' );
|
|
this.$posterImage = shadowDom.querySelector( '#posterimage' );
|
|
this.$playButton = shadowDom.querySelector( '#playbutton' );
|
|
this.$cookieConsentButton = shadowDom.querySelector( '#cookieconsent-button' );
|
|
this.$emailCaptureModal = shadowDom.querySelector( '#email-capture-modal' );
|
|
|
|
// Set references to the private properties used by the component
|
|
this._isRendered = false;
|
|
this._ajaxUrl = aiovg_embed.ajax_url;
|
|
this._ajaxNonce = aiovg_embed.ajax_nonce;
|
|
this._isCookieConsentLoaded = false;
|
|
this._isEmailCaptureLoaded = false;
|
|
this._isPosterImageLoaded = false;
|
|
this._isIframeLoaded = false;
|
|
this._forceIframeElement = navigator.vendor.includes( 'Apple' ) || navigator.userAgent.includes( 'Mobi' );
|
|
this._intersectionObserver = null;
|
|
this._isInViewport = false;
|
|
}
|
|
|
|
/**
|
|
* Browser calls this method when the element is added to the document.
|
|
* (can be called many times if an element is repeatedly added/removed)
|
|
*/
|
|
connectedCallback() {
|
|
if ( ! this.src ) return false;
|
|
|
|
if ( ! this.lazyLoading ) {
|
|
this._forceIframeElement = true;
|
|
}
|
|
|
|
if ( ! this.poster ) {
|
|
this._forceIframeElement = true;
|
|
}
|
|
|
|
if ( ! this._forceIframeElement ) {
|
|
const url = new URL( this.src );
|
|
const query = new URLSearchParams( url.search );
|
|
const autoplayRequested = query.has( 'autoplay' ) && ( query.get( 'autoplay' ) == 1 || query.get( 'autoplay' ) == true );
|
|
|
|
if ( autoplayRequested ) this._forceIframeElement = true;
|
|
}
|
|
|
|
this._render();
|
|
|
|
this.addEventListener( 'pointerover', () => this._warmConnections(), { once: true, } );
|
|
this.addEventListener( 'click', () => this._addIframe( true ) );
|
|
}
|
|
|
|
/**
|
|
* Browser calls this method when the element is removed from the document.
|
|
* (can be called many times if an element is repeatedly added/removed)
|
|
*/
|
|
disconnectedCallback() {
|
|
// TODO
|
|
}
|
|
|
|
/**
|
|
* Array of attribute names to monitor for changes.
|
|
*/
|
|
static get observedAttributes() {
|
|
return [ 'title', 'ratio' ];
|
|
}
|
|
|
|
/**
|
|
* Called when one of the observed attributes listed above is modified.
|
|
*/
|
|
attributeChangedCallback( name, oldValue, newValue ) {
|
|
if ( oldValue == newValue ) return false;
|
|
|
|
switch ( name ) {
|
|
case 'title':
|
|
// Set attributes for accessibility
|
|
if ( newValue ) {
|
|
this.$posterImage.setAttribute( 'alt', newValue );
|
|
} else {
|
|
this.$posterImage.setAttribute( 'alt', '' );
|
|
}
|
|
break;
|
|
|
|
case 'ratio':
|
|
if ( newValue ) {
|
|
this.$root.style.paddingBottom = `${parseFloat(newValue)}%`;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Define getters and setters for attributes.
|
|
*/
|
|
|
|
get title() {
|
|
return this.getAttribute( 'title' ) || '';
|
|
}
|
|
|
|
get src() {
|
|
const value = this.getAttribute( 'src' ) || '';
|
|
return AIOVGBaseElement.isValidUrl( value ) ? value : '';
|
|
}
|
|
|
|
get poster() {
|
|
const value = this.getAttribute( 'poster' ) || '';
|
|
return AIOVGBaseElement.isValidUrl( value ) ? value : '';
|
|
}
|
|
|
|
get postId() {
|
|
return parseInt( this.getAttribute( 'post_id' ) || 0 );
|
|
}
|
|
|
|
get postType() {
|
|
return this.getAttribute( 'post_type' ) || '';
|
|
}
|
|
|
|
get lazyLoading() {
|
|
return this.hasAttribute( 'lazyloading' );
|
|
}
|
|
|
|
get statistics() {
|
|
return this.hasAttribute( 'statistics' );
|
|
}
|
|
|
|
get cookieConsent() {
|
|
return this.hasAttribute( 'cookieconsent' );
|
|
}
|
|
|
|
set cookieConsent( value ) {
|
|
const isEnabled = Boolean( value );
|
|
|
|
if ( isEnabled ) {
|
|
this.setAttribute( 'cookieconsent', '' );
|
|
} else {
|
|
this.removeAttribute( 'cookieconsent' );
|
|
}
|
|
}
|
|
|
|
get emailCapture() {
|
|
return this.hasAttribute( 'email-capture' );
|
|
}
|
|
|
|
set emailCapture( value ) {
|
|
const isEnabled = Boolean( value );
|
|
|
|
if ( isEnabled ) {
|
|
this.setAttribute( 'email-capture', '' );
|
|
} else {
|
|
this.removeAttribute( 'email-capture' );
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Define private methods.
|
|
*/
|
|
|
|
_render() {
|
|
if ( this._isRendered ) return false;
|
|
|
|
if ( this.lazyLoading && ! this._isInViewport ) {
|
|
this._initIntersectionObserver();
|
|
return false;
|
|
}
|
|
|
|
if ( this.emailCapture ) {
|
|
this._addEmailCapture();
|
|
return false;
|
|
}
|
|
|
|
if ( this.cookieConsent ) {
|
|
this._addCookieConsent();
|
|
return false;
|
|
}
|
|
|
|
this._isRendered = true;
|
|
|
|
if ( this._forceIframeElement ) {
|
|
this._warmConnections();
|
|
this._addIframe();
|
|
} else {
|
|
this._addPosterImage();
|
|
}
|
|
}
|
|
|
|
_addCookieConsent() {
|
|
if ( this._isCookieConsentLoaded ) return false;
|
|
this._isCookieConsentLoaded = true;
|
|
|
|
this._addPosterImage();
|
|
this._addClass( 'cookieconsent' );
|
|
|
|
this.$cookieConsentButton.addEventListener( 'click', () => this._onCookieConsent() );
|
|
}
|
|
|
|
_onCookieConsent() {
|
|
this._isRendered = true;
|
|
|
|
this._removeClass( 'cookieconsent' );
|
|
this.cookieConsent = false;
|
|
|
|
this._warmConnections();
|
|
this._addIframe( true );
|
|
|
|
this._setCookie();
|
|
|
|
// Remove cookieconsent from other players
|
|
const videos = document.querySelectorAll( '.aiovg-player-element' );
|
|
for ( let i = 0; i < videos.length; i++ ) {
|
|
videos[ i ].removeCookieConsent();
|
|
}
|
|
|
|
window.postMessage({
|
|
message: 'aiovg-cookie-consent'
|
|
}, window.location.origin );
|
|
}
|
|
|
|
_addEmailCapture() {
|
|
if ( this._isEmailCaptureLoaded ) return false;
|
|
this._isEmailCaptureLoaded = true;
|
|
|
|
// Read template from light DOM child placed by PHP
|
|
const templateEl = this.querySelector( 'template.aiovg-player-template' );
|
|
if ( ! templateEl ) return false;
|
|
|
|
// Clone HTML from template into shadow DOM
|
|
const emailCaptureEl = templateEl.content.querySelector( '.email-capture' );
|
|
if ( ! emailCaptureEl ) return false;
|
|
|
|
// Move all children of email capture block into the email capture modal container in the shadow DOM
|
|
this.$emailCaptureModal.appendChild( emailCaptureEl.cloneNode( true ) );
|
|
|
|
// Add poster image if available and enable the email capture modal by adding the corresponding class to the root element
|
|
this._addPosterImage();
|
|
this._addClass( 'email-capture' );
|
|
|
|
// Focus the first input for better accessibility
|
|
const firstInput = this.$emailCaptureModal.querySelector( 'input' );
|
|
if ( firstInput ) {
|
|
firstInput.focus();
|
|
}
|
|
|
|
// Submit handler
|
|
const submitBtn = this.$emailCaptureModal.querySelector( '.email-capture-submit' );
|
|
|
|
if ( submitBtn ) {
|
|
submitBtn.addEventListener( 'click', () => {
|
|
const emailField = this.$emailCaptureModal.querySelector( '.email-capture-email' );
|
|
const errorSpan = this.$emailCaptureModal.querySelector( '.email-capture-error' );
|
|
|
|
const email = emailField ? emailField.value.trim() : '';
|
|
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
|
|
if ( ! email || ! regex.test( email ) ) {
|
|
if ( errorSpan ) {
|
|
const errorMessage = errorSpan.getAttribute( 'data-invalid_email' ) || 'Please enter a valid email address.';
|
|
|
|
errorSpan.textContent = errorMessage;
|
|
errorSpan.style.display = 'block';
|
|
}
|
|
|
|
if ( emailField ) {
|
|
emailField.classList.add( 'is-invalid' );
|
|
emailField.setAttribute( 'aria-invalid', 'true' );
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
if ( errorSpan ) {
|
|
errorSpan.style.display = 'none';
|
|
}
|
|
|
|
if ( emailField ) {
|
|
emailField.classList.remove( 'is-invalid' );
|
|
emailField.removeAttribute( 'aria-invalid' );
|
|
}
|
|
|
|
let params = 'email=' + encodeURIComponent( email );
|
|
|
|
const nameField = this.$emailCaptureModal.querySelector( '.email-capture-name' );
|
|
if ( nameField && nameField.value.trim() ) {
|
|
params += '&name=' + encodeURIComponent( nameField.value.trim() );
|
|
}
|
|
|
|
const phoneField = this.$emailCaptureModal.querySelector( '.email-capture-phone' );
|
|
if ( phoneField && phoneField.value.trim() ) {
|
|
params += '&phone=' + encodeURIComponent( phoneField.value.trim() );
|
|
}
|
|
|
|
if ( 'aiovg_videos' === this.postType && this.postId ) {
|
|
params += '&video_id=' + encodeURIComponent( this.postId );
|
|
} else {
|
|
params += '&video_id=0';
|
|
|
|
if ( this.src ) {
|
|
params += '&video_url=' + encodeURIComponent( this.src );
|
|
}
|
|
|
|
}
|
|
|
|
params += '&page_url=' + encodeURIComponent( window.location.href );
|
|
|
|
this._onEmailCapture( params );
|
|
} );
|
|
}
|
|
|
|
// Skip handler
|
|
const skipLink = this.$emailCaptureModal.querySelector( '.email-capture-skip' );
|
|
|
|
if ( skipLink ) {
|
|
const doSkip = () => {
|
|
this._onEmailCapture( 'skipped=1' );
|
|
};
|
|
|
|
skipLink.addEventListener( 'click', doSkip );
|
|
|
|
skipLink.addEventListener( 'keydown', ( event ) => {
|
|
if ( 13 === event.keyCode || 32 === event.keyCode ) {
|
|
event.preventDefault();
|
|
doSkip();
|
|
}
|
|
} );
|
|
}
|
|
}
|
|
|
|
_onEmailCapture( data ) {
|
|
if ( this.$emailCaptureModal.classList.contains( 'is-loading' ) ) return false; // Prevent multiple submissions
|
|
this.$emailCaptureModal.classList.add( 'is-loading' );
|
|
|
|
const xmlhttp = new XMLHttpRequest();
|
|
|
|
xmlhttp.onreadystatechange = () => {
|
|
if ( 4 == xmlhttp.readyState ) {
|
|
let response = null;
|
|
|
|
if ( 200 == xmlhttp.status && xmlhttp.responseText ) {
|
|
try {
|
|
response = JSON.parse( xmlhttp.responseText );
|
|
} catch ( e ) {}
|
|
}
|
|
|
|
if ( response && response.success ) {
|
|
// Email captured successfully, proceed to load the video and remove the email capture gate
|
|
this._isRendered = true;
|
|
|
|
this._removeClass( 'email-capture' );
|
|
this.emailCapture = false;
|
|
|
|
this._warmConnections();
|
|
this._addIframe( true );
|
|
|
|
// Email submission implies consent — remove both gates from other players
|
|
const videos = document.querySelectorAll( '.aiovg-player-element' );
|
|
for ( let i = 0; i < videos.length; i++ ) {
|
|
videos[ i ].removeCookieConsent();
|
|
videos[ i ].removeEmailCapture();
|
|
}
|
|
|
|
window.postMessage({
|
|
message: 'aiovg-email-captured'
|
|
}, window.location.origin );
|
|
} else {
|
|
// Show error message
|
|
const errorSpan = this.$emailCaptureModal.querySelector( '.email-capture-error' );
|
|
|
|
if ( errorSpan ) {
|
|
errorSpan.textContent = ( response && response.data && typeof response.data === 'string' ) ? response.data : errorSpan.getAttribute( 'data-error_generic' );
|
|
errorSpan.style.display = 'block';
|
|
}
|
|
|
|
// Restore the form so the user can retry.
|
|
this.$emailCaptureModal.classList.remove( 'is-loading' );
|
|
}
|
|
}
|
|
};
|
|
|
|
xmlhttp.open( 'POST', this._ajaxUrl + '?action=aiovg_save_email_lead&security=' + this._ajaxNonce, true );
|
|
xmlhttp.setRequestHeader( 'Content-type', 'application/x-www-form-urlencoded' );
|
|
xmlhttp.send( data );
|
|
}
|
|
|
|
_addPosterImage() {
|
|
if ( this._isPosterImageLoaded ) return false;
|
|
this._isPosterImageLoaded = true;
|
|
|
|
if ( this.poster ) {
|
|
this.$posterImage.src = this.poster;
|
|
}
|
|
}
|
|
|
|
_addIframe( autoplayRequested = false ) {
|
|
if ( this._isIframeLoaded || this.emailCapture || this.cookieConsent ) return false;
|
|
this._isIframeLoaded = true;
|
|
|
|
const iframeEl = document.createElement( 'iframe' );
|
|
|
|
iframeEl.width = 560;
|
|
iframeEl.height = 315;
|
|
|
|
iframeEl.title = this.title;
|
|
|
|
iframeEl.allow = 'accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share';
|
|
iframeEl.allowFullscreen = true;
|
|
|
|
if ( /youtube\.com|youtu\.be/.test( this.src ) ) {
|
|
iframeEl.referrerPolicy = 'strict-origin-when-cross-origin';
|
|
}
|
|
|
|
if ( autoplayRequested ) {
|
|
const url = new URL( this.src );
|
|
|
|
let searchParams = url.searchParams;
|
|
searchParams.set( 'autoplay', 1 );
|
|
|
|
url.search = searchParams.toString();
|
|
|
|
iframeEl.src = url.toString();
|
|
} else {
|
|
iframeEl.src = this.src;
|
|
}
|
|
|
|
this.$root.append( iframeEl );
|
|
|
|
this._onIframeAdded( iframeEl );
|
|
|
|
this._addClass( 'initialized' );
|
|
this._updateViewsCount();
|
|
}
|
|
|
|
_initIntersectionObserver() {
|
|
if ( this._intersectionObserver ) return false;
|
|
|
|
const options = {
|
|
root: null,
|
|
rootMargin: '0px',
|
|
threshold: 0,
|
|
};
|
|
|
|
this._intersectionObserver = new IntersectionObserver(( entries, observer ) => {
|
|
entries.forEach(entry => {
|
|
if ( entry.isIntersecting ) {
|
|
this._isInViewport = true;
|
|
this._render();
|
|
|
|
if ( this._isRendered ) observer.unobserve( this );
|
|
} else {
|
|
this._isInViewport = false;
|
|
}
|
|
});
|
|
}, options);
|
|
|
|
this._intersectionObserver.observe( this );
|
|
}
|
|
|
|
_hasClass( className ) {
|
|
return this.$root.classList.contains( className );
|
|
}
|
|
|
|
_addClass( className ) {
|
|
this.$root.classList.add( className );
|
|
}
|
|
|
|
_removeClass( className ) {
|
|
this.$root.classList.remove( className );
|
|
}
|
|
|
|
/**
|
|
* Define private async methods.
|
|
*/
|
|
|
|
async _updateViewsCount() {
|
|
if ( this.statistics && this.postType == 'aiovg_videos' ) {
|
|
let formData = new FormData();
|
|
formData.append( 'action', 'aiovg_update_views_count' );
|
|
formData.append( 'post_id', this.postId );
|
|
formData.append( 'security', this._ajaxNonce );
|
|
|
|
fetch( this._ajaxUrl, { method: 'POST', body: formData } );
|
|
}
|
|
}
|
|
|
|
async _setCookie() {
|
|
let formData = new FormData();
|
|
formData.append( 'action', 'aiovg_set_cookie' );
|
|
formData.append( 'security', this._ajaxNonce );
|
|
|
|
fetch( this._ajaxUrl, { method: 'POST', body: formData } );
|
|
}
|
|
|
|
/**
|
|
* Define public methods.
|
|
*/
|
|
|
|
_warmConnections() {
|
|
// Always overridden by the child classes
|
|
}
|
|
|
|
_onIframeAdded() {
|
|
// Always overridden by the child classes
|
|
}
|
|
|
|
/**
|
|
* Define public static methods.
|
|
*/
|
|
|
|
static isValidUrl( url ) {
|
|
if ( url == '' ) return false;
|
|
|
|
try {
|
|
new URL( url );
|
|
return true;
|
|
} catch ( error ) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static addPrefetch( kind, url ) {
|
|
const linkElem = document.createElement( 'link' );
|
|
linkElem.rel = kind;
|
|
linkElem.href = url;
|
|
linkElem.crossOrigin = 'true';
|
|
|
|
document.head.append( linkElem );
|
|
}
|
|
|
|
/**
|
|
* Define API methods.
|
|
*/
|
|
|
|
removeCookieConsent() {
|
|
if ( this._isRendered ) return false;
|
|
|
|
this._removeClass( 'cookieconsent' );
|
|
this.cookieConsent = false;
|
|
|
|
this._render();
|
|
}
|
|
|
|
removeEmailCapture() {
|
|
if ( this._isRendered ) return false;
|
|
|
|
this._removeClass( 'email-capture' );
|
|
this.emailCapture = false;
|
|
|
|
this._render();
|
|
}
|
|
|
|
play() {
|
|
// Always overridden by the child classes
|
|
}
|
|
|
|
pause() {
|
|
// Always overridden by the child classes
|
|
}
|
|
|
|
seekTo( seconds ) {
|
|
// Always overridden by the child classes
|
|
}
|
|
|
|
}
|
|
|
|
class AIOVGYouTubeElement extends AIOVGBaseElement {
|
|
|
|
constructor() {
|
|
super();
|
|
this._addClass( 'youtube' );
|
|
|
|
// Set references to the private properties used by the component
|
|
this._player = null;
|
|
}
|
|
|
|
/**
|
|
* Browser calls this method when the element is removed from the document.
|
|
* (can be called many times if an element is repeatedly added/removed)
|
|
*/
|
|
disconnectedCallback() {
|
|
if ( this._player && this._player.destroy ) {
|
|
this._player.destroy();
|
|
}
|
|
|
|
this._player = null;
|
|
|
|
if ( super.disconnectedCallback ) {
|
|
super.disconnectedCallback();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Define public methods.
|
|
*/
|
|
|
|
_warmConnections() {
|
|
if ( window.AIOVGYouTubeIsPreconnected ) return false;
|
|
|
|
AIOVGBaseElement.addPrefetch( 'preconnect', 'https://i.ytimg.com' );
|
|
AIOVGBaseElement.addPrefetch( 'preconnect', 'https://s.ytimg.com' );
|
|
AIOVGBaseElement.addPrefetch( 'preconnect', 'https://yt3.ggpht.com' );
|
|
|
|
if ( this.src.indexOf( 'www.youtube-nocookie.com' ) > -1 ) {
|
|
AIOVGBaseElement.addPrefetch( 'preconnect', 'https://www.youtube-nocookie.com' );
|
|
} else {
|
|
AIOVGBaseElement.addPrefetch( 'preconnect', 'https://www.youtube.com' );
|
|
}
|
|
|
|
AIOVGBaseElement.addPrefetch( 'preconnect', 'https://www.google.com' );
|
|
AIOVGBaseElement.addPrefetch( 'preconnect', 'https://googleads.g.doubleclick.net' );
|
|
AIOVGBaseElement.addPrefetch( 'preconnect', 'https://static.doubleclick.net' );
|
|
|
|
window.AIOVGYouTubeIsPreconnected = true;
|
|
}
|
|
|
|
_onIframeAdded( iframeEl ) {
|
|
this._loadApi().then(() => {
|
|
const player = new YT.Player( iframeEl, {
|
|
events: {
|
|
'onReady': () => {
|
|
this._player = player;
|
|
},
|
|
'onStateChange': ( event ) => {
|
|
if ( 1 == event.data ) { // Playing
|
|
// Pause other players
|
|
const videos = document.querySelectorAll( '.aiovg-player-element' );
|
|
for ( let i = 0; i < videos.length; i++ ) {
|
|
if ( videos[ i ] != this ) {
|
|
videos[ i ].pause();
|
|
}
|
|
}
|
|
|
|
window.postMessage({
|
|
message: 'aiovg-video-playing'
|
|
}, window.location.origin );
|
|
}
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Define private methods.
|
|
*/
|
|
|
|
_loadApi() {
|
|
return new Promise(( resolve ) => {
|
|
if ( typeof window.YT === 'undefined' && typeof AIOVGYouTubeElement.isApiLoaded === 'undefined' ) {
|
|
AIOVGYouTubeElement.isApiLoaded = true;
|
|
|
|
const tag = document.createElement( 'script' );
|
|
tag.src = 'https://www.youtube.com/iframe_api';
|
|
|
|
const firstScriptTag = document.getElementsByTagName( 'script' )[0];
|
|
firstScriptTag.parentNode.insertBefore( tag, firstScriptTag );
|
|
}
|
|
|
|
if ( typeof window.YT !== 'undefined' && window.YT.Player ) {
|
|
resolve();
|
|
} else {
|
|
let intervalHandler = setInterval(function() {
|
|
if ( typeof window.YT !== 'undefined' && window.YT.Player ) {
|
|
clearInterval( intervalHandler );
|
|
resolve();
|
|
}
|
|
}, 100 );
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Define API methods.
|
|
*/
|
|
|
|
play() {
|
|
if ( this._player && this._player.playVideo ) {
|
|
this._player.playVideo();
|
|
}
|
|
}
|
|
|
|
pause() {
|
|
if ( this._player && this._player.pauseVideo ) {
|
|
this._player.pauseVideo();
|
|
}
|
|
}
|
|
|
|
seekTo( seconds ) {
|
|
if ( this._player && this._player.seekTo ) {
|
|
this._player.seekTo( seconds, true );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
class AIOVGVimeoElement extends AIOVGBaseElement {
|
|
|
|
constructor() {
|
|
super();
|
|
this._addClass( 'vimeo' );
|
|
|
|
// Set references to the private properties used by the component
|
|
this._player = null;
|
|
}
|
|
|
|
/**
|
|
* Browser calls this method when the element is removed from the document.
|
|
* (can be called many times if an element is repeatedly added/removed)
|
|
*/
|
|
disconnectedCallback() {
|
|
if ( this._player && this._player.destroy ) {
|
|
this._player.destroy();
|
|
}
|
|
|
|
this._player = null;
|
|
|
|
if ( super.disconnectedCallback ) {
|
|
super.disconnectedCallback();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Define public methods.
|
|
*/
|
|
|
|
_warmConnections() {
|
|
if ( window.AIOVGVimeoIsPreconnected ) return false;
|
|
|
|
AIOVGBaseElement.addPrefetch( 'preconnect', 'https://i.vimeocdn.com' );
|
|
AIOVGBaseElement.addPrefetch( 'preconnect', 'https://player.vimeo.com' );
|
|
|
|
window.AIOVGVimeoIsPreconnected = true;
|
|
}
|
|
|
|
_onIframeAdded( iframeEl ) {
|
|
this._loadApi().then(() => {
|
|
const player = new Vimeo.Player( iframeEl );
|
|
|
|
player.ready().then(() => {
|
|
this._player = player;
|
|
});
|
|
|
|
player.on( 'play', ( data ) => {
|
|
// Pause other players
|
|
const videos = document.querySelectorAll( '.aiovg-player-element' );
|
|
for ( let i = 0; i < videos.length; i++ ) {
|
|
if ( videos[ i ] != this ) {
|
|
videos[ i ].pause();
|
|
}
|
|
}
|
|
|
|
window.postMessage({
|
|
message: 'aiovg-video-playing'
|
|
}, window.location.origin );
|
|
});
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Define private methods.
|
|
*/
|
|
|
|
_loadApi() {
|
|
return new Promise(( resolve ) => {
|
|
if ( typeof window.Vimeo === 'undefined' && typeof AIOVGVimeoElement.isApiLoaded === 'undefined' ) {
|
|
AIOVGVimeoElement.isApiLoaded = true;
|
|
|
|
const tag = document.createElement( 'script' );
|
|
tag.src = 'https://player.vimeo.com/api/player.js';
|
|
|
|
const firstScriptTag = document.getElementsByTagName( 'script' )[0];
|
|
firstScriptTag.parentNode.insertBefore( tag, firstScriptTag );
|
|
}
|
|
|
|
if ( typeof window.Vimeo !== 'undefined' && window.Vimeo.Player ) {
|
|
resolve();
|
|
} else {
|
|
let intervalHandler = setInterval(function() {
|
|
if ( typeof window.Vimeo !== 'undefined' && window.Vimeo.Player ) {
|
|
clearInterval( intervalHandler );
|
|
resolve();
|
|
}
|
|
}, 100 );
|
|
}
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Define API methods.
|
|
*/
|
|
|
|
play() {
|
|
if ( this._player && this._player.play ) {
|
|
this._player.play();
|
|
}
|
|
}
|
|
|
|
pause() {
|
|
if ( this._player && this._player.pause ) {
|
|
this._player.pause();
|
|
}
|
|
}
|
|
|
|
seekTo( seconds ) {
|
|
if ( this._player && this._player.setCurrentTime ) {
|
|
this._player.setCurrentTime( seconds );
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
class AIOVGDailymotionElement extends AIOVGBaseElement {
|
|
|
|
constructor() {
|
|
super();
|
|
this._addClass( 'dailymotion' );
|
|
}
|
|
|
|
_warmConnections() {
|
|
if ( window.AIOVGDailymotionIsPreconnected ) return false;
|
|
|
|
AIOVGBaseElement.addPrefetch( 'preconnect', 'https://s1.dmcdn.net' );
|
|
AIOVGBaseElement.addPrefetch( 'preconnect', 'https://s2.dmcdn.net' );
|
|
AIOVGBaseElement.addPrefetch( 'preconnect', 'https://www.dailymotion.com' );
|
|
|
|
window.AIOVGDailymotionIsPreconnected = true;
|
|
}
|
|
|
|
}
|
|
|
|
class AIOVGIframeElement extends AIOVGBaseElement {
|
|
|
|
constructor() {
|
|
super();
|
|
this._forceIframeElement = true;
|
|
}
|
|
|
|
}
|
|
|
|
window.AIOVGYouTubeIsPreconnected = false;
|
|
window.AIOVGVimeoIsPreconnected = false;
|
|
window.AIOVGDailymotionIsPreconnected = false;
|
|
|
|
/**
|
|
* Called when the page has loaded.
|
|
*/
|
|
document.addEventListener( 'DOMContentLoaded', function() {
|
|
// Register custom elements
|
|
if ( ! customElements.get( 'aiovg-youtube' ) ) {
|
|
customElements.define( 'aiovg-youtube', AIOVGYouTubeElement );
|
|
}
|
|
|
|
if ( ! customElements.get( 'aiovg-vimeo' ) ) {
|
|
customElements.define( 'aiovg-vimeo', AIOVGVimeoElement );
|
|
}
|
|
|
|
if ( ! customElements.get( 'aiovg-dailymotion' ) ) {
|
|
customElements.define( 'aiovg-dailymotion', AIOVGDailymotionElement );
|
|
}
|
|
|
|
if ( ! customElements.get( 'aiovg-embed' ) ) {
|
|
customElements.define( 'aiovg-embed', AIOVGIframeElement );
|
|
}
|
|
|
|
// Update views count for the non-iframe embeds
|
|
const videos = document.querySelectorAll( '.aiovg-player-raw' );
|
|
for ( let i = 0; i < videos.length; i++ ) {
|
|
const elem = videos[ i ];
|
|
const post_id = parseInt( elem.dataset.post_id );
|
|
const statistics = parseInt( elem.dataset.statistics );
|
|
|
|
if ( statistics ) {
|
|
let formData = new FormData();
|
|
formData.append( 'action', 'aiovg_update_views_count' );
|
|
formData.append( 'post_id', post_id );
|
|
formData.append( 'security', aiovg_embed.ajax_nonce );
|
|
|
|
fetch( aiovg_embed.ajax_url, { method: 'POST', body: formData } );
|
|
}
|
|
}
|
|
|
|
// Listen to the iframe player events
|
|
window.addEventListener( 'message', function( event ) {
|
|
if ( event.origin != window.location.origin ) {
|
|
return false;
|
|
}
|
|
|
|
if ( ! event.data.hasOwnProperty( 'context' ) || event.data.context != 'iframe' ) {
|
|
return false;
|
|
}
|
|
|
|
if ( ! event.data.hasOwnProperty( 'message' ) ) {
|
|
return false;
|
|
}
|
|
|
|
if ( event.data.message == 'aiovg-cookie-consent' ) {
|
|
const videos = document.querySelectorAll( '.aiovg-player-element' );
|
|
for ( let i = 0; i < videos.length; i++ ) {
|
|
videos[ i ].removeCookieConsent();
|
|
}
|
|
}
|
|
|
|
if ( event.data.message == 'aiovg-email-captured' ) {
|
|
const videos = document.querySelectorAll( '.aiovg-player-element' );
|
|
for ( let i = 0; i < videos.length; i++ ) {
|
|
videos[ i ].removeEmailCapture();
|
|
}
|
|
}
|
|
|
|
if ( event.data.message == 'aiovg-video-playing' ) {
|
|
const videos = document.querySelectorAll( '.aiovg-player-element' );
|
|
for ( let i = 0; i < videos.length; i++ ) {
|
|
videos[ i ].pause();
|
|
}
|
|
}
|
|
});
|
|
});
|
|
|
|
})();
|