Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: Don't use copyStyleSheets with documentPIP #8314

Merged
merged 4 commits into from
Jul 7, 2023
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/js/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 => {
Dom.copyStyleSheetsToWindow(pipWindow);
this.el_.parentNode.insertBefore(pipContainer, this.el_);

pipWindow.document.body.append(this.el_);
Expand Down
30 changes: 30 additions & 0 deletions src/js/utils/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 sheets 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);
}
1 change: 1 addition & 0 deletions test/unit/player.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
45 changes: 45 additions & 0 deletions test/unit/utils/dom.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 <style> element only');

const fakeWindowStyle = fakeWindow.document.head.querySelectorAll('style')[0];

assert.true(fakeWindowStyle.textContent.includes(style1.textContent), 'the <style> in the fake window contains content from first <style> element');
assert.true(fakeWindowStyle.textContent.includes(style2.textContent), 'the <style> in the fake window contains content from second <style> element');

assert.strictEqual(fakeWindow.document.head.querySelectorAll('link[rel=stylesheet]').length, 1, 'the fake window has one <link> stylesheet element');

const fakeWindowLink = fakeWindow.document.head.querySelectorAll('link[rel=stylesheet]')[0];

assert.strictEqual(fakeWindowLink.type, link.type, 'the <style> type attribute in the fake window is the one from <link> element');
assert.strictEqual(fakeWindowLink.href, link.href, 'the <style> href attribute in the fake window is the one from <link> element');
assert.strictEqual(fakeWindowLink.media, link.media, 'the <style> media attribute in the fake window is the one from <link> element');
});