From f7b5e5ec602b0455b5d97cc9f6bdb1a92e05255d Mon Sep 17 00:00:00 2001 From: Steve Heffernan Date: Thu, 5 Dec 2013 16:45:31 -0800 Subject: [PATCH] Moved all player exports to externs. Updated isFullScreen to be a function. --- src/js/control-bar/fullscreen-toggle.js | 2 +- src/js/exports.js | 11 +---- src/js/player.externs.js | 66 ++++++++++++++++++++++++- src/js/player.js | 51 ++++++++++++++++--- src/js/tracks.js | 2 +- test/unit/api.js | 54 +++++++++++++++----- test/unit/player.js | 2 +- 7 files changed, 156 insertions(+), 32 deletions(-) diff --git a/src/js/control-bar/fullscreen-toggle.js b/src/js/control-bar/fullscreen-toggle.js index 3e16b4379c..831b9c9775 100644 --- a/src/js/control-bar/fullscreen-toggle.js +++ b/src/js/control-bar/fullscreen-toggle.js @@ -23,7 +23,7 @@ vjs.FullscreenToggle.prototype.buildCSSClass = function(){ }; vjs.FullscreenToggle.prototype.onClick = function(){ - if (!this.player_.isFullScreen) { + if (!this.player_.isFullScreen()) { this.player_.requestFullScreen(); this.el_.children[0].children[0].innerHTML = 'Non-Fullscreen'; // change the button text to "Non-Fullscreen" } else { diff --git a/src/js/exports.js b/src/js/exports.js index e7569c750b..b7001be9d8 100644 --- a/src/js/exports.js +++ b/src/js/exports.js @@ -59,15 +59,8 @@ goog.exportProperty(vjs.Component.prototype, 'ready', vjs.Component.prototype.re goog.exportProperty(vjs.Component.prototype, 'addClass', vjs.Component.prototype.addClass); goog.exportProperty(vjs.Component.prototype, 'removeClass', vjs.Component.prototype.removeClass); -goog.exportSymbol('videojs.Player', vjs.Player); -goog.exportProperty(vjs.Player.prototype, 'dispose', vjs.Player.prototype.dispose); -goog.exportProperty(vjs.Player.prototype, 'requestFullScreen', vjs.Player.prototype.requestFullScreen); -goog.exportProperty(vjs.Player.prototype, 'cancelFullScreen', vjs.Player.prototype.cancelFullScreen); -goog.exportProperty(vjs.Player.prototype, 'bufferedPercent', vjs.Player.prototype.bufferedPercent); -goog.exportProperty(vjs.Player.prototype, 'textTracks', vjs.Player.prototype.textTracks); -goog.exportProperty(vjs.Player.prototype, 'usingNativeControls', vjs.Player.prototype.usingNativeControls); -goog.exportProperty(vjs.Player.prototype, 'reportUserActivity', vjs.Player.prototype.reportUserActivity); -goog.exportProperty(vjs.Player.prototype, 'userActive', vjs.Player.prototype.userActive); +// Need to export ended to ensure it's not removed by CC, since it's not used internally +goog.exportProperty(vjs.Player.prototype, 'ended', vjs.Player.prototype.ended); goog.exportSymbol('videojs.MediaLoader', vjs.MediaLoader); goog.exportSymbol('videojs.TextTrackDisplay', vjs.TextTrackDisplay); diff --git a/src/js/player.externs.js b/src/js/player.externs.js index 8d2538dbec..d1a2942f5c 100644 --- a/src/js/player.externs.js +++ b/src/js/player.externs.js @@ -3,10 +3,53 @@ * compiler shouldn't obfuscate. */ +/** + * @constructor + * @extends {videojs.Component} + */ + videojs.Player = function(){}; + +/** + * Native HTML5 video properties + * Most likely covered by the default closure compiler externs + * Copied list from http://code.google.com/p/closure-compiler/source/browse/externs/html5.js?spec=svne2e531de906d9ccccf23516bd2dd6152a93f6468&r=e2e531de906d9ccccf23516bd2dd6152a93f6468 + * May not all be available on a videojs player yet + */ +videojs.Player.prototype.error = function(){}; +videojs.Player.prototype.src = function(){}; +videojs.Player.prototype.currentSrc = function(){}; +videojs.Player.prototype.networkState = function(){}; +videojs.Player.prototype.buffered = function(){}; +videojs.Player.prototype.load = function(){}; +videojs.Player.prototype.canPlayType = function(){}; +videojs.Player.prototype.readyState = function(){}; +videojs.Player.prototype.seeking = function(){}; +videojs.Player.prototype.currentTime = function(){}; +videojs.Player.prototype.startTime = function(){}; +videojs.Player.prototype.duration = function(){}; +videojs.Player.prototype.paused = function(){}; +videojs.Player.prototype.defaultPlaybackRate = function(){}; +videojs.Player.prototype.playbackRate = function(){}; +videojs.Player.prototype.played = function(){}; +videojs.Player.prototype.seekable = function(){}; +videojs.Player.prototype.ended = function(){}; +videojs.Player.prototype.autoplay = function(){}; +videojs.Player.prototype.loop = function(){}; +videojs.Player.prototype.play = function() {}; +videojs.Player.prototype.pause = function() {}; +videojs.Player.prototype.controls = function(){}; +videojs.Player.prototype.volume = function(){}; +videojs.Player.prototype.muted = function(){}; +videojs.Player.prototype.width = function(){}; +videojs.Player.prototype.height = function(){}; +videojs.Player.prototype.videoWidth = function(){}; +videojs.Player.prototype.videoHeight = function(){}; +videojs.Player.prototype.poster = function(){}; + /** * Fullscreen functionality */ -videojs.Player.prototype.isFullScreen = undefined; +videojs.Player.prototype.isFullScreen = function(){}; videojs.Player.prototype.requestFullScreen = function(){}; videojs.Player.prototype.cancelFullScreen = function(){}; @@ -14,3 +57,24 @@ videojs.Player.prototype.cancelFullScreen = function(){}; * Text tracks */ videojs.Player.prototype.textTracks = function(){}; + +/** + * Component functions + */ +videojs.Player.prototype.dispose = function(){}; + +/** + * Buffered percent + */ +videojs.Player.prototype.bufferedPercent = function(){}; + +/** + * User activity functions + */ +videojs.Player.prototype.reportUserActivity = function(){}; +videojs.Player.prototype.userActive = function(){}; + +/** + * Native controls + */ +videojs.Player.prototype.usingNativeControls = function(){}; diff --git a/src/js/player.js b/src/js/player.js index b7e47770e1..4f625f91f8 100644 --- a/src/js/player.js +++ b/src/js/player.js @@ -516,7 +516,7 @@ vjs.Player.prototype.onVolumeChange; * @event fullscreenchange */ vjs.Player.prototype.onFullscreenChange = function() { - if (this.isFullScreen) { + if (this.isFullScreen()) { this.addClass('vjs-fullscreen'); } else { this.removeClass('vjs-fullscreen'); @@ -802,8 +802,43 @@ vjs.Player.prototype.muted = function(muted){ return this.techGet('muted') || false; // Default to false }; -// Check if current tech can support native fullscreen (e.g. with built in controls lik iOS, so not our flash swf) -vjs.Player.prototype.supportsFullScreen = function(){ return this.techGet('supportsFullScreen') || false; }; +// Check if current tech can support native fullscreen +// (e.g. with built in controls lik iOS, so not our flash swf) +vjs.Player.prototype.supportsFullScreen = function(){ + return this.techGet('supportsFullScreen') || false; +}; + +/** + * is the player in fullscreen + * @type {Boolean} + * @private + */ +vjs.Player.prototype.isFullScreen_ = false; + +/** + * Check if the player is in fullscreen mode + * + * // get + * var fullscreenOrNot = myPlayer.isFullScreen(); + * + * // set + * myPlayer.isFullScreen(true); // tell the player it's in fullscreen + * + * NOTE: As of the latest HTML5 spec, isFullScreen is no longer an official + * property and instead document.fullscreenElement is used. But isFullScreen is + * still a valuable property for internal player workings. + * + * @param {Boolean=} isFS Update the player's fullscreen state + * @return {Boolean} true if fullscreen, false if not + * @return {vjs.Player} self, when setting + */ +vjs.Player.prototype.isFullScreen = function(isFS){ + if (isFS !== undefined) { + this.isFullScreen_ = isFS; + return this; + } + return this.isFullScreen_; +}; /** * Increase the size of the video to full screen @@ -821,7 +856,7 @@ vjs.Player.prototype.supportsFullScreen = function(){ return this.techGet('suppo */ vjs.Player.prototype.requestFullScreen = function(){ var requestFullScreen = vjs.support.requestFullScreen; - this.isFullScreen = true; + this.isFullScreen(true); if (requestFullScreen) { // the browser supports going fullscreen at the element level so we can @@ -833,10 +868,10 @@ vjs.Player.prototype.requestFullScreen = function(){ // players on a page, they would all be reacting to the same fullscreen // events vjs.on(document, requestFullScreen.eventName, vjs.bind(this, function(e){ - this.isFullScreen = document[requestFullScreen.isFullScreen]; + this.isFullScreen(document[requestFullScreen.isFullScreen]); // If cancelling fullscreen, remove event listener. - if (this.isFullScreen === false) { + if (this.isFullScreen() === false) { vjs.off(document, requestFullScreen.eventName, arguments.callee); } @@ -868,7 +903,7 @@ vjs.Player.prototype.requestFullScreen = function(){ */ vjs.Player.prototype.cancelFullScreen = function(){ var requestFullScreen = vjs.support.requestFullScreen; - this.isFullScreen = false; + this.isFullScreen(false); // Check for browser element fullscreen support if (requestFullScreen) { @@ -903,7 +938,7 @@ vjs.Player.prototype.enterFullWindow = function(){ }; vjs.Player.prototype.fullWindowOnEscKey = function(event){ if (event.keyCode === 27) { - if (this.isFullScreen === true) { + if (this.isFullScreen() === true) { this.cancelFullScreen(); } else { this.exitFullWindow(); diff --git a/src/js/tracks.js b/src/js/tracks.js index 9ffb8142c4..97b857d790 100644 --- a/src/js/tracks.js +++ b/src/js/tracks.js @@ -307,7 +307,7 @@ vjs.TextTrack.prototype.mode = function(){ * and restore it to its normal size when not in fullscreen mode. */ vjs.TextTrack.prototype.adjustFontSize = function(){ - if (this.player_.isFullScreen) { + if (this.player_.isFullScreen()) { // Scale the font by the same factor as increasing the video width to the full screen window width. // Additionally, multiply that factor by 1.4, which is the default font size for // the caption track (from the CSS) diff --git a/test/unit/api.js b/test/unit/api.js index c422c51bbd..77df09c317 100644 --- a/test/unit/api.js +++ b/test/unit/api.js @@ -4,30 +4,58 @@ test('should be able to access expected player API methods', function() { var player = PlayerTest.makePlayer(); // Native HTML5 Methods - ok(player.play, 'play exists'); - ok(player.pause, 'pause exists'); - ok(player.paused, 'paused exists'); + ok(player.error, 'error exists'); ok(player.src, 'src exists'); + ok(player.currentSrc, 'currentSrc exists'); + ok(player.buffered, 'buffered exists'); + ok(player.load, 'load exists'); + ok(player.seeking, 'seeking exists'); ok(player.currentTime, 'currentTime exists'); ok(player.duration, 'duration exists'); - ok(player.buffered, 'buffered exists'); + ok(player.paused, 'paused exists'); + ok(player.ended, 'ended exists'); + ok(player.autoplay, 'autoplay exists'); + ok(player.loop, 'loop exists'); + ok(player.play , 'play exists'); + ok(player.pause , 'pause exists'); + ok(player.controls, 'controls exists'); ok(player.volume, 'volume exists'); ok(player.muted, 'muted exists'); ok(player.width, 'width exists'); ok(player.height, 'height exists'); + ok(player.poster, 'poster exists'); + ok(player.textTracks, 'textTracks exists'); ok(player.requestFullScreen, 'requestFullScreen exists'); ok(player.cancelFullScreen, 'cancelFullScreen exists'); - // Added player methods + // Unsupported Native HTML5 Methods + // ok(player.canPlayType, 'canPlayType exists'); + // ok(player.readyState, 'readyState exists'); + // ok(player.networkState, 'networkState exists'); + // ok(player.startTime, 'startTime exists'); + // ok(player.defaultPlaybackRate, 'defaultPlaybackRate exists'); + // ok(player.playbackRate, 'playbackRate exists'); + // ok(player.played, 'played exists'); + // ok(player.seekable, 'seekable exists'); + // ok(player.videoWidth, 'videoWidth exists'); + // ok(player.videoHeight, 'videoHeight exists'); + + // Additional player methods + ok(player.bufferedPercent, 'bufferedPercent exists'); + ok(player.reportUserActivity, 'reportUserActivity exists'); + ok(player.userActive, 'userActive exists'); + ok(player.usingNativeControls, 'usingNativeControls exists'); + ok(player.isFullScreen, 'isFullScreen exists'); + + // Component methods ok(player.ready, 'ready exists'); ok(player.on, 'on exists'); ok(player.off, 'off exists'); ok(player.one, 'one exists'); - ok(player.bufferedPercent, 'bufferedPercent exists'); ok(player.dimensions, 'dimensions exists'); ok(player.addClass, 'addClass exists'); ok(player.removeClass, 'removeClass exists'); - ok(player.usingNativeControls, 'usingNativeControls exists'); + ok(player.dispose, 'dispose exists'); player.dispose(); }); @@ -110,7 +138,7 @@ test('videojs.players should be available after minification', function() { // NOTE: This test could be removed after we've landed on a permanent // externs/exports strategy. See comment on videojs/video.js#853 test('fullscreenToggle does not depend on minified player methods', function(){ - var noop, player, fullscreen, requestFullScreen, cancelFullScreen; + var noop, player, fullscreen, requestFullScreen, cancelFullScreen, isFullScreen_; noop = function(){}; requestFullScreen = false; cancelFullScreen = false; @@ -124,16 +152,20 @@ test('fullscreenToggle does not depend on minified player methods', function(){ requestFullScreen = true; }; player['cancelFullScreen'] = function(){ - cancelFullScreen = true; + cancelFullScreen = true; + }; + + isFullScreen_ = false; + player['isFullScreen'] = function(){ + return isFullScreen_; }; - player['isFullScreen'] = false; fullscreen = new videojs.FullscreenToggle(player); fullscreen.trigger('click'); ok(requestFullScreen, 'requestFullScreen called'); - player.isFullScreen = true; + isFullScreen_ = true; fullscreen.trigger('click'); ok(cancelFullScreen, 'cancelFullScreen called'); diff --git a/test/unit/player.js b/test/unit/player.js index c33e6f6cf2..4b8f135d57 100644 --- a/test/unit/player.js +++ b/test/unit/player.js @@ -252,7 +252,7 @@ test('should set controls and trigger events', function() { // var player = PlayerTest.makePlayer(); // player.on('fullscreenchange', function(){ // ok(true, 'fullscreenchange event fired'); -// ok(this.isFullScreen === true, 'isFullScreen is true'); +// ok(this.isFullScreen() === true, 'isFullScreen is true'); // ok(this.el().className.indexOf('vjs-fullscreen') !== -1, 'vjs-fullscreen class added'); // player.dispose();