1
0
mirror of https://github.com/videojs/video.js.git synced 2025-01-02 06:32:07 +02:00

fix: Don't use copyStyleSheets with documentPIP (#8314)

* Don't use copyStyleSheets

* Move to dom.js

* Add tests

* Address feedback
This commit is contained in:
François Beaufort 2023-07-07 15:56:54 +02:00 committed by GitHub
parent c11d213453
commit 8dd98f602b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 79 additions and 2 deletions

View File

@ -3095,9 +3095,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_);

View File

@ -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);
}
});
}

View File

@ -2919,6 +2919,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) {

View File

@ -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');
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);
});