From 69f08d58cbe603bb111787f5d345f6da5f082704 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Beaufort?= Date: Thu, 8 Jun 2023 11:58:46 +0000 Subject: [PATCH 1/4] Don't use copyStyleSheets --- src/js/player.js | 34 ++++++++++++++++++++++++++++++++-- test/unit/player.test.js | 1 + 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/js/player.js b/src/js/player.js index e516d7aea1..869bab1a84 100644 --- a/src/js/player.js +++ b/src/js/player.js @@ -3074,9 +3074,9 @@ class Player extends Component { return window.documentPictureInPicture.requestWindow({ // The aspect ratio won't be correct, Chrome bug https://crbug.com/1407629 width: this.videoWidth(), - height: this.videoHeight(), - copyStyleSheets: true + height: this.videoHeight() }).then(pipWindow => { + this.copyStyleSheetsToWindow_(pipWindow); this.el_.parentNode.insertBefore(pipContainer, this.el_); pipWindow.document.body.append(this.el_); @@ -3109,6 +3109,36 @@ class Player extends Component { return Promise.reject('No PiP mode is available'); } + /** + * Copy document style sheets to another window. + * + * @param {Window} win + * + * @private + */ + copyStyleSheetsToWindow_(win) { + const allCSS = [...document.styleSheets] + .map((styleSheet) => { + try { + return [...styleSheet.cssRules].map((rule) => rule.cssText).join(''); + } catch (e) { + const link = document.createElement('link'); + + link.rel = 'stylesheet'; + link.type = styleSheet.type; + link.media = styleSheet.media; + link.href = styleSheet.href; + win.document.head.appendChild(link); + } + }) + .filter(Boolean) + .join('\n'); + const style = document.createElement('style'); + + style.textContent = allCSS; + win.document.head.appendChild(style); + } + /** * Exit Picture-in-Picture mode. * diff --git a/test/unit/player.test.js b/test/unit/player.test.js index d8f9534263..4463e806dc 100644 --- a/test/unit/player.test.js +++ b/test/unit/player.test.js @@ -2886,6 +2886,7 @@ QUnit.test('docPiP moves player and triggers events', function(assert) { const fakePiPWindow = document.createElement('div'); fakePiPWindow.document = { + head: document.createElement('div'), body: document.createElement('div') }; fakePiPWindow.querySelector = function(sel) { From 77becf3d24662a18e8f0ad2e550d0204dacc493e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Beaufort?= Date: Mon, 19 Jun 2023 07:52:01 +0000 Subject: [PATCH 2/4] Move to dom.js --- src/js/player.js | 32 +------------------------------- src/js/utils/dom.js | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/js/player.js b/src/js/player.js index 869bab1a84..c1d59214ae 100644 --- a/src/js/player.js +++ b/src/js/player.js @@ -3076,7 +3076,7 @@ class Player extends Component { width: this.videoWidth(), height: this.videoHeight() }).then(pipWindow => { - this.copyStyleSheetsToWindow_(pipWindow); + Dom.copyStyleSheetsToWindow_(pipWindow); this.el_.parentNode.insertBefore(pipContainer, this.el_); pipWindow.document.body.append(this.el_); @@ -3109,36 +3109,6 @@ class Player extends Component { return Promise.reject('No PiP mode is available'); } - /** - * Copy document style sheets to another window. - * - * @param {Window} win - * - * @private - */ - copyStyleSheetsToWindow_(win) { - const allCSS = [...document.styleSheets] - .map((styleSheet) => { - try { - return [...styleSheet.cssRules].map((rule) => rule.cssText).join(''); - } catch (e) { - const link = document.createElement('link'); - - link.rel = 'stylesheet'; - link.type = styleSheet.type; - link.media = styleSheet.media; - link.href = styleSheet.href; - win.document.head.appendChild(link); - } - }) - .filter(Boolean) - .join('\n'); - const style = document.createElement('style'); - - style.textContent = allCSS; - win.document.head.appendChild(style); - } - /** * Exit Picture-in-Picture mode. * diff --git a/src/js/utils/dom.js b/src/js/utils/dom.js index 80a92dd21d..74d674e25e 100644 --- a/src/js/utils/dom.js +++ b/src/js/utils/dom.js @@ -857,3 +857,33 @@ export function computedStyle(el, prop) { return ''; } + +/** + * Copy document style sheets to another window. + * + * @param {Window} win + * The window element you want to copy the document style style to. + * + */ +export function copyStyleSheetsToWindow_(win) { + const allCSS = [...document.styleSheets] + .map((styleSheet) => { + try { + return [...styleSheet.cssRules].map((rule) => rule.cssText).join(''); + } catch (e) { + const link = document.createElement('link'); + + link.rel = 'stylesheet'; + link.type = styleSheet.type; + link.media = styleSheet.media; + link.href = styleSheet.href; + win.document.head.appendChild(link); + } + }) + .filter(Boolean) + .join('\n'); + const style = document.createElement('style'); + + style.textContent = allCSS; + win.document.head.appendChild(style); +} From 873d0c76c08f0f76ebb9da6ca029733f115591ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Beaufort?= Date: Mon, 19 Jun 2023 09:27:19 +0000 Subject: [PATCH 3/4] Add tests --- src/js/player.js | 2 +- src/js/utils/dom.js | 4 ++-- test/unit/utils/dom.test.js | 45 +++++++++++++++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 3 deletions(-) diff --git a/src/js/player.js b/src/js/player.js index c1d59214ae..e21a6a30f9 100644 --- a/src/js/player.js +++ b/src/js/player.js @@ -3076,7 +3076,7 @@ class Player extends Component { width: this.videoWidth(), height: this.videoHeight() }).then(pipWindow => { - Dom.copyStyleSheetsToWindow_(pipWindow); + Dom.copyStyleSheetsToWindow(pipWindow); this.el_.parentNode.insertBefore(pipContainer, this.el_); pipWindow.document.body.append(this.el_); diff --git a/src/js/utils/dom.js b/src/js/utils/dom.js index 74d674e25e..9a60465792 100644 --- a/src/js/utils/dom.js +++ b/src/js/utils/dom.js @@ -862,10 +862,10 @@ export function computedStyle(el, prop) { * Copy document style sheets to another window. * * @param {Window} win - * The window element you want to copy the document style style to. + * The window element you want to copy the document style sheets to. * */ -export function copyStyleSheetsToWindow_(win) { +export function copyStyleSheetsToWindow(win) { const allCSS = [...document.styleSheets] .map((styleSheet) => { try { diff --git a/test/unit/utils/dom.test.js b/test/unit/utils/dom.test.js index 811cd4c617..49774ed232 100644 --- a/test/unit/utils/dom.test.js +++ b/test/unit/utils/dom.test.js @@ -686,3 +686,48 @@ QUnit.test('isSingleLeftClick() checks return values for mousedown event', funct assert.ok(Dom.isSingleLeftClick(mouseEvent), 'a touch event on simulated mobiles is a single left click'); }); + +QUnit.test('Dom.copyStyleSheetsToWindow() copies all style sheets to a window', function(assert) { + const fakeWindow = document.createElement('div'); + + fakeWindow.document = { + head: document.createElement('div') + }; + + const style1 = document.createElement('style'); + + style1.textContent = 'body { background: white; }'; + document.head.appendChild(style1); + + const style2 = document.createElement('style'); + + style2.textContent = 'body { margin: 0px; }'; + document.head.appendChild(style2); + + const link = document.createElement('link'); + + link.rel = 'stylesheet'; + link.type = 'text/css'; + link.media = 'print'; + link.href = 'http://asdf.com/styles.css'; + document.head.appendChild(link); + + Dom.copyStyleSheetsToWindow(fakeWindow); + + assert.expect(7); + + assert.strictEqual(fakeWindow.document.head.querySelectorAll('style').length, 1, 'the fake window has one