Skip to content

Commit 8dd98f6

Browse files
fix: Don't use copyStyleSheets with documentPIP (#8314)
* Don't use copyStyleSheets * Move to dom.js * Add tests * Address feedback
1 parent c11d213 commit 8dd98f6

File tree

4 files changed

+79
-2
lines changed

4 files changed

+79
-2
lines changed

src/js/player.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3095,9 +3095,9 @@ class Player extends Component {
30953095
return window.documentPictureInPicture.requestWindow({
30963096
// The aspect ratio won't be correct, Chrome bug https://crbug.com/1407629
30973097
width: this.videoWidth(),
3098-
height: this.videoHeight(),
3099-
copyStyleSheets: true
3098+
height: this.videoHeight()
31003099
}).then(pipWindow => {
3100+
Dom.copyStyleSheetsToWindow(pipWindow);
31013101
this.el_.parentNode.insertBefore(pipContainer, this.el_);
31023102

31033103
pipWindow.document.body.append(this.el_);

src/js/utils/dom.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -857,3 +857,30 @@ export function computedStyle(el, prop) {
857857

858858
return '';
859859
}
860+
861+
/**
862+
* Copy document style sheets to another window.
863+
*
864+
* @param {Window} win
865+
* The window element you want to copy the document style sheets to.
866+
*
867+
*/
868+
export function copyStyleSheetsToWindow(win) {
869+
[...document.styleSheets].forEach((styleSheet) => {
870+
try {
871+
const cssRules = [...styleSheet.cssRules].map((rule) => rule.cssText).join('');
872+
const style = document.createElement('style');
873+
874+
style.textContent = cssRules;
875+
win.document.head.appendChild(style);
876+
} catch (e) {
877+
const link = document.createElement('link');
878+
879+
link.rel = 'stylesheet';
880+
link.type = styleSheet.type;
881+
link.media = styleSheet.media;
882+
link.href = styleSheet.href;
883+
win.document.head.appendChild(link);
884+
}
885+
});
886+
}

test/unit/player.test.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2919,6 +2919,7 @@ QUnit.test('docPiP moves player and triggers events', function(assert) {
29192919
const fakePiPWindow = document.createElement('div');
29202920

29212921
fakePiPWindow.document = {
2922+
head: document.createElement('div'),
29222923
body: document.createElement('div')
29232924
};
29242925
fakePiPWindow.querySelector = function(sel) {

test/unit/utils/dom.test.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -686,3 +686,52 @@ QUnit.test('isSingleLeftClick() checks return values for mousedown event', funct
686686

687687
assert.ok(Dom.isSingleLeftClick(mouseEvent), 'a touch event on simulated mobiles is a single left click');
688688
});
689+
690+
QUnit.test('Dom.copyStyleSheetsToWindow() copies all style sheets to a window', function(assert) {
691+
const fakeWindow = document.createElement('div');
692+
const done = assert.async();
693+
694+
assert.expect(7);
695+
696+
fakeWindow.document = {
697+
head: document.createElement('div')
698+
};
699+
700+
const style1 = document.createElement('style');
701+
702+
style1.textContent = 'body { background: white; }';
703+
document.head.appendChild(style1);
704+
705+
const style2 = document.createElement('style');
706+
707+
style2.textContent = 'body { margin: 0px; }';
708+
document.head.appendChild(style2);
709+
710+
const link = document.createElement('link');
711+
712+
link.rel = 'stylesheet';
713+
link.type = 'text/css';
714+
link.media = 'print';
715+
link.href = 'http://asdf.com/styles.css';
716+
717+
const containsRulesFromStyle = (el) => {
718+
return Boolean([...fakeWindow.document.head.querySelectorAll('style')].find(s => {
719+
return s.textContent.includes(el.textContent);
720+
}));
721+
};
722+
723+
link.onload = link.onerror = () => {
724+
Dom.copyStyleSheetsToWindow(fakeWindow);
725+
assert.strictEqual(fakeWindow.document.head.querySelectorAll('style, link').length, document.styleSheets.length, 'the fake window has as many <style> or <link> elements as document.styleSheets');
726+
assert.true(containsRulesFromStyle(style1), 'a <style> in the fake window contains content from first <style> element');
727+
assert.true(containsRulesFromStyle(style2), 'a <style> in the fake window contains content from second <style> element');
728+
assert.strictEqual(fakeWindow.document.head.querySelectorAll('link[rel=stylesheet]').length, 1, 'the fake window has one <link> stylesheet element');
729+
const fakeWindowLink = fakeWindow.document.head.querySelectorAll('link[rel=stylesheet]')[0];
730+
731+
assert.strictEqual(fakeWindowLink.type, link.type, 'the <style> type attribute in the fake window is the one from <link> element');
732+
assert.strictEqual(fakeWindowLink.href, link.href, 'the <style> href attribute in the fake window is the one from <link> element');
733+
assert.strictEqual(fakeWindowLink.media, link.media, 'the <style> media attribute in the fake window is the one from <link> element');
734+
done();
735+
};
736+
document.head.appendChild(link);
737+
});

0 commit comments

Comments
 (0)