mirror of
https://github.com/videojs/video.js.git
synced 2025-02-04 11:43:27 +02:00
fix(shadow-dom): prevent warning 'element supplied is not included' (#8192)
Co-authored-by: Giuseppe Piscopo <g.piscopo@braincrumbz.com>
This commit is contained in:
parent
3dece507bc
commit
dc1e2bb42a
@ -52,7 +52,7 @@
|
|||||||
"minify:css:cdn": "cleancss dist/alt/video-js-cdn.css -o dist/alt/video-js-cdn.min.css",
|
"minify:css:cdn": "cleancss dist/alt/video-js-cdn.css -o dist/alt/video-js-cdn.min.css",
|
||||||
"minify:css:default": "cleancss dist/video-js.css -o dist/video-js.min.css",
|
"minify:css:default": "cleancss dist/video-js.css -o dist/video-js.min.css",
|
||||||
"watch": "npm-run-all -p watch:*",
|
"watch": "npm-run-all -p watch:*",
|
||||||
"watch:lang": "chokidar --initial 'lang/**/!(zh-Hans|zh-Hant)*.json' -c 'npm run build:lang'",
|
"watch:lang": "chokidar --initial \"lang/**/!(zh-Hans|zh-Hant)*.json\" -c \"npm run build:lang\"",
|
||||||
"watch:rollup": "rollup -c -w --no-progress",
|
"watch:rollup": "rollup -c -w --no-progress",
|
||||||
"watch:types": "tsc -w",
|
"watch:types": "tsc -w",
|
||||||
"watch:css": "npm-run-all -p build:css:default build:css:cdn watch:css:*",
|
"watch:css": "npm-run-all -p build:css:default build:css:cdn watch:css:*",
|
||||||
|
79
sandbox/shadow-dom.html.example
Normal file
79
sandbox/shadow-dom.html.example
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<title>Video.js Sandbox</title>
|
||||||
|
<link href="../dist/video-js.css" rel="stylesheet" type="text/css">
|
||||||
|
<script src="../dist/video.js"></script>
|
||||||
|
<link rel="icon" href="data:;base64,=">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div style="background-color:#eee; border: 1px solid #777; padding: 10px; margin-bottom: 20px; font-size: .8em; line-height: 1.5em; font-family: Verdana, sans-serif;">
|
||||||
|
<p>You can use /sandbox/ for writing and testing your own code. Nothing in /sandbox/ will get checked into the repo, except files that end in .example (so don't edit or add those files). To get started run `npm start` and open the index.html</p>
|
||||||
|
<pre>npm start</pre>
|
||||||
|
<pre>open http://localhost:9999/sandbox/index.html</pre>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<p>Tap on video to play/pause</p>
|
||||||
|
|
||||||
|
<test-custom-element id="customElement1"></test-custom-element>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// Custom Element definition
|
||||||
|
class TestCustomElement extends HTMLElement {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
const shadowRoot = this.attachShadow({ mode: 'closed' });
|
||||||
|
|
||||||
|
const styleLinkElem = document.createElement('link');
|
||||||
|
|
||||||
|
styleLinkElem.setAttribute('rel', 'stylesheet');
|
||||||
|
styleLinkElem.setAttribute('href', '../dist/video-js.css')
|
||||||
|
shadowRoot.append(styleLinkElem);
|
||||||
|
|
||||||
|
const containerElem = document.createElement('div');
|
||||||
|
|
||||||
|
containerElem.setAttribute('data-vjs-player', '');
|
||||||
|
shadowRoot.appendChild(containerElem);
|
||||||
|
|
||||||
|
const videoElem = document.createElement('video');
|
||||||
|
|
||||||
|
videoElem.setAttribute('preload', 'auto');
|
||||||
|
videoElem.setAttribute('width', 640);
|
||||||
|
videoElem.setAttribute('height', 260);
|
||||||
|
containerElem.appendChild(videoElem);
|
||||||
|
|
||||||
|
const sourceElem = document.createElement('source');
|
||||||
|
|
||||||
|
sourceElem.setAttribute('src', 'https://vjs.zencdn.net/v/oceans.mp4');
|
||||||
|
sourceElem.setAttribute('type', 'video/mp4');
|
||||||
|
videoElem.appendChild(sourceElem);
|
||||||
|
|
||||||
|
this.innerPlayer = videojs(videoElem);
|
||||||
|
|
||||||
|
containerElem.addEventListener('click', () => {
|
||||||
|
if (this.innerPlayer.paused()) {
|
||||||
|
this.innerPlayer.play();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.innerPlayer.pause();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.customElements.define('test-custom-element', TestCustomElement);
|
||||||
|
|
||||||
|
// Main entry point
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
var customElem = document.getElementById('customElement1');
|
||||||
|
var innerPlayer = customElem.innerPlayer;
|
||||||
|
innerPlayer.log('Shadow DOM inner player created', innerPlayer);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -149,7 +149,12 @@ function videojs(id, options, ready) {
|
|||||||
// This will make sure that the element is indeed in the dom of that document.
|
// This will make sure that the element is indeed in the dom of that document.
|
||||||
// Additionally, check that the document in question has a default view.
|
// Additionally, check that the document in question has a default view.
|
||||||
// If the document is no longer attached to the dom, the defaultView of the document will be null.
|
// If the document is no longer attached to the dom, the defaultView of the document will be null.
|
||||||
if (!el.ownerDocument.defaultView || !el.ownerDocument.body.contains(el)) {
|
// If element is inside Shadow DOM (e.g. is part of a Custom element), ownerDocument.body
|
||||||
|
// always returns false. Instead, use the Shadow DOM root.
|
||||||
|
const inShadowDom = el.getRootNode() instanceof window.ShadowRoot;
|
||||||
|
const rootNode = inShadowDom ? el.getRootNode() : el.ownerDocument.body;
|
||||||
|
|
||||||
|
if (!el.ownerDocument.defaultView || !rootNode.contains(el)) {
|
||||||
log.warn('The element supplied is not included in the DOM');
|
log.warn('The element supplied is not included in the DOM');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
26
test/unit/utils/custom-element.test.js
Normal file
26
test/unit/utils/custom-element.test.js
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
/* eslint-env browser */
|
||||||
|
import videojs from '../../../src/js/video.js';
|
||||||
|
|
||||||
|
export class TestCustomElement extends HTMLElement {
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
|
||||||
|
const shadowRoot = this.attachShadow({ mode: 'closed' });
|
||||||
|
|
||||||
|
const containerElem = document.createElement('div');
|
||||||
|
|
||||||
|
containerElem.setAttribute('data-vjs-player', '');
|
||||||
|
shadowRoot.appendChild(containerElem);
|
||||||
|
|
||||||
|
const videoElem = document.createElement('video');
|
||||||
|
|
||||||
|
videoElem.setAttribute('width', 640);
|
||||||
|
videoElem.setAttribute('height', 260);
|
||||||
|
containerElem.appendChild(videoElem);
|
||||||
|
|
||||||
|
this.innerPlayer = videojs(videoElem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
window.customElements.define('test-custom-element', TestCustomElement);
|
@ -4,6 +4,8 @@ import * as Dom from '../../src/js/utils/dom.js';
|
|||||||
import log from '../../src/js/utils/log.js';
|
import log from '../../src/js/utils/log.js';
|
||||||
import document from 'global/document';
|
import document from 'global/document';
|
||||||
import sinon from 'sinon';
|
import sinon from 'sinon';
|
||||||
|
// import custom element for Shadow DOM test
|
||||||
|
import './utils/custom-element.test';
|
||||||
|
|
||||||
QUnit.module('video.js', {
|
QUnit.module('video.js', {
|
||||||
beforeEach() {
|
beforeEach() {
|
||||||
@ -84,6 +86,29 @@ QUnit.test(
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
QUnit.test(
|
||||||
|
'should not log if the supplied element is included in the Shadow DOM',
|
||||||
|
function(assert) {
|
||||||
|
const origWarnLog = log.warn;
|
||||||
|
const fixture = document.getElementById('qunit-fixture');
|
||||||
|
const warnLogs = [];
|
||||||
|
|
||||||
|
log.warn = (args) => {
|
||||||
|
warnLogs.push(args);
|
||||||
|
};
|
||||||
|
|
||||||
|
const customElem = document.createElement('test-custom-element');
|
||||||
|
|
||||||
|
fixture.appendChild(customElem);
|
||||||
|
const innerPlayer = customElem.innerPlayer;
|
||||||
|
|
||||||
|
assert.ok(innerPlayer, 'created player within Shadow DOM');
|
||||||
|
assert.equal(warnLogs.length, 0, 'no warn logs');
|
||||||
|
|
||||||
|
log.warn = origWarnLog;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
QUnit.test(
|
QUnit.test(
|
||||||
'should log about already initialized players if options already passed',
|
'should log about already initialized players if options already passed',
|
||||||
function(assert) {
|
function(assert) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user