PageSourceSearch

https://www.novuna.co.uk/_res/dist/scripts/_lite-you-tube-embed.min.js

js novuna.co.uk collected 2026-10-03 19:45:21 UTC 3,797 bytes, 92 lines download raw bytes

1class LiteYTEmbed extends HTMLElement {
2    constructor() {
3        super();
4        this.videoId = encodeURIComponent(this.getAttribute('videoid'));
5        this.posterUrl = `https://i.ytimg.com/vi_webp/${this.videoId}/maxresdefault.webp`;
6        this.fallbackPosterUrl = `https://i.ytimg.com/vi/${this.videoId}/hqdefault.jpg`;
7    }
8
9    async connectedCallback() {
10
11        // try and load the high resolution poster first, otherwise fall back to lower res.
12        // sometimes not all images exist
13        
14        const validPosterUrl = await this.checkImageExists(this.posterUrl)
15            .then(() => this.posterUrl)
16            .catch(() => this.fallbackPosterUrl);
17
18        this.style.backgroundImage = `url("${validPosterUrl}")`;
19
20        if (!this.querySelector(".lty-playbtn")) {
21            const playBtn = document.createElement('div');
22            playBtn.classList.add('lty-playbtn');
23            this.append(playBtn);
24
25            // On hover (or tap), warm up the TCP connections we're (likely) about to use.
26            this.addEventListener('pointerover', LiteYTEmbed.warmConnections, { once: true });
27
28            // Once the user clicks, add the real iframe and drop our play button
29            // TODO: In the future we could be like amp-youtube and silently swap in the iframe during idle time
30            //   We'd want to only do this for in-viewport or near-viewport ones: https://github.com/ampproject/amphtml/pull/5003
31            this.addEventListener('click', e => this.addIframe());
32        }
33    }
34
35    async checkImageExists(url) {
36        return fetch(url, { method: 'HEAD' })
37            .then(response => {
38                if (!response.ok) {
39                    console.log(response);
40                    throw new Error('Image not found');
41                }
42                
43                return response;
44            });
45    }
46
47    /**
48     * Add a <link rel={preload | preconnect} ...> to the head
49     */
50    static addPrefetch(kind, url, as) {
51        const linkElem = document.createElement('link');
52        linkElem.rel = kind;
53        linkElem.href = url;
54        if (as) {
55            linkElem.as = as;
56        }
57        linkElem.crossorigin = true;
58        document.head.append(linkElem);
59    }
60
61    /**
62     * Begin pre-connecting to warm up the iframe load
63     * Since the embed's network requests load within its iframe,
64     *   preload/prefetch'ing them outside the iframe will only cause double-downloads.
65     * So, the best we can do is warm up a few connections to origins that are in the critical path.
66     *
67     * Maybe `<link rel=preload as=document>` would work, but it's unsupported: http://crbug.com/593267
68     * But TBH, I don't think it'll happen soon with Site Isolation and split caches adding serious complexity.
69     */
70    static warmConnections() {
71        if (LiteYTEmbed.preconnected) return;
72
73        LiteYTEmbed.addPrefetch('preconnect', 'https://www.youtube.com');
74        LiteYTEmbed.addPrefetch('preconnect', 'https://www.google.com');
75        LiteYTEmbed.addPrefetch('preconnect', 'https://googleads.g.doubleclick.net');
76        LiteYTEmbed.addPrefetch('preconnect', 'https://static.doubleclick.net');
77
78        LiteYTEmbed.preconnected = true;
79    }
80
81    addIframe() {
82        const iframeHTML = `
83<iframe width="560" height="315" frameborder="0"
84  allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen
85  src="https://www.youtube.com/embed/${this.videoId}?autoplay=1"
86></iframe>`;
87        this.insertAdjacentHTML('beforeend', iframeHTML);
88        this.classList.add('lyt-activated');
89    }
90}
91// Register custom element
92customElements.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.