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 all 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
27 changes: 27 additions & 0 deletions src/js/utils/dom.js
Original file line number Diff line number Diff line change
Expand Up @@ -857,3 +857,30 @@ 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) {
[...document.styleSheets].forEach((styleSheet) => {
try {
const cssRules = [...styleSheet.cssRules].map((rule) => rule.cssText).join('');
const style = document.createElement('style');

style.textContent = cssRules;
win.document.head.appendChild(style);
} 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);
}
});
}
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
49 changes: 49 additions & 0 deletions test/unit/utils/dom.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -686,3 +686,52 @@ 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');
beaufortfrancois marked this conversation as resolved.
Show resolved Hide resolved
const done = assert.async();

assert.expect(7);

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';

const containsRulesFromStyle = (el) => {
return Boolean([...fakeWindow.document.head.querySelectorAll('style')].find(s => {
return s.textContent.includes(el.textContent);
}));
};

link.onload = link.onerror = () => {
Dom.copyStyleSheetsToWindow(fakeWindow);
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');
assert.true(containsRulesFromStyle(style1), 'a <style> in the fake window contains content from first <style> element');
assert.true(containsRulesFromStyle(style2), 'a <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');
done();
};
document.head.appendChild(link);
});