- // ==UserScript==
- // @name YouTube: Floating Chat Window on Fullscreen
- // @namespace UserScript
- // @match https://www.youtube.com/*
- // @exclude /^https?://\S+\.(txt|png|jpg|jpeg|gif|xml|svg|manifest|log|ini)[^\/]*$/
- // @version 0.2.7
- // @license MIT License
- // @author CY Fung
- // @description To make floating chat window on fullscreen
- // @require https://greasyfork.org/scripts/465819-api-for-customelements-in-youtube/code/API%20for%20CustomElements%20in%20YouTube.js?version=1215161
- // @run-at document-start
- // @grant none
- // @unwrap
- // @allFrames true
- // @inject-into page
- // ==/UserScript==
-
-
- ((__CONTEXT__) => {
-
-
- const win = typeof unsafeWindow !== 'undefined' ? unsafeWindow : (this instanceof Window ? this : window);
-
- const hkey_script = 'vdnvorrwsksy';
- if (win[hkey_script]) throw new Error('Duplicated Userscript Calling'); // avoid duplicated scripting
- win[hkey_script] = true;
-
- /** @type {globalThis.PromiseConstructor} */
- const Promise = (async () => { })().constructor; // YouTube hacks Promise in WaterFox Classic and "Promise.resolve(0)" nevers resolve.
-
-
- const createStyleTextForTopWin = () => `
-
-
- [floating-chat-window]:fullscreen ytd-live-chat-frame#chat:not([collapsed]) {
- position:fixed !important;
- top: var(--f3-top, 5px) !important;
- left: var(--f3-left, calc(60vw + 100px)) !important;
- height: var(--f3-h, 60vh) !important;
- width: var(--f3-w, 320px) !important;
- display:flex !important;
- flex-direction: column !important;
- padding: 4px;
- cursor: all-scroll;
- z-index:9999;
- box-sizing: border-box !important;
- margin:0 !important;
- opacity: var(--floating-window-opacity, 1.0) !important;
- background: transparent;
- background-color: rgba(0, 0, 0, 0.5);
- transition: background-color 300ms;
- }
-
- [floating-chat-window]:fullscreen ytd-live-chat-frame#chat:not([collapsed]):hover {
- background-color: rgba(0, 0, 0, 0.85);
-
- }
-
- .no-floating[floating-chat-window]:fullscreen ytd-live-chat-frame#chat:not([collapsed]) {
-
- top: -300vh !important;
- left: -300vh !important;
- }
-
-
- [floating-chat-window]:fullscreen ytd-live-chat-frame#chat:not([collapsed]) #show-hide-button[class]{
- flex-grow: 0;
- flex-shrink:0;
- position:static;
- cursor: all-scroll;
- }
- [floating-chat-window]:fullscreen ytd-live-chat-frame#chat:not([collapsed]) #show-hide-button[class] *[class]{
- cursor: inherit;
- }
- [floating-chat-window]:fullscreen ytd-live-chat-frame#chat:not([collapsed]) iframe[class]{
- flex-grow: 100;
- flex-shrink:0;
- height: 0;
- position:static;
- }
-
-
- html{
- --fc7-handle-color: #0cb8da;
- }
- html[dark]{
- --fc7-handle-color: #0c74e4;
- }
-
- :fullscreen .resize-handle {
-
- position: absolute !important;
- top: 0;
- left: 0;
- bottom: 0;
- background: transparent;
- right: 0;
- z-index: 999 !important;
- border-radius: inherit !important;
- box-sizing: border-box !important;
- pointer-events:none !important;
- visibility: collapse;
- border: 4px solid transparent;
- border-color: transparent;
- transition: border-color 300ms;
- }
-
- [floating-chat-window]:fullscreen ytd-live-chat-frame#chat:not([collapsed]):hover .resize-handle {
-
- visibility: visible;
-
- border-color: var(--fc7-handle-color);
- }
-
- [moving] {
- cursor: all-scroll;
- --pointer-events:initial;
- }
-
- [moving] body {
- --pointer-events:none;
- }
-
- [moving] ytd-live-chat-frame#chat{
-
- --pointer-events:initial;
- }
-
-
- [moving] ytd-live-chat-frame#chat iframe {
-
- --pointer-events:none;
- }
-
-
- [moving="move"] ytd-live-chat-frame#chat {
- background-color: var(--yt-spec-general-background-a);
-
- }
-
-
- [moving="move"] ytd-live-chat-frame#chat iframe {
-
- visibility: collapse;
- }
-
- [moving] * {
- pointer-events:var(--pointer-events) !important;
-
- }
- [moving] *, [moving] [class] {
- user-select: none !important;
- }
-
- :fullscreen tyt-iframe-popup-btn{
- display: none !important;
- }
-
- [moving] tyt-iframe-popup-btn{
- display: none !important;
- }
-
- [floating-chat-window]:fullscreen ytd-live-chat-frame#chat:not([collapsed]) #show-hide-button.ytd-live-chat-frame>ytd-toggle-button-renderer.ytd-live-chat-frame {
-
- background: transparent;
-
- }
-
-
-
- `;
-
- const createStyleTextForIframe = () => `
-
- .youtube-floating-chat-iframe #right-arrow-container.yt-live-chat-ticker-renderer,
- .youtube-floating-chat-iframe #left-arrow-container.yt-live-chat-ticker-renderer
-
- {
- background: transparent;
- }
-
- .youtube-floating-chat-iframe yt-live-chat-renderer.yt-live-chat-app {
-
- --yt-live-chat-background-color: transparent;
- --yt-live-chat-action-panel-background-color: rgba(0, 0, 0, 0.08);
- --yt-live-chat-header-background-color: rgba(0, 0, 0, 0.18);
- --yt-spec-static-overlay-background-medium: rgba(0, 0, 0, 0.08);
- --yt-live-chat-banner-gradient-scrim: transparent;
-
- }
-
-
-
-
- .youtube-floating-chat-iframe yt-live-chat-renderer.yt-live-chat-app #visible-banners > yt-live-chat-banner-renderer {
- --fc7-banner-opacity: 0.86;
- }
-
- .youtube-floating-chat-iframe yt-live-chat-renderer.yt-live-chat-app #visible-banners > yt-live-chat-banner-renderer[collapsed] {
- --fc7-banner-opacity: 0.66;
- }
-
-
- .youtube-floating-chat-iframe yt-live-chat-app:hover yt-live-chat-renderer.yt-live-chat-app #visible-banners > yt-live-chat-banner-renderer[class] {
- --fc7-banner-opacity: 1;
- }
-
-
- .youtube-floating-chat-iframe yt-live-chat-renderer.yt-live-chat-app {
- --fc7-system-message-opacity: 0.66;
-
- }
-
- .youtube-floating-chat-iframe yt-live-chat-app:hover yt-live-chat-renderer.yt-live-chat-app {
- --fc7-system-message-opacity: 1.0;
-
- }
-
-
- .youtube-floating-chat-iframe yt-live-chat-renderer.yt-live-chat-app #visible-banners > yt-live-chat-banner-renderer {
- opacity: var(--fc7-banner-opacity) !important;
- }
-
-
- .youtube-floating-chat-iframe yt-live-chat-renderer.yt-live-chat-app yt-live-chat-viewer-engagement-message-renderer {
- opacity: var(--fc7-system-message-opacity) !important;
- }
-
-
- .youtube-floating-chat-iframe yt-live-chat-app:not(:hover) yt-live-chat-renderer.yt-live-chat-app yt-live-chat-message-input-renderer {
- display: none;
- }
-
- .youtube-floating-chat-iframe yt-live-chat-app:hover yt-live-chat-renderer.yt-live-chat-app yt-live-chat-message-input-renderer {
-
- position: absolute;
- transform: translateY(-100%);
- left: 0;
- right: 0;
- opacity: 1;
- background: rgba(0,0,0,0.86);
- }
-
-
- /* hide message with input panel hidden */
- .youtube-floating-chat-iframe yt-live-chat-app:not(:hover) > tp-yt-iron-dropdown.yt-live-chat-app yt-tooltip-renderer[slot="dropdown-content"][position-type="OPEN_POPUP_POSITION_TOP"].yt-live-chat-app {
- visibility: collapse;
- display: none;
- }
-
-
-
-
-
-
-
-
-
-
- [dark].youtube-floating-chat-iframe yt-live-chat-app ::-webkit-scrollbar-track,
- [dark].youtube-floating-chat-iframe yt-live-chat-kevlar-container ::-webkit-scrollbar-track {
- background-color: var(--ytd-searchbox-legacy-button-color);
- }
-
- .youtube-floating-chat-iframe yt-live-chat-app ::-webkit-scrollbar-track,
- .youtube-floating-chat-iframe yt-live-chat-kevlar-container ::-webkit-scrollbar-track {
- background-color: #fcfcfc;
- }
-
-
- [dark].youtube-floating-chat-iframe yt-live-chat-app ::-webkit-scrollbar-thumb,
- [dark].youtube-floating-chat-iframe yt-live-chat-kevlar-container ::-webkit-scrollbar-thumb{
-
- background-color: var(--ytd-searchbox-legacy-button-color);
- border: 2px solid var(--ytd-searchbox-legacy-button-color);
-
- }
-
-
-
- .youtube-floating-chat-iframe yt-live-chat-renderer[has-action-panel-renderer] #action-panel.yt-live-chat-renderer {
- --yt-live-chat-action-panel-gradient-scrim: transparent;
- }
-
-
- .youtube-floating-chat-iframe yt-live-chat-renderer[has-action-panel-renderer] #action-panel.yt-live-chat-renderer yt-live-chat-action-panel-renderer {
- --fc7-system-message-opacity2: 0.66;
- }
-
- .youtube-floating-chat-iframe yt-live-chat-app:hover yt-live-chat-renderer[has-action-panel-renderer] #action-panel.yt-live-chat-renderer yt-live-chat-action-panel-renderer {
- --fc7-system-message-opacity2: 1.00;
- }
-
-
- .youtube-floating-chat-iframe yt-live-chat-renderer[has-action-panel-renderer] #action-panel.yt-live-chat-renderer yt-live-chat-action-panel-renderer {
- opacity: var(--fc7-system-message-opacity2) !important;
- }
-
- `;
-
- const { isIframe, isTopFrame } = (() => {
-
- let isIframe = false, isTopFrame = false;
- try {
- isIframe = window.document !== top.document
- } catch (e) { }
-
- try {
- isTopFrame = window.document === top.document
- } catch (e) { }
-
- return { isIframe, isTopFrame };
-
- })();
-
- if (isIframe ^ isTopFrame) { } else return;
-
- if (isTopFrame) {
-
-
-
-
- const addCSS = (createStyleText) => {
- let text = createStyleText();
- let style = document.createElement('style');
- style.id = 'rvZ0t';
- style.textContent = text;
- document.head.appendChild(style);
- }
-
-
-
- const cleanContext = async (win) => {
- const waitFn = requestAnimationFrame; // shall have been binded to window
- try {
- let mx = 16; // MAX TRIAL
- const frameId = 'vanillajs-iframe-v1'
- let frame = document.getElementById(frameId);
- let removeIframeFn = null;
- if (!frame) {
- frame = document.createElement('iframe');
- frame.id = 'vanillajs-iframe-v1';
- frame.sandbox = 'allow-same-origin'; // script cannot be run inside iframe but API can be obtained from iframe
- let n = document.createElement('noscript'); // wrap into NOSCRPIT to avoid reflow (layouting)
- n.appendChild(frame);
- while (!document.documentElement && mx-- > 0) await new Promise(waitFn); // requestAnimationFrame here could get modified by YouTube engine
- const root = document.documentElement;
- root.appendChild(n); // throw error if root is null due to exceeding MAX TRIAL
- removeIframeFn = (setTimeout) => {
- const removeIframeOnDocumentReady = (e) => {
- e && win.removeEventListener("DOMContentLoaded", removeIframeOnDocumentReady, false);
- win = null;
- setTimeout(() => {
- n.remove();
- n = null;
- }, 200);
- }
- if (document.readyState !== 'loading') {
- removeIframeOnDocumentReady();
- } else {
- win.addEventListener("DOMContentLoaded", removeIframeOnDocumentReady, false);
- }
- }
- }
- while (!frame.contentWindow && mx-- > 0) await new Promise(waitFn);
- const fc = frame.contentWindow;
- if (!fc) throw "window is not found."; // throw error if root is null due to exceeding MAX TRIAL
- const { requestAnimationFrame, setTimeout } = fc;
- const res = { requestAnimationFrame, setTimeout };
- for (let k in res) res[k] = res[k].bind(win); // necessary
- if (removeIframeFn) Promise.resolve(res.setTimeout).then(removeIframeFn);
- return res;
- } catch (e) {
- console.warn(e);
- return null;
- }
- };
-
- cleanContext(win).then(__CONTEXT__ => {
- if (!__CONTEXT__) return null;
-
- const { requestAnimationFrame } = __CONTEXT__;
-
- let chatWindowWR = null;
- let showHideButtonWR = null;
-
- /* globals WeakRef:false */
-
- /** @type {(o: Object | null) => WeakRef | null} */
- const mWeakRef = typeof WeakRef === 'function' ? (o => o ? new WeakRef(o) : null) : (o => o || null); // typeof InvalidVar == 'undefined'
-
- /** @type {(wr: Object | null) => Object | null} */
- const kRef = (wr => (wr && wr.deref) ? wr.deref() : wr);
-
- let startX;
- let startY;
- let startWidth;
- let startHeight;
-
-
- let edge = 0;
-
-
- let initialLeft;
- let initialTop;
-
- let stopResize;
- let stopMove;
-
-
- const getXY = (e) => {
- let rect = e.target.getBoundingClientRect();
- let x = e.clientX - rect.left; //x position within the element.
- let y = e.clientY - rect.top; //y position within the element.
- return { x, y }
- }
-
- let beforeEvent = null;
-
- function resizeWindow(e) {
-
-
- const chatWindow = kRef(chatWindowWR);
- if (chatWindow) {
-
- const mEdge = edge;
-
- if (mEdge == 4 || mEdge == 1) {
-
- } else if (mEdge == 8 || mEdge == 16) {
- } else {
- return;
- }
-
-
- Promise.resolve(chatWindow).then(chatWindow => {
- let rect;
-
- if (mEdge == 4 || mEdge == 1 || mEdge == 16) {
-
- let newWidth = startWidth + (startX - e.pageX);
-
- let newLeft = initialLeft + startWidth - newWidth;
- chatWindow.style.setProperty('--f3-w', newWidth + "px");
- chatWindow.style.setProperty('--f3-left', newLeft + "px");
-
-
-
- let newHeight = startHeight + (startY - e.pageY);
-
- let newTop = initialTop + startHeight - newHeight;
- chatWindow.style.setProperty('--f3-h', newHeight + "px");
- chatWindow.style.setProperty('--f3-top', newTop + "px");
-
- rect = {
- x: newLeft,
- y: newTop,
- w: newWidth,
-
- h: newHeight,
-
-
- };
-
-
-
- } else if (mEdge == 8) {
-
- let newWidth = startWidth + e.pageX - startX;
- let newHeight = startHeight + e.pageY - startY;
-
- chatWindow.style.setProperty('--f3-w', newWidth + "px");
- chatWindow.style.setProperty('--f3-h', newHeight + "px");
-
-
- rect = {
- x: initialLeft,
- y: initialTop,
- w: newWidth,
-
- h: newHeight,
-
-
- };
-
- }
-
-
-
- updateOpacity(chatWindow, rect, screen);
-
- })
-
-
- e.stopImmediatePropagation();
- e.stopPropagation();
- e.preventDefault();
-
-
- }
-
- }
-
- let isMoved = false;
-
- function moveWindow(e) {
-
-
-
- const chatWindow = kRef(chatWindowWR);
- if (chatWindow) {
-
- Promise.resolve(chatWindow).then(chatWindow => {
-
-
- let newX = initialLeft + e.pageX - startX;
- let newY = initialTop + e.pageY - startY;
-
- if (Math.abs(e.pageX - startX) > 10 || Math.abs(e.pageY - startY) > 10) isMoved = true;
-
- chatWindow.style.setProperty('--f3-left', newX + "px");
- chatWindow.style.setProperty('--f3-top', newY + "px");
-
-
-
- updateOpacity(chatWindow, {
- x: newX,
- y: newY,
- w: startWidth,
-
- h: startHeight,
-
-
- }, screen);
-
- });
-
- console.log(1002)
-
-
- e.stopImmediatePropagation();
- e.stopPropagation();
- e.preventDefault();
-
- }
- }
-
-
-
-
- function initializeResize(e) {
-
- if (!document.fullscreenElement) return;
-
- if (!document.querySelector('[floating-chat-window]:fullscreen ytd-live-chat-frame#chat:not([collapsed])')) return;
-
- if (e.target.id !== 'chat') return;
-
-
-
- const { x, y } = getXY(e);
- edge = 0;
- if (x < 16 && y < 16) { edge = 16; }
- else if (x < 16) edge = 4;
- else if (y < 16) edge = 1;
- else edge = 8;
-
- if (edge <= 0) return;
-
- startX = e.pageX;
- startY = e.pageY;
-
- const chatWindow = kRef(chatWindowWR);
- if (chatWindow) {
-
- Promise.resolve(chatWindow).then(chatWindow => {
-
- let rect = chatWindow.getBoundingClientRect();
- initialLeft = rect.x;
- initialTop = rect.y;
-
-
-
- startWidth = rect.width;
- startHeight = rect.height;
-
-
- chatWindow.style.setProperty('--f3-left', initialLeft + "px");
- chatWindow.style.setProperty('--f3-top', initialTop + "px");
- chatWindow.style.setProperty('--f3-w', startWidth + "px");
- chatWindow.style.setProperty('--f3-h', startHeight + "px");
-
- });
-
- }
-
-
-
-
- document.documentElement.setAttribute('moving', 'resize');
-
- document.documentElement.removeEventListener("mousemove", resizeWindow, false);
- document.documentElement.removeEventListener("mousemove", moveWindow, false);
- document.documentElement.removeEventListener("mouseup", stopResize, false);
- document.documentElement.removeEventListener("mouseup", stopMove, false);
-
- isMoved = false;
- document.documentElement.addEventListener("mousemove", resizeWindow);
- document.documentElement.addEventListener("mouseup", stopResize);
-
- }
-
-
- let updateOpacityRid = 0;
-
- function updateOpacity(chatWindow, rect, screen) {
-
- let tid = ++updateOpacityRid;
-
- requestAnimationFrame(() => {
-
-
- if (tid !== updateOpacityRid) return;
-
- let { x, y, w, h } = rect;
- let [left, top, right, bottom] = [x, y, x + w, y + h];
-
-
- let opacityW = (Math.min(right, screen.width) - Math.max(0, left)) / w;
- let opacityH = (Math.min(bottom, screen.height) - Math.max(0, top)) / h;
-
- let opacity = Math.min(opacityW, opacityH);
-
- chatWindow.style.setProperty('--floating-window-opacity', Math.round(opacity * 100 * 5, 0) / 5 / 100);
-
-
- })
-
-
-
-
-
- }
-
- function initializeMove(e) {
-
- if (!document.fullscreenElement) return;
- if (!document.querySelector('[floating-chat-window]:fullscreen ytd-live-chat-frame#chat:not([collapsed])')) return;
-
-
-
- const chatWindow = kRef(chatWindowWR);
-
-
-
- startX = e.pageX;
- startY = e.pageY;
-
-
- if (chatWindow) {
-
- Promise.resolve(chatWindow).then(chatWindow => {
-
-
- let rect = chatWindow.getBoundingClientRect();
- initialLeft = rect.x;
- initialTop = rect.y;
-
-
-
- startWidth = rect.width;
- startHeight = rect.height;
-
-
- chatWindow.style.setProperty('--f3-left', initialLeft + "px");
- chatWindow.style.setProperty('--f3-top', initialTop + "px");
- chatWindow.style.setProperty('--f3-w', startWidth + "px");
- chatWindow.style.setProperty('--f3-h', startHeight + "px");
-
- })
-
-
- }
-
-
-
- document.documentElement.setAttribute('moving', 'move');
-
- document.documentElement.removeEventListener("mousemove", resizeWindow, false);
- document.documentElement.removeEventListener("mousemove", moveWindow, false);
- document.documentElement.removeEventListener("mouseup", stopResize, false);
- document.documentElement.removeEventListener("mouseup", stopMove, false);
- isMoved = false;
-
- document.documentElement.addEventListener("mousemove", moveWindow, false);
- document.documentElement.addEventListener("mouseup", stopMove, false);
-
- e.stopImmediatePropagation();
- e.stopPropagation();
- e.preventDefault();
-
- beforeEvent = e;
- console.log(1001)
-
- }
-
-
- function checkClick(beforeEvent, currentEvent) {
-
- const d = currentEvent.timeStamp - beforeEvent.timeStamp;
- if (d < 300 && d > 30 && !isMoved) {
-
- document.documentElement.classList.add('no-floating');
-
- }
-
- }
-
-
- stopResize = (e) => {
-
- document.documentElement.removeEventListener("mousemove", resizeWindow, false);
- document.documentElement.removeEventListener("mousemove", moveWindow, false);
- document.documentElement.removeEventListener("mouseup", stopResize, false);
- document.documentElement.removeEventListener("mouseup", stopMove, false);
-
- document.documentElement.removeAttribute('moving');
-
- e.stopImmediatePropagation();
- e.stopPropagation();
-
- }
-
- stopMove = (e) => {
-
- document.documentElement.removeEventListener("mousemove", resizeWindow, false);
- document.documentElement.removeEventListener("mousemove", moveWindow, false);
- document.documentElement.removeEventListener("mouseup", stopResize, false);
- document.documentElement.removeEventListener("mouseup", stopMove, false);
-
- document.documentElement.removeAttribute('moving');
- beforeEvent && checkClick(beforeEvent, e);
- beforeEvent = null;
-
- e.stopImmediatePropagation();
- e.stopPropagation();
-
- }
-
-
- function reset() {
-
- document.documentElement.removeAttribute('moving');
- document.documentElement.removeEventListener("mousemove", resizeWindow, false);
- document.documentElement.removeEventListener("mousemove", moveWindow, false);
- document.documentElement.removeEventListener("mouseup", stopResize, false);
- document.documentElement.removeEventListener("mouseup", stopMove, false);
-
-
- startX = 0;
- startY = 0;
- startWidth = 0;
- startHeight = 0;
-
-
- edge = 0;
-
-
- initialLeft = 0;
- initialTop = 0;
-
- beforeEvent = null;
-
-
- }
-
- function iframeLoaded() {
-
- }
-
- function iframeFullscreenChanged() {
- const iframeDoc = this;
-
-
- if (!document.fullscreenElement) {
- iframeDoc.documentElement.classList.remove('youtube-floating-chat-iframe');
- } else {
- iframeDoc.documentElement.classList.add('youtube-floating-chat-iframe');
-
- }
-
-
- }
-
- let iframeFullscreenChangedBinded = null;
-
-
-
- function onMessage(evt) {
- if (evt.data === hkey_script) {
-
- const iframeWin = evt.source;
- if (!iframeWin) return;
- const iframeDoc = iframeWin.document;
-
- function onReady() {
-
- iframeDoc.head.appendChild(document.createElement('style')).textContent = createStyleTextForIframe();
-
- if (iframeFullscreenChangedBinded) document.removeEventListener('fullscreenchange', iframeFullscreenChangedBinded, false);
- iframeFullscreenChangedBinded = iframeFullscreenChanged.bind(iframeDoc);
- document.addEventListener('fullscreenchange', iframeFullscreenChangedBinded, false);
-
- iframeFullscreenChangedBinded();
-
- }
-
- Promise.resolve().then(() => {
-
- if (iframeDoc.readyState !== 'loading') {
- onReady();
- } else {
- iframeWin.addEventListener("DOMContentLoaded", onReady, false);
- }
-
- });
-
-
- }
-
- }
-
-
- function setChat(chat) {
-
- let resizeHandle = HTMLElement.prototype.querySelector.call(chat, '.resize-handle')
- if (resizeHandle) return;
-
-
-
- let cw = (() => {
- try {
- const { head, body } = chat.$.chatframe.contentWindow.document;
- return { head, body }
-
- } catch (e) { return null; }
- })();
-
- if (!cw) return;
-
- window.removeEventListener('message', onMessage, false);
- window.addEventListener('message', onMessage, false);
-
-
-
- let script = document.getElementById('rvZ0t') || (document.evaluate("//div[contains(text(), 'userscript-control[enable-customized-floating-window]')]", document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null) || 0).singleNodeValue;
- if (!script) addCSS(createStyleTextForTopWin);
-
- if (!document.documentElement.hasAttribute('floating-chat-window')) document.documentElement.setAttribute('floating-chat-window', '');
-
-
- chat.setAttribute('allowtransparency', 'true');
-
-
-
- resizeHandle = document.createElement("div");
- resizeHandle.className = "resize-handle";
- chat.appendChild(resizeHandle);
- resizeHandle = null;
-
- let chatWindow;
- let showHideButton;
-
- chatWindow = kRef(chatWindowWR);
- showHideButton = kRef(showHideButtonWR);
-
-
-
- if (chatWindow) chatWindow.removeEventListener("mousedown", initializeResize, false);
- if (showHideButton) showHideButton.removeEventListener("mousedown", initializeMove, false);
-
-
- chatWindow = chat;
- showHideButton = HTMLElement.prototype.querySelector.call(chat, '#show-hide-button');
- chatWindowWR = mWeakRef(chat)
- showHideButtonWR = mWeakRef(showHideButton);
-
-
-
- chatWindow.addEventListener("mousedown", initializeResize, false);
- showHideButton.addEventListener("mousedown", initializeMove, false);
-
- reset();
-
- }
-
-
- const fullscreenchangePageFn = () => {
- if (!document.fullscreenElement) {
- document.documentElement.classList.remove('no-floating')
- }
- };
-
- function noChat(chat) {
-
- let chatWindow;
- let showHideButton;
-
- chatWindow = kRef(chatWindowWR);
- showHideButton = kRef(showHideButtonWR);
-
-
-
- if (chatWindow) chatWindow.removeEventListener("mousedown", initializeResize, false);
- if (showHideButton) showHideButton.removeEventListener("mousedown", initializeMove, false);
-
-
- let resizeHandle = HTMLElement.prototype.querySelector.call(chat, '.resize-handle')
- if (resizeHandle) {
- resizeHandle.remove();
- }
-
- chat.removeEventListener("mousedown", initializeResize, false);
-
-
- showHideButton = HTMLElement.prototype.querySelector.call(chat, '#show-hide-button');
-
- if (showHideButton) showHideButton.removeEventListener("mousedown", initializeMove, false);
-
-
- reset();
- }
-
-
- document.removeEventListener('fullscreenchange', fullscreenchangePageFn, false);
- document.addEventListener('fullscreenchange', fullscreenchangePageFn, false);
- fullscreenchangePageFn();
-
- customYtElements.whenRegistered('ytd-live-chat-frame', (proto) => {
-
-
- proto.attached = ((attached) => (function () { Promise.resolve(this).then(setChat); return attached.apply(this, arguments) }))(proto.attached);
-
- proto.detached = ((detached) => (function () { Promise.resolve(this).then(noChat); return detached.apply(this, arguments) }))(proto.detached);
-
- let chat = document.querySelector('ytd-live-chat-frame');
- if (chat) Promise.resolve(chat).then(setChat);
-
- })
-
-
- });
-
-
- } else if (isIframe && top === parent) {
-
-
-
- top.postMessage(hkey_script, `${location.protocol}//${location.hostname}`);
-
-
-
-
- }
-
-
-
-
-
- })({ requestAnimationFrame });