From d7dd6e901827e7fbb80b931253166b999daed892 Mon Sep 17 00:00:00 2001 From: Dan Ziv Date: Mon, 30 Oct 2017 23:36:06 +0200 Subject: [PATCH 1/8] Handle fullscreen --- src/event/events.js | 16 +++++++++ src/player.js | 64 +++++++++++++++++++++++++++++++++++ test/src/event/events.spec.js | 4 +++ 3 files changed, 84 insertions(+) diff --git a/src/event/events.js b/src/event/events.js index ba6f774d0..c17b96942 100644 --- a/src/event/events.js +++ b/src/event/events.js @@ -93,6 +93,22 @@ const HTML5_EVENTS: { [event: string]: string } = { }; const CUSTOM_EVENTS: { [event: string]: string } = { + /** + * Fires when the player enters fullscreen + */ + ENTER_FULLSCREEN: 'enterfullscreen', + /** + * Fires when the player exists fullscreen + */ + EXIT_FULLSCREEN: 'exitfullscreen', + /** + * Fires when the player received a request to enter fullscreen + */ + REQUESTED_ENTER_FULLSCREEN: 'requestedenterfullscreen', + /** + * Fires when the player received a request to exit fullscreen + */ + REQUESTED_EXIT_FULLSCREEN: 'requestedexitfullscreen', /** * Fires when browser fails to autoplay with sound */ diff --git a/src/player.js b/src/player.js index 103f752a5..a385b8078 100644 --- a/src/player.js +++ b/src/player.js @@ -281,6 +281,11 @@ export default class Player extends FakeEventTarget { audioLanguage: "", textLanguage: "" }; + /** + * Fullscreen indicator flag + * @private + */ + _fullscreen: boolean; /** * @param {Object} config - The configuration for the player instance. @@ -291,6 +296,7 @@ export default class Player extends FakeEventTarget { this._env = Env; this._tracks = []; this._firstPlay = true; + this._fullscreen = false; this._firstPlayInCurrentSession = true; this._config = Player._defaultConfig; this._eventManager = new EventManager(); @@ -898,6 +904,64 @@ export default class Player extends FakeEventTarget { // + // + + /** + * @returns {boolean} - Whether the player is in fullscreen mode. + * @public + */ + isFullscreen(): boolean { + return this._fullscreen; + } + + /** + * Notify the player that the ui application entered to fullscreen. + * @public + * @returns {void} + */ + notifyEnterFullscreen(): void { + if (!this._fullscreen) { + this.dispatchEvent(new FakeEvent(CustomEvents.ENTER_FULLSCREEN)); + this._fullscreen = true; + } + } + + /** + * Notify the player that the ui application exited from fullscreen. + * @public + * @returns {void} + */ + notifyExitFullscreen(): void { + if (this._fullscreen) { + this.dispatchEvent(new FakeEvent(CustomEvents.EXIT_FULLSCREEN)); + this._fullscreen = false; + } + } + + /** + * Request the player to enter fullscreen. + * @public + * @returns {void} + */ + enterFullscreen(): void { + if (!this._fullscreen) { + this.dispatchEvent(new FakeEvent(CustomEvents.REQUESTED_ENTER_FULLSCREEN)); + } + } + + /** + * Request the player to exit fullscreen. + * @public + * @returns {void} + */ + exitFullscreen(): void { + if (this._fullscreen) { + this.dispatchEvent(new FakeEvent(CustomEvents.REQUESTED_EXIT_FULLSCREEN)); + } + } + + // + // // diff --git a/test/src/event/events.spec.js b/test/src/event/events.spec.js index 0cb17482f..b316bceda 100644 --- a/test/src/event/events.spec.js +++ b/test/src/event/events.spec.js @@ -28,6 +28,10 @@ describe('events', () => { WAITING: 'waiting', }); events.CUSTOM_EVENTS.should.deep.equals({ + ENTER_FULLSCREEN: 'enterfullscreen', + EXIT_FULLSCREEN: 'exitfullscreen', + REQUESTED_ENTER_FULLSCREEN: 'requestedenterfullscreen', + REQUESTED_EXIT_FULLSCREEN: 'requestedexitfullscreen', AUTOPLAY_FAILED: 'autoplayfailed', FALLBACK_TO_MUTED_AUTOPLAY: 'fallbacktomutedautoplay', CHANGE_SOURCE_STARTED: 'changesourcestarted', From aa5406eb015e241636ea95c1c0feea5f4e8bfb11 Mon Sep 17 00:00:00 2001 From: Dan Ziv Date: Tue, 31 Oct 2017 12:52:38 +0200 Subject: [PATCH 2/8] Update events.js --- src/event/events.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/event/events.js b/src/event/events.js index c17b96942..1284e4f2b 100644 --- a/src/event/events.js +++ b/src/event/events.js @@ -98,7 +98,7 @@ const CUSTOM_EVENTS: { [event: string]: string } = { */ ENTER_FULLSCREEN: 'enterfullscreen', /** - * Fires when the player exists fullscreen + * Fires when the player exits fullscreen */ EXIT_FULLSCREEN: 'exitfullscreen', /** From 3b96b83b45bd7a0c00f4ae4f7f0cd9770943caf7 Mon Sep 17 00:00:00 2001 From: odedhutzler Date: Tue, 31 Oct 2017 19:53:55 +0200 Subject: [PATCH 3/8] adding full screen events handlers and repositioning the captions + tests --- src/event/events.js | 12 +++++++++-- src/player.js | 38 +++++++++++++++++++++++++++++++---- test/src/event/events.spec.js | 6 ++++-- test/src/player.spec.js | 24 ++++++++++++++++++++++ 4 files changed, 72 insertions(+), 8 deletions(-) diff --git a/src/event/events.js b/src/event/events.js index 1284e4f2b..89fec8c66 100644 --- a/src/event/events.js +++ b/src/event/events.js @@ -96,11 +96,19 @@ const CUSTOM_EVENTS: { [event: string]: string } = { /** * Fires when the player enters fullscreen */ - ENTER_FULLSCREEN: 'enterfullscreen', + ENTER_FULLSCREEN_STARTED: 'enterfullscreenstarted', + /** + * Fires when the full screen is fully loaded (it's a hack, we just fire this after 500 miliseconds) + */ + ENTER_FULLSCREEN_ENDED: 'enterfullscreenended', /** * Fires when the player exits fullscreen */ - EXIT_FULLSCREEN: 'exitfullscreen', + EXIT_FULLSCREEN_STARTED: 'exitfullscreenstarted', + /** + * Fires when the full screen is fully unloaded (it's a hack, we just fire this after 500 miliseconds) + */ + EXIT_FULLSCREEN_ENDED: 'exitfullscreenended', /** * Fires when the player received a request to enter fullscreen */ diff --git a/src/player.js b/src/player.js index a385b8078..ba4d14543 100644 --- a/src/player.js +++ b/src/player.js @@ -921,8 +921,11 @@ export default class Player extends FakeEventTarget { */ notifyEnterFullscreen(): void { if (!this._fullscreen) { - this.dispatchEvent(new FakeEvent(CustomEvents.ENTER_FULLSCREEN)); - this._fullscreen = true; + this.dispatchEvent(new FakeEvent(CustomEvents.ENTER_FULLSCREEN_STARTED)); + window.setTimeout(() => { + this.dispatchEvent(new FakeEvent(CustomEvents.ENTER_FULLSCREEN_ENDED)); + this._fullscreen = true; + }, 500); } } @@ -933,8 +936,11 @@ export default class Player extends FakeEventTarget { */ notifyExitFullscreen(): void { if (this._fullscreen) { - this.dispatchEvent(new FakeEvent(CustomEvents.EXIT_FULLSCREEN)); - this._fullscreen = false; + this.dispatchEvent(new FakeEvent(CustomEvents.EXIT_FULLSCREEN_STARTED)); + window.setTimeout(() => { + this.dispatchEvent(new FakeEvent(CustomEvents.EXIT_FULLSCREEN_ENDED)); + this._fullscreen = false; + }, 500); } } @@ -1157,7 +1163,31 @@ export default class Player extends FakeEventTarget { this._eventManager.listen(this, Html5Events.RATE_CHANGE, () => { this._playbackAttributesState.rate = this.playbackRate; }); + this._eventManager.listen(this, CustomEvents.ENTER_FULLSCREEN_STARTED, () => { + this._updateTextDisplay([]); + }); + this._eventManager.listen(this, CustomEvents.ENTER_FULLSCREEN_ENDED, () => { + this._resetTextCuesAndReposition(); + }); + this._eventManager.listen(this, CustomEvents.EXIT_FULLSCREEN_STARTED, () => { + this._updateTextDisplay([]); + }); + this._eventManager.listen(this, CustomEvents.EXIT_FULLSCREEN_ENDED, () => { + this._resetTextCuesAndReposition(); + }); + } + } + + /** + * Reset the active cues hasBeenReset = true and then reposition it + * @returns {void} + * @private + */ + _resetTextCuesAndReposition(): void { + for (let i = 0; i < this._activeTextCues.length; i++) { + this._activeTextCues[i].hasBeenReset = true; } + processCues(window, this._activeTextCues, this._textDisplayEl) } /** diff --git a/test/src/event/events.spec.js b/test/src/event/events.spec.js index b316bceda..98a4ac048 100644 --- a/test/src/event/events.spec.js +++ b/test/src/event/events.spec.js @@ -28,8 +28,10 @@ describe('events', () => { WAITING: 'waiting', }); events.CUSTOM_EVENTS.should.deep.equals({ - ENTER_FULLSCREEN: 'enterfullscreen', - EXIT_FULLSCREEN: 'exitfullscreen', + ENTER_FULLSCREEN_STARTED: 'enterfullscreenstarted', + ENTER_FULLSCREEN_ENDED: 'enterfullscreenended', + EXIT_FULLSCREEN_STARTED: 'exitfullscreenstarted', + EXIT_FULLSCREEN_ENDED: 'exitfullscreenended', REQUESTED_ENTER_FULLSCREEN: 'requestedenterfullscreen', REQUESTED_EXIT_FULLSCREEN: 'requestedexitfullscreen', AUTOPLAY_FAILED: 'autoplayfailed', diff --git a/test/src/player.spec.js b/test/src/player.spec.js index a6c97c860..8f4fc7538 100644 --- a/test/src/player.spec.js +++ b/test/src/player.spec.js @@ -2517,3 +2517,27 @@ describe('_getLanguage', function () { player._getLanguage(configuredLanguage, offTrack, "text").should.equals(gerTrack.language); }); }); + + +describe('_resetTextCuesAndReposition', function () { + let config, player, sandbox; + + beforeEach(() => { + sandbox = sinon.sandbox.create(); + config = getConfigStructure(); + player = new Player(config); + }); + + afterEach(() => { + sandbox.restore(); + player.destroy(); + }); + + it('should reset the active text cues', () => { + player._activeTextCues[0]={}; + player._resetText CuesAndReposition(); + let cue = player._activeTextCues[0]; + cue.hasBeenReset.should.equals(true); + }); +}); + From 772a12ccfaa1f7dc96d33125a6cd73fba48e38b5 Mon Sep 17 00:00:00 2001 From: odedhutzler Date: Tue, 31 Oct 2017 20:10:20 +0200 Subject: [PATCH 4/8] fix --- test/src/player.spec.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/src/player.spec.js b/test/src/player.spec.js index 34b0c060c..05bba1648 100644 --- a/test/src/player.spec.js +++ b/test/src/player.spec.js @@ -2666,7 +2666,7 @@ describe('_resetTextCuesAndReposition', function () { it('should reset the active text cues', () => { player._activeTextCues[0]={}; - player._resetText CuesAndReposition(); + player._resetTextCuesAndReposition(); let cue = player._activeTextCues[0]; cue.hasBeenReset.should.equals(true); }); From 133d6c7e0b26b99204145b650a82fad0bbe698d3 Mon Sep 17 00:00:00 2001 From: odedhutzler Date: Wed, 1 Nov 2017 11:01:54 +0200 Subject: [PATCH 5/8] reverting the full screen hack, using timeout only for the captions --- src/event/events.js | 12 ++---------- src/player.js | 34 ++++++++++++++-------------------- test/src/event/events.spec.js | 6 ++---- 3 files changed, 18 insertions(+), 34 deletions(-) diff --git a/src/event/events.js b/src/event/events.js index 89fec8c66..1284e4f2b 100644 --- a/src/event/events.js +++ b/src/event/events.js @@ -96,19 +96,11 @@ const CUSTOM_EVENTS: { [event: string]: string } = { /** * Fires when the player enters fullscreen */ - ENTER_FULLSCREEN_STARTED: 'enterfullscreenstarted', - /** - * Fires when the full screen is fully loaded (it's a hack, we just fire this after 500 miliseconds) - */ - ENTER_FULLSCREEN_ENDED: 'enterfullscreenended', + ENTER_FULLSCREEN: 'enterfullscreen', /** * Fires when the player exits fullscreen */ - EXIT_FULLSCREEN_STARTED: 'exitfullscreenstarted', - /** - * Fires when the full screen is fully unloaded (it's a hack, we just fire this after 500 miliseconds) - */ - EXIT_FULLSCREEN_ENDED: 'exitfullscreenended', + EXIT_FULLSCREEN: 'exitfullscreen', /** * Fires when the player received a request to enter fullscreen */ diff --git a/src/player.js b/src/player.js index ba4d14543..d47b8e5eb 100644 --- a/src/player.js +++ b/src/player.js @@ -921,11 +921,8 @@ export default class Player extends FakeEventTarget { */ notifyEnterFullscreen(): void { if (!this._fullscreen) { - this.dispatchEvent(new FakeEvent(CustomEvents.ENTER_FULLSCREEN_STARTED)); - window.setTimeout(() => { - this.dispatchEvent(new FakeEvent(CustomEvents.ENTER_FULLSCREEN_ENDED)); - this._fullscreen = true; - }, 500); + this._fullscreen = true; + this.dispatchEvent(new FakeEvent(CustomEvents.ENTER_FULLSCREEN)); } } @@ -936,11 +933,8 @@ export default class Player extends FakeEventTarget { */ notifyExitFullscreen(): void { if (this._fullscreen) { - this.dispatchEvent(new FakeEvent(CustomEvents.EXIT_FULLSCREEN_STARTED)); - window.setTimeout(() => { - this.dispatchEvent(new FakeEvent(CustomEvents.EXIT_FULLSCREEN_ENDED)); - this._fullscreen = false; - }, 500); + this._fullscreen = false; + this.dispatchEvent(new FakeEvent(CustomEvents.EXIT_FULLSCREEN)); } } @@ -1163,31 +1157,31 @@ export default class Player extends FakeEventTarget { this._eventManager.listen(this, Html5Events.RATE_CHANGE, () => { this._playbackAttributesState.rate = this.playbackRate; }); - this._eventManager.listen(this, CustomEvents.ENTER_FULLSCREEN_STARTED, () => { - this._updateTextDisplay([]); - }); - this._eventManager.listen(this, CustomEvents.ENTER_FULLSCREEN_ENDED, () => { + this._eventManager.listen(this, CustomEvents.ENTER_FULLSCREEN, () => { this._resetTextCuesAndReposition(); }); - this._eventManager.listen(this, CustomEvents.EXIT_FULLSCREEN_STARTED, () => { - this._updateTextDisplay([]); - }); - this._eventManager.listen(this, CustomEvents.EXIT_FULLSCREEN_ENDED, () => { + this._eventManager.listen(this, CustomEvents.EXIT_FULLSCREEN, () => { this._resetTextCuesAndReposition(); }); } } /** - * Reset the active cues hasBeenReset = true and then reposition it + * Reset the active cues hasBeenReset = true and then reposition it, timeout here is for the screen to + * finish render the fullscreen * @returns {void} * @private */ _resetTextCuesAndReposition(): void { + this._updateTextDisplay([]); for (let i = 0; i < this._activeTextCues.length; i++) { this._activeTextCues[i].hasBeenReset = true; } - processCues(window, this._activeTextCues, this._textDisplayEl) + + // waiting the browser to render the screen + setTimeout(() => { + processCues(window, this._activeTextCues, this._textDisplayEl); + }, 1000); } /** diff --git a/test/src/event/events.spec.js b/test/src/event/events.spec.js index 98a4ac048..b316bceda 100644 --- a/test/src/event/events.spec.js +++ b/test/src/event/events.spec.js @@ -28,10 +28,8 @@ describe('events', () => { WAITING: 'waiting', }); events.CUSTOM_EVENTS.should.deep.equals({ - ENTER_FULLSCREEN_STARTED: 'enterfullscreenstarted', - ENTER_FULLSCREEN_ENDED: 'enterfullscreenended', - EXIT_FULLSCREEN_STARTED: 'exitfullscreenstarted', - EXIT_FULLSCREEN_ENDED: 'exitfullscreenended', + ENTER_FULLSCREEN: 'enterfullscreen', + EXIT_FULLSCREEN: 'exitfullscreen', REQUESTED_ENTER_FULLSCREEN: 'requestedenterfullscreen', REQUESTED_EXIT_FULLSCREEN: 'requestedexitfullscreen', AUTOPLAY_FAILED: 'autoplayfailed', From b7a2b6aae51d9fce122742c216477502db6156de Mon Sep 17 00:00:00 2001 From: odedhutzler Date: Wed, 1 Nov 2017 13:02:14 +0200 Subject: [PATCH 6/8] handling only the last reposition --- src/player.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/player.js b/src/player.js index d47b8e5eb..e18a1ab32 100644 --- a/src/player.js +++ b/src/player.js @@ -309,6 +309,7 @@ export default class Player extends FakeEventTarget { this._createPlayerContainer(); this._appendPosterEl(); this.configure(config); + this._repositionCuesTimeout = false; } // @@ -1177,10 +1178,13 @@ export default class Player extends FakeEventTarget { for (let i = 0; i < this._activeTextCues.length; i++) { this._activeTextCues[i].hasBeenReset = true; } - - // waiting the browser to render the screen - setTimeout(() => { + // handling only the last reposition + if (this._repositionCuesTimeout) { + clearTimeout(this._repositionCuesTimeout); + } + this._repositionCuesTimeout = setTimeout(() => { processCues(window, this._activeTextCues, this._textDisplayEl); + this._repositionCuesTimeout = false; }, 1000); } From 1c287b4384c7e321211f344f16737d3d6be03e16 Mon Sep 17 00:00:00 2001 From: odedhutzler Date: Wed, 1 Nov 2017 16:22:46 +0200 Subject: [PATCH 7/8] consts + flow --- src/player.js | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/player.js b/src/player.js index e18a1ab32..34088edcc 100644 --- a/src/player.js +++ b/src/player.js @@ -32,6 +32,13 @@ import './assets/style.css' */ const CONTAINER_CLASS_NAME: string = 'playkit-container'; +/** + * The toggle fullscreen rendering timeout value + * @type {number} + * @const + */ +const FULLSCREEN_RENDERING_TIMEOUT: number = 1000; + /** /** * The player poster class name. @@ -286,7 +293,12 @@ export default class Player extends FakeEventTarget { * @private */ _fullscreen: boolean; - + /** + * holds false or an id for the timeout the reposition the text cues after togelling full screen + * @type {any} + * @private + */ + _repositionCuesTimeout: any; /** * @param {Object} config - The configuration for the player instance. * @constructor @@ -1185,7 +1197,7 @@ export default class Player extends FakeEventTarget { this._repositionCuesTimeout = setTimeout(() => { processCues(window, this._activeTextCues, this._textDisplayEl); this._repositionCuesTimeout = false; - }, 1000); + }, FULLSCREEN_RENDERING_TIMEOUT); } /** From 073f3ef1c642265545acc08ceae26e1800fe5ccf Mon Sep 17 00:00:00 2001 From: Oren Me Date: Wed, 1 Nov 2017 16:29:24 +0200 Subject: [PATCH 8/8] change const name --- src/player.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/player.js b/src/player.js index 34088edcc..4b5a2981e 100644 --- a/src/player.js +++ b/src/player.js @@ -32,13 +32,6 @@ import './assets/style.css' */ const CONTAINER_CLASS_NAME: string = 'playkit-container'; -/** - * The toggle fullscreen rendering timeout value - * @type {number} - * @const - */ -const FULLSCREEN_RENDERING_TIMEOUT: number = 1000; - /** /** * The player poster class name. @@ -96,6 +89,13 @@ const OFF: string = 'off'; */ const DURATION_OFFSET: number = 0.1; +/** + * The toggle fullscreen rendering timeout value + * @type {number} + * @const + */ +const REPOSITION_CUES_TIMEOUT: number = 1000; + /** * The HTML5 player class. * @classdesc @@ -1197,7 +1197,7 @@ export default class Player extends FakeEventTarget { this._repositionCuesTimeout = setTimeout(() => { processCues(window, this._activeTextCues, this._textDisplayEl); this._repositionCuesTimeout = false; - }, FULLSCREEN_RENDERING_TIMEOUT); + }, REPOSITION_CUES_TIMEOUT); } /**