'use strict'; const AIOVGTemplate = document.createElement( 'template' ); AIOVGTemplate.innerHTML = `
`; 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' ); // Set references to the private properties used by the component this._isRendered = false; this._isCookieConsentLoaded = 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() { this.removeEventListener( 'pointerover', () => this._warmConnections(), { once: true, } ); this.removeEventListener( 'click', () => this._addIframe( true ) ); } /** * Array of attribute names to monitor for changes. */ static get observedAttributes() { return [ 'title', 'ratio', 'cookieconsent' ]; } /** * 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; case 'cookieconsent': if ( ! this._isRendered ) { this._removeClass( 'cookieconsent' ); this._render(); } 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 ajaxUrl() { const value = this.getAttribute( 'ajax_url' ) || ''; return AIOVGBaseElement.isValidUrl( value ) ? value : ''; } get ajaxNonce() { return this.getAttribute( 'ajax_nonce' ) || ''; } get lazyLoading() { return this.hasAttribute( 'lazyloading' ); } get cookieConsent() { return this.hasAttribute( 'cookieconsent' ); } set cookieConsent( value ) { const isEnabled = Boolean( value ); if ( isEnabled ) { this.setAttribute( 'cookieconsent', '' ); } else { this.removeAttribute( 'cookieconsent' ); } } /** * Define private methods. */ _render() { if ( this._isRendered ) true; if ( this.lazyLoading && ! this._isInViewport ) { this._initIntersectionObserver(); 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(); } _addPosterImage() { if ( this._isPosterImageLoaded ) return false; this._isPosterImageLoaded = true; if ( this.poster ) { this.$posterImage.src = this.poster; } } _addIframe( autoplayRequested = false ) { if ( this._isIframeLoaded ) 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 ( 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._addClass( 'initialized' ); this._updateViewsCount(); this.dispatchEvent(new CustomEvent('AIOVGIframeLoaded', { detail: 'iframe.loaded', bubbles: true, cancelable: true, })); } _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.postType == 'aiovg_videos' && this.ajaxUrl ) { 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() { try { if ( this.ajaxUrl ) { let formData = new FormData(); formData.append( 'action', 'aiovg_set_cookie' ); formData.append( 'security', this.ajaxNonce ); fetch( this.ajaxUrl, { method: 'POST', body: formData } ); } // Announce to our friends const vidstack = document.querySelectorAll( '.aiovg-player-element[cookieconsent]' ); for ( let i = 0; i < vidstack.length; i++ ) { vidstack[ i ].removeAttribute( 'cookieconsent' ); } const videojs = document.querySelectorAll( '.aiovg-player-standard' ); const event = new CustomEvent( 'cookieConsent' ); for ( let i = 0; i < videojs.length; i++ ) { videojs[ i ].dispatchEvent( event ); } } catch ( error ) { /** console.log( error ); */ } } /** * Define public methods. */ _warmConnections() { // 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 ); } } class AIOVGYouTubeElement extends AIOVGBaseElement { constructor() { super(); this._addClass( 'youtube' ); } _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; } } class AIOVGVimeoElement extends AIOVGBaseElement { constructor() { super(); this._addClass( 'vimeo' ); } _warmConnections() { if ( window.AIOVGVimeoIsPreconnected ) return false; AIOVGBaseElement.addPrefetch( 'preconnect', 'https://i.vimeocdn.com' ); AIOVGBaseElement.addPrefetch( 'preconnect', 'https://player.vimeo.com' ); window.AIOVGVimeoIsPreconnected = true; } } 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; // Register custom element document.addEventListener( 'DOMContentLoaded', function() { customElements.define( 'aiovg-youtube', AIOVGYouTubeElement ); customElements.define( 'aiovg-vimeo', AIOVGVimeoElement ); customElements.define( 'aiovg-dailymotion', AIOVGDailymotionElement ); customElements.define( 'aiovg-embed', AIOVGIframeElement ); });