PageSourceSearch

https://www.royalaviationmuseum.com/wp-content/plugins/hideyt-prem…?ver=33a9f59ef558e82b4cdbdfb33377845b

js royalaviationmuseum.com collected 2026-09-24 09:47:36 UTC 17,626 bytes, 434 lines download raw bytes

1/* Copyright 2026 Maximillian Laumeister */
2/* https://www.hideyt.com/ */
3(function () {
4    "use strict";
5
6    let DEBUG = false;
7    window.HIDEYT_VERSION = "2.3.0";
8
9    const iframeInnerHTML = `
10        <!doctype html>
11        <meta charset="utf-8">
12        <title>HideYT Embedded Frame</title>
13        <script src="https://www.youtube.com/iframe_api"></script>
14        <style>
15
16        html, body {
17            margin: 0;
18            padding: 0;
19            width: 100vw;
20            height: 100vh;
21            font-size: 0;
22            overflow: hidden;
23        }
24
25        body, .hytWPOverlay.ended::after, .hytWPOverlay.fullHiding.paused, .hytWPOverlay.hidestart {
26            background-repeat: no-repeat;
27            background-position: center;
28            background-size: cover;
29        }
30
31        iframe {
32            position: absolute;
33            top: 0;
34            right: 0;
35            width: 100vw;
36            height: 100vh;
37        }
38
39        .hytWPOverlay {
40            position: absolute;
41            top: 0;
42            left: 0;
43            bottom: 0;
44            right: 0;
45            pointer-events: none;
46        }
47
48        .hytWPOverlay.ended::after {
49            content:"";
50            position: absolute;
51            top: 0;
52            left: 0;
53            bottom: 0;
54            right: 0;
55        }
56
57        .hytWPOverlay.paused::after, .hytWPOverlay.hidestart::after {
58            content:"";
59            pointer-events: auto;
60            position: absolute;
61            top: 70px;
62            left: 0;
63            bottom: 127px;
64            right: 0;
65            cursor: pointer;
66            background-color: #1b1b1b;
67            background-repeat: no-repeat;
68            background-position: center;
69            background-size: 70px 70px;
70            background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' version='1' width='400' height='400' viewBox='0 0 300 300'%3E%3Cg transform='translate(-.234 .173)'%3E%3Ccircle r='147.914' cy='149.827' cx='150.234' fill='%231b1b1b' fill-opacity='.818'/%3E%3Cpath d='M107.06 76.304l127.346 73.523L107.06 223.35z' fill='%23fff'/%3E%3C/g%3E%3C/svg%3E");
71        }
72
73        @media (pointer: coarse) {
74            .hytWPOverlay.paused::after, .hytWPOverlay.hidestart::after {
75                bottom: 60px;
76            }
77        }
78
79        .hytWPOverlay.paused.fullHiding::after, .hytWPOverlay.hidestart::after {
80            bottom: 0;
81            top: 0;
82            background-color: transparent;
83        }
84
85        .hytWPPlayerWrapExpired {
86            position: absolute;
87            pointer-events: auto;
88            font-size: 14px;
89            top: 0;
90            left: 0;
91            right: 0;
92            padding: 10px;
93            background: darkred;
94            color: white;
95            font-family: sans-serif;
96            line-height: 1.1;
97            z-index: 1;
98        }
99
100        .hytWPPlayerWrapExpired p {
101            margin: 5px 0;
102        }
103
104        .hytWPPlayerWrapExpired a, .hytWPPlayerWrapExpired a:visited {
105            color: #ffa5a5 !important;
106            text-decoration: underline !important;
107            font-weight: bold;
108        }
109
110        .hytWPPlayerWrapExpired a:hover {
111            color: white !important;
112        }
113
114        </style>
115        <script>
116        (function () {
117                "use strict";
118
119                let DEBUG = false;
120                if (DEBUG) console.log("inner document script parsed");
121
122                let playerData;
123
124                function init() {
125                    if (DEBUG) console.log("begin init");
126
127                    // Set background images in CSS
128                    function addCss(cssCode) {
129                        // https://stackoverflow.com/a/6211716/2234742
130                        var styleElement = document.createElement("style");
131                        styleElement.type = "text/css";
132                        if (styleElement.styleSheet) {
133                        styleElement.styleSheet.cssText = cssCode;
134                        } else {
135                        styleElement.appendChild(document.createTextNode(cssCode));
136                        }
137                        document.getElementsByTagName("head")[0].appendChild(styleElement);
138                    }
139                    const styles = \`
140                        body, .hytWPOverlay.ended::after, .hytWPOverlay.fullHiding.paused, .hytWPOverlay.hidestart {
141                            background-image: url('https://img.youtube.com/vi/\${playerData.videoId}/0.jpg');
142                        }
143                    \`;
144                    addCss(styles); // TODO: Tear this down before new player init, avoid duplicate css
145
146                    // Import options
147                    let HIDING_OPTION = playerData.options.hideyt_field_appearance || "full";
148                    let EXPIRED = playerData.options.expired ? true : false;
149                    let PAUSE_OPTION = playerData.options.hideyt_field_pausehiding || "partial";
150                    let START_HIDING = (playerData.options.hideyt_field_starthiding === "true");
151
152                    // Configure overlay
153                    let overlay = document.querySelector(".hytWPOverlay");
154                    if (PAUSE_OPTION === "full") overlay.classList.add("fullHiding");
155
156                    // Reset overlay
157                    overlay.classList.remove("ended");
158                    overlay.classList.remove("paused");
159                    if (START_HIDING) overlay.classList.add("hidestart");
160
161                    // Clean up from last instantiation
162                    const prevFrame = document.querySelector("#player");
163                    if (prevFrame) prevFrame.remove();
164
165                    let surrogate = document.createElement("div");
166                    surrogate.id = "player";
167                    document.body.insertBefore(surrogate, overlay);
168
169                    const ytplayer = new YT.Player('player', {
170                        height: '390',
171                        width: '640',
172                        videoId: playerData.videoId,
173                        playerVars: playerData.urlParameters,
174                        events: {
175                            'onReady': onPlayerReady
176                        }
177                    });
178                    const ytiframe = ytplayer.getIframe();
179
180                    if (DEBUG) console.log(ytiframe);
181
182                    // Add enablejsapi on YouTube Embed
183                    /*let url = new URL(ytiframe.src);
184                    if (url.searchParams.get('enablejsapi') !== "1") {
185                        url.searchParams.set('enablejsapi', "1");
186                        url.searchParams.set('rel', "0"); // Since the iframe needs to reload anyway...
187                        ytiframe.src = url;
188                    }*/
189
190                    // Init player
191
192                    function resetClasses() {
193                        overlay.classList.remove("ended");
194                        overlay.classList.remove("paused");
195                    }
196
197                    let pauseTimeout;
198                    function onPlayerStateChange(event) {
199                        if (DEBUG) console.log("player state change: ", ytplayer);
200                        if (EXPIRED) return;
201                        if (event.data == YT.PlayerState.ENDED) {
202                            if (DEBUG) console.log("player state ended: ", ytplayer);
203                            if (HIDING_OPTION !== "none") {
204                                window.clearTimeout(pauseTimeout);
205                                resetClasses();
206                                if (START_HIDING) overlay.classList.add("hidestart");
207                                ytplayer.stopVideo();
208                            }
209                        } else if (event.data == YT.PlayerState.PAUSED) {
210                            if (DEBUG) console.log("player state paused: ", ytplayer);
211                            if (HIDING_OPTION === "full") {
212                                if (PAUSE_OPTION === "partial") {
213                                    resetClasses();
214                                    overlay.classList.add("paused");
215                                } else {
216                                    // PAUSE_OPTION === "full"
217                                    pauseTimeout = window.setTimeout(function() {
218                                        // We need this timeout, otherwise the click event will get stuck in the overlay and not make it to the YouTube player.
219                                        resetClasses();
220                                        overlay.classList.add("paused");
221                                    }, 0);
222                                }
223                            }
224                        } else if (event.data == YT.PlayerState.PLAYING || event.data == YT.PlayerState.BUFFERING) {
225                            if (START_HIDING) overlay.classList.remove("hidestart");
226                            window.clearTimeout(pauseTimeout);
227                            // We need this timeout so that the related videos don't flicker
228                            pauseTimeout = window.setTimeout(function() {
229                                resetClasses();
230                            }, 100);
231                        }
232                    };
233
234                    function onPlayerApiChange(ch) {
235                        console.log("playerapichange:", ch);
236                    }
237                    function onPlayerError(error) {
238                        console.log("playererror:", error);
239                    }
240                    function onPlayerReady(event) {
241                        if (DEBUG) console.log("player ready: ", ytplayer);
242                        // Register YouTube Player change
243                        ytplayer.addEventListener('onStateChange', onPlayerStateChange);
244                        if (DEBUG) ytplayer.addEventListener('onError', onPlayerError);
245                        if (DEBUG) ytplayer.addEventListener('onApiChange', onPlayerApiChange);
246                        // Register overlay click
247                        overlay.addEventListener("click", function() {
248                            ytplayer.playVideo();
249                        });
250                    };
251
252                    if (DEBUG) console.log("player created: ", ytplayer);
253
254                    if (EXPIRED && playerData.options.has_plugin_privileges) {
255                        let message = document.createElement("div");
256                        message.classList.add("hytWPPlayerWrapExpired");
257                        message.innerHTML = "<p><b>HideYT Plugin License Expired</b></p><p>To continue hiding YouTube related videos, please <a href='/wp-admin/options-general.php?page=hideyt'>renew your license</a>! (This message is shown only to WordPress admins, not users).";
258                        overlay.appendChild(message);
259                    }
260
261                    window.theplayer = ytplayer;
262                }
263
264                window.addEventListener("message", function(msg) {
265                    if (msg.data.type === "hytInit") {
266                        const msgdata = msg.data.data;
267                        msgdata.urlParameters.rel = "0"; // Force rel=0
268
269                        // Fullscreen
270                        if (msgdata.options.hideyt_field_forcefullscreen === "forceon") {
271                            msgdata.urlParameters.fs = "1";
272                        } else if (msgdata.options.hideyt_field_forcefullscreen === "forceoff") {
273                            msgdata.urlParameters.fs = "0";
274                        }
275
276                        playerData = msgdata;
277                        // Init HideYT
278                        init();
279                    }
280                }, false);
281            })();
282
283        </script>
284        <div class="hytWPOverlay"></div>
285    `;
286
287    // Disable HideYT if Thrive Architect editor is open
288    if (new URL(window.location.href).searchParams.get("tve") === "true") return;
289
290    // Returns an array all elements from array "a" that are also in array "b"
291    function arrayDiff(a, b) {
292        return a.filter(function(i) {return b.indexOf(i) < 0;});
293    };
294
295    // Deduplicate an array
296    function arrayUnique(array) {
297        var a = array.concat();
298        for(var i=0; i<a.length; ++i) {
299            for(var j=i+1; j<a.length; ++j) {
300                if(a[i] === a[j])
301                    a.splice(j--, 1);
302            }
303        }
304        return a;
305    }
306
307    let iframeList = [];
308
309    function initPlayer(playerFrame) {
310        // Replace the youtube iframe with the custom hideyt iframe
311        let src;
312        if (!playerFrame.src.includes(".com/embed/") && playerFrame.dataset.src.includes(".com/embed/")) {
313            src = new URL(playerFrame.dataset.src, new URL(window.location.href));
314        } else {
315            src = new URL(playerFrame.src, new URL(window.location.href));
316        }
317        const hideYTFrame = playerFrame.cloneNode(false);
318        delete hideYTFrame.dataset.src;
319        hideYTFrame.style.visibility = "visible";
320        hideYTFrame.style.opacity = "1";
321        hideYTFrame.removeAttribute("src");
322        const supportsSrcdoc = !!("srcdoc" in document.createElement("iframe"));
323        if (supportsSrcdoc) {
324            hideYTFrame.setAttribute("srcdoc", iframeInnerHTML);
325        } else {
326            const blob = new Blob([iframeInnerHTML], 'text/html');
327            const blobURL = URL.createObjectURL(blob);
328            hideYTFrame.setAttribute("src", blobURL);
329        }
330        // TODO: Force frameborder, allow, allowfullscreen
331
332        playerFrame.parentNode.insertBefore(hideYTFrame, playerFrame);
333
334        playerFrame.parentNode.removeChild(playerFrame);
335
336        const playerFrameHTML = playerFrame.outerHTML;
337
338        if (DEBUG) console.log("player replaced");
339
340        hideYTFrame.addEventListener("load", function() {
341            if (DEBUG) console.log("iframe load");
342
343            const videoId = src.pathname.split("/").slice(-1)[0];
344
345            // Copy url parameters to js object
346            const urlParameters = {};
347            src.searchParams.forEach((value, key) => {
348                urlParameters[key] = value;
349            });
350
351            // Fix elementor autoplay
352            try {
353                const elementorWidget = hideYTFrame.closest(".elementor-widget-video");
354                if (elementorWidget) {
355                    const elementorSettings = JSON.parse(elementorWidget.dataset.settings);
356                    if (elementorSettings.show_image_overlay === "yes") {
357                        urlParameters.autoplay = 1;
358                    }
359                }
360            } catch (error) {
361                // Bail on elementor fix
362            }
363
364            hideYTFrame.contentWindow.postMessage({
365                type: "hytInit",
366                data: {
367                    options: hideyt_options,
368                    videoId: videoId,
369                    urlParameters: urlParameters
370                }
371            }, "*");
372        });
373    }
374
375    function updatePlayers() {
376        let ytiframes = Array.from(document.querySelectorAll(`
377
378            iframe[src^="https://www.youtube.com/embed/"],
379            iframe[src^="http://www.youtube.com/embed/"],
380            iframe[src^="//www.youtube.com/embed/"],
381
382            iframe[src^="https://youtube.com/embed/"],
383            iframe[src^="http://youtube.com/embed/"],
384            iframe[src^="//youtube.com/embed/"],
385
386            iframe[src^="https://www.youtube-nocookie.com/embed/"],
387            iframe[src^="http://www.youtube-nocookie.com/embed/"],
388            iframe[src^="//www.youtube-nocookie.com/embed/"],
389
390            iframe[src^="https://youtube-nocookie.com/embed/"],
391            iframe[src^="http://youtube-nocookie.com/embed/"],
392            iframe[src^="//youtube-nocookie.com/embed/"],
393
394            iframe[data-src^="https://www.youtube.com/embed/"],
395            iframe[data-src^="http://www.youtube.com/embed/"],
396            iframe[data-src^="//www.youtube.com/embed/"],
397
398            iframe[data-src^="https://youtube.com/embed/"],
399            iframe[data-src^="http://youtube.com/embed/"],
400            iframe[data-src^="//youtube.com/embed/"],
401
402            iframe[data-src^="https://www.youtube-nocookie.com/embed/"],
403            iframe[data-src^="http://www.youtube-nocookie.com/embed/"],
404            iframe[data-src^="//www.youtube-nocookie.com/embed/"],
405
406            iframe[data-src^="https://youtube-nocookie.com/embed/"],
407            iframe[data-src^="http://youtube-nocookie.com/embed/"],
408            iframe[data-src^="//youtube-nocookie.com/embed/"]
409
410        `));
411        ytiframes = ytiframes.filter(elem => {
412            // ThemePunch / Slider Revolution background video container.
413            if (elem.closest(".rs-background-video-layer") !== null) return false;
414
415            // Slider Revolution sometimes uses IDs like sr...video; skip those embeds.
416            let id = (elem.id || "").toLowerCase();
417            let isSliderRevolutionVideo = id.startsWith("sr") && id.endsWith("video");
418            return !isSliderRevolutionVideo;
419        });
420        let newFrames = arrayDiff(ytiframes, iframeList); // Now ytiframes has only the NEW iframes.
421        iframeList = arrayUnique(iframeList.concat(newFrames));
422
423        // Init all new YouTube players
424        for (let ytiframe of newFrames) {
425            initPlayer(ytiframe)
426        }
427    }
428
429    // The updatePlayers function benchmarks at 30 microseconds for a dry poll,
430    // so there will be no jank even at a high polling rate.
431    updatePlayers();
432    setInterval(updatePlayers, 100);
433
434})();

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.