1class LiteYTEmbed extends HTMLElement{constructor(){super(),this.__iframeLoaded=!1,this.__setupDom()}static get observedAttributes(){return["videoid"]}connectedCallback(){this.addEventListener("pointerover",LiteYTEmbed.warmConnections,{once:!0}),this.addEventListener("click",(e=>this.__addIframe()))}__setupDom(){this.attachShadow({mode:"open"}).innerHTML='\n <style>\n :host {\n contain: content;\n display: block;\n position: relative;\n width: 100%;\n padding-bottom: calc(100% / (16 / 9));\n }\n\n #frame, #fallbackPlaceholder, iframe {\n position: absolute;\n width: 100%;\n height: 100%;\n }\n\n #frame {\n cursor: pointer;\n }\n\n #fallbackPlaceholder {\n object-fit: cover;\n }\n\n #frame::before {\n content: \'\';\n display: block;\n position: absolute;\n top: 0;\n background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAADGCAYAAAAT+OqFAAAAdklEQVQoz42QQQ7AIAgEF/T/D+kbq/RWAlnQyyazA4aoAB4FsBSA/bFjuF1EOL7VbrIrBuusmrt4ZZORfb6ehbWdnRHEIiITaEUKa5EJqUakRSaEYBJSCY2dEstQY7AuxahwXFrvZmWl2rh4JZ07z9dLtesfNj5q0FU3A5ObbwAAAABJRU5ErkJggg==);\n background-position: top;\n background-repeat: repeat-x;\n height: 60px;\n padding-bottom: 50px;\n width: 100%;\n transition: all 0.2s cubic-bezier(0, 0, 0.2, 1);\n z-index: 1;\n }\n /* play button */\n .lty-playbtn {\n width: 70px;\n height: 46px;\n background-color: #212121;\n z-index: 1;\n opacity: 0.8;\n border-radius: 14%; /* TODO: Consider replacing this with YT\'s actual svg. Eh. */\n transition: all 0.2s cubic-bezier(0, 0, 0.2, 1);\n border: 0;\n }\n #frame:hover .lty-playbtn {\n background-color: #f00;\n opacity: 1;\n }\n /* play button triangle */\n .lty-playbtn:before {\n content: \'\';\n border-style: solid;\n border-width: 11px 0 11px 19px;\n border-color: transparent transparent transparent #fff;\n }\n .lty-playbtn,\n .lty-playbtn:before {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate3d(-50%, -50%, 0);\n }\n\n /* Post-click styles */\n .lyt-activated {\n cursor: unset;\n }\n\n #frame.lyt-activated::before,\n .lyt-activated .lty-playbtn {\n display: none;\n }\n </style>\n <div id="frame">\n <picture>\n <source id="webpPlaceholder" type="image/webp">\n <source id="jpegPlaceholder" type="image/jpeg">\n <img id="fallbackPlaceholder" referrerpolicy="origin">\n </picture>\n <button class="lty-playbtn"></button>\n </div>\n ',this.__domRefFrame=this.shadowRoot.querySelector("#frame"),this.__domRefImg={fallback:this.shadowRoot.querySelector("#fallbackPlaceholder"),webp:this.shadowRoot.querySelector("#webpPlaceholder"),jpeg:this.shadowRoot.querySelector("#jpegPlaceholder")},this.__domRefPlayButton=this.shadowRoot.querySelector(".lty-playbtn")}__setupComponent(){this.videoId=encodeURIComponent(this.getAttribute("videoid")),this.videoTitle=this.getAttribute("videotitle")||"Video",this.videoPlay=this.getAttribute("videoplay")||"Play",this.videoStartAt=this.getAttribute("start")||0,this.autoLoad=""===this.getAttribute("autoload"),this.__initImagePlaceholder(),this.__domRefPlayButton.setAttribute("aria-label",`${this.videoPlay}: ${this.videoTitle}`),this.setAttribute("title",`${this.videoPlay}: ${this.videoTitle}`),this.autoLoad&&this.__initIntersectionObserver()}attributeChangedCallback(e,t,i){if("videoid"===e)t!==i&&(this.__setupComponent(),this.__domRefFrame.classList.contains("lyt-activated")&&(this.__domRefFrame.classList.remove("lyt-activated"),this.shadowRoot.querySelector("iframe").remove()))}__addIframe(){if(!this.__iframeLoaded){const e=`\n<iframe frameborder="0"\n allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen\n src="https://www.youtube.com/embed/${this.videoId}?autoplay=1&start=${this.videoStartAt}"\n></iframe>`;this.__domRefFrame.insertAdjacentHTML("beforeend",e),this.__domRefFrame.classList.add("lyt-activated"),this.__iframeLoaded=!0}}__initImagePlaceholder(){LiteYTEmbed.addPrefetch("preconnect","https://i.ytimg.com/");const e=`https://i.ytimg.com/vi_webp/${this.videoId}/hqdefault.webp`,t=`https://i.ytimg.com/vi/${this.videoId}/hqdefault.jpg`;this.__domRefImg.webp.srcset=e,this.__domRefImg.jpeg.srcset=t,this.__domRefImg.fallback.src=t,this.__domRefImg.fallback.setAttribute("aria-label",`${this.videoPlay}: ${this.videoTitle}`),this.__domRefImg.fallback.setAttribute("alt",`${this.videoPlay}: ${this.videoTitle}`)}__initIntersectionObserver(){if("IntersectionObserver"in window&&"IntersectionObserverEntry"in window){new IntersectionObserver(((e,t)=>{e.forEach((e=>{e.isIntersecting&&!this.__iframeLoaded&&(LiteYTEmbed.warmConnections(),this.__addIframe(),t.unobserve(this))}))}),{root:null,rootMargin:"0px",threshold:0}).observe(this)}}static addPrefetch(e,t,i){const n=document.createElement("link");n.rel=e,n.href=t,i&&(n.as=i),n.crossorigin=!0,document.head.append(n)}static warmConnections(){LiteYTEmbed.preconnected||(LiteYTEmbed.addPrefetch("preconnect","https://s.ytimg.com"),LiteYTEmbed.addPrefetch("preconnect","https://www.youtube.com"),LiteYTEmbed.addPrefetch("preconnect","https://www.google.com"),LiteYTEmbed.addPrefetch("preconnect","https://googleads.g.doubleclick.net"),LiteYTEmbed.addPrefetch("preconnect","https://static.doubleclick.net"),LiteYTEmbed.preconnected=!0)}}customElements.define("lite-youtube",LiteYTEmbed);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.