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
+
npm start
+
open http://localhost:9999/sandbox/index.html
+
+
+
Tap on video to play/pause
+
+
+
+
+
+
+
diff --git a/src/js/video.js b/src/js/video.js
index 2734cf08d..12a3d8235 100644
--- a/src/js/video.js
+++ b/src/js/video.js
@@ -149,7 +149,12 @@ function videojs(id, options, ready) {
// 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.
// 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');
}
diff --git a/test/unit/utils/custom-element.test.js b/test/unit/utils/custom-element.test.js
new file mode 100644
index 000000000..a60f793da
--- /dev/null
+++ b/test/unit/utils/custom-element.test.js
@@ -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);
diff --git a/test/unit/video.test.js b/test/unit/video.test.js
index 2b041b9ba..327437b0d 100644
--- a/test/unit/video.test.js
+++ b/test/unit/video.test.js
@@ -4,6 +4,8 @@ import * as Dom from '../../src/js/utils/dom.js';
import log from '../../src/js/utils/log.js';
import document from 'global/document';
import sinon from 'sinon';
+// import custom element for Shadow DOM test
+import './utils/custom-element.test';
QUnit.module('video.js', {
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(
'should log about already initialized players if options already passed',
function(assert) {