diff --git a/src/js/player.js b/src/js/player.js index ece584467c..8eceeaa379 100644 --- a/src/js/player.js +++ b/src/js/player.js @@ -776,6 +776,19 @@ class Player extends Component { // Default state of video is paused this.addClass('vjs-paused'); + const deviceClassNames = [ + 'IS_SMART_TV', + 'IS_TIZEN', + 'IS_WEBOS', + 'IS_ANDROID', + 'IS_IPAD', + 'IS_IPHONE' + ].filter(key => browser[key]).map(key => { + return 'vjs-device-' + key.substring(3).toLowerCase().replace(/\_/g, '-'); + }); + + this.addClass(...deviceClassNames); + // Add a style element in the player that we'll use to set the width/height // of the player in a way that's still overridable by CSS, just like the // video element diff --git a/src/js/utils/browser.js b/src/js/utils/browser.js index e85ee4f9e7..607986d924 100644 --- a/src/js/utils/browser.js +++ b/src/js/utils/browser.js @@ -156,6 +156,14 @@ export let IS_TIZEN = false; */ export let IS_WEBOS = false; +/** + * Whether or not this is a Smart TV (Tizen or WebOS) device. + * + * @static + * @type {Boolean} + */ +export let IS_SMART_TV = false; + /** * Whether or not this device is touch-enabled. * @@ -255,7 +263,9 @@ if (!IS_CHROMIUM) { IS_WEBOS = (/Web0S/i).test(USER_AGENT); - IS_SAFARI = (/Safari/i).test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE && !IS_TIZEN && !IS_WEBOS; + IS_SMART_TV = IS_TIZEN || IS_WEBOS; + + IS_SAFARI = (/Safari/i).test(USER_AGENT) && !IS_CHROME && !IS_ANDROID && !IS_EDGE && !IS_SMART_TV; IS_WINDOWS = (/Windows/i).test(USER_AGENT); diff --git a/test/unit/player.test.js b/test/unit/player.test.js index 4feb3ea34b..34ce4a6a90 100644 --- a/test/unit/player.test.js +++ b/test/unit/player.test.js @@ -967,6 +967,84 @@ QUnit.test('should add a touch-enabled classname when touch is supported', funct player.dispose(); }); +QUnit.test('should add smart-tv classname when on smart tv', function(assert) { + assert.expect(1); + + browser.stub_IS_SMART_TV(true); + + const player = TestHelpers.makePlayer({}); + + assert.ok(player.hasClass('vjs-device-smart-tv'), 'smart-tv classname added'); + + browser.reset_IS_SMART_TV(); + player.dispose(); +}); + +QUnit.test('should add webos classname when on webos', function(assert) { + assert.expect(1); + + browser.stub_IS_WEBOS(true); + + const player = TestHelpers.makePlayer({}); + + assert.ok(player.hasClass('vjs-device-webos'), 'webos classname added'); + + browser.reset_IS_WEBOS(); + player.dispose(); +}); + +QUnit.test('should add tizen classname when on tizen', function(assert) { + assert.expect(1); + + browser.stub_IS_TIZEN(true); + + const player = TestHelpers.makePlayer({}); + + assert.ok(player.hasClass('vjs-device-tizen'), 'tizen classname added'); + + browser.reset_IS_TIZEN(); + player.dispose(); +}); + +QUnit.test('should add android classname when on android', function(assert) { + assert.expect(1); + + browser.stub_IS_ANDROID(true); + + const player = TestHelpers.makePlayer({}); + + assert.ok(player.hasClass('vjs-device-android'), 'android classname added'); + + browser.reset_IS_ANDROID(); + player.dispose(); +}); + +QUnit.test('should add ipad classname when on ipad', function(assert) { + assert.expect(1); + + browser.stub_IS_IPAD(true); + + const player = TestHelpers.makePlayer({}); + + assert.ok(player.hasClass('vjs-device-ipad'), 'ipad classname added'); + + browser.reset_IS_IPAD(); + player.dispose(); +}); + +QUnit.test('should add iphone classname when on iphone', function(assert) { + assert.expect(1); + + browser.stub_IS_IPHONE(true); + + const player = TestHelpers.makePlayer({}); + + assert.ok(player.hasClass('vjs-device-iphone'), 'iphone classname added'); + + browser.reset_IS_IPHONE(); + player.dispose(); +}); + QUnit.test('should add a svg-icons-enabled classname when svg icons are supported', function(assert) { // Stub a successful parsing of the SVG sprite. sinon.stub(window.DOMParser.prototype, 'parseFromString').returns({ @@ -3492,3 +3570,4 @@ QUnit.test('smooth seeking set to true should update the display time components seekBarUpdate.restore(); player.dispose(); }); +