Skip to content

Commit

Permalink
feat: handle fullscreen (#154)
Browse files Browse the repository at this point in the history
  • Loading branch information
Dan Ziv authored Oct 31, 2017
1 parent 0e577a9 commit 3373c8c
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/event/events.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 exits 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
*/
Expand Down
64 changes: 64 additions & 0 deletions src/player.js
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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();
Expand Down Expand Up @@ -898,6 +904,64 @@ export default class Player extends FakeEventTarget {

// </editor-fold>

// <editor-fold desc="Fullscreen API">

/**
* @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._fullscreen = true;
this.dispatchEvent(new FakeEvent(CustomEvents.ENTER_FULLSCREEN));
}
}

/**
* Notify the player that the ui application exited from fullscreen.
* @public
* @returns {void}
*/
notifyExitFullscreen(): void {
if (this._fullscreen) {
this._fullscreen = false;
this.dispatchEvent(new FakeEvent(CustomEvents.EXIT_FULLSCREEN));
}
}

/**
* 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));
}
}

// </editor-fold>

// </editor-fold>

// <editor-fold desc="Private Methods">
Expand Down
4 changes: 4 additions & 0 deletions test/src/event/events.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down
131 changes: 131 additions & 0 deletions test/src/player.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,137 @@ describe('Text Track API', () => {
});
});

describe('Fullscreen API', () => {
let player;

beforeEach(() => {
player = new Player();
});

afterEach(() => {
player.destroy();
});

after(() => {
removeVideoElementsFromTestPage();
});

describe('isFullscreen', () => {
it("should start with initial fullscreen state of false", () => {
player.isFullscreen().should.be.false;
});

it("should be in fullscreen state after notify", () => {
player.notifyEnterFullscreen();
player.isFullscreen().should.be.true;
});

it("should not be in fullscreen state after notify", () => {
player.notifyEnterFullscreen();
player.isFullscreen().should.be.true;
player.notifyExitFullscreen();
player.isFullscreen().should.be.false;
});
});

describe('notifyEnterFullscreen', () => {
it("should fire ENTER_FULLSCREEN event", (done) => {
player.addEventListener(player.Event.ENTER_FULLSCREEN, () => {
player.isFullscreen().should.be.true;
done();
});
player.notifyEnterFullscreen();
});

it("should not fire ENTER_FULLSCREEN event twice", (done) => {
let callCount = 0;
player.addEventListener(player.Event.ENTER_FULLSCREEN, () => {
callCount++;
player.isFullscreen().should.be.true;
player.notifyEnterFullscreen();
setTimeout(() => {
if (callCount === 1) {
done();
} else {
done(new Error('fail'));
}
}, 500);
});
player.notifyEnterFullscreen();
});
});

describe('notifyExitFullscreen', () => {
it("should fire EXIT_FULLSCREEN event", (done) => {
player.addEventListener(player.Event.EXIT_FULLSCREEN, () => {
player.isFullscreen().should.be.false;
done();
});
player.addEventListener(player.Event.ENTER_FULLSCREEN, () => {
player.isFullscreen().should.be.true;
player.notifyExitFullscreen();
});
player.notifyEnterFullscreen();
});

it("should not fire EXIT_FULLSCREEN event twice", (done) => {
let callCount = 0;
player.addEventListener(player.Event.EXIT_FULLSCREEN, () => {
callCount++;
player.isFullscreen().should.be.false;
player.notifyExitFullscreen();
setTimeout(() => {
if (callCount === 1) {
done();
} else {
done(new Error('fail'));
}
}, 500);
});
player.addEventListener(player.Event.ENTER_FULLSCREEN, () => {
player.isFullscreen().should.be.true;
player.notifyExitFullscreen();
});
player.notifyEnterFullscreen();
});

it("should not fire EXIT_FULLSCREEN event when player is not in fullscreen state", (done) => {
player.addEventListener(player.Event.EXIT_FULLSCREEN, () => done(new Error('fail')));
player.notifyExitFullscreen();
setTimeout(() => done(), 500);
});
});

describe('enterFullscreen', () => {
it("should fire REQUESTED_ENTER_FULLSCREEN event", (done) => {
player.addEventListener(player.Event.REQUESTED_ENTER_FULLSCREEN, () => done());
player.enterFullscreen();
});

it("should not fire REQUESTED_ENTER_FULLSCREEN event when player is already in fullscreen", (done) => {
player.addEventListener(player.Event.REQUESTED_ENTER_FULLSCREEN, () => done(new Error('fail')));
player.notifyEnterFullscreen();
player.enterFullscreen();
setTimeout(() => done(), 500);
});
});

describe('exitFullscreen', () => {
it("should fire REQUESTED_EXIT_FULLSCREEN event", (done) => {
player.addEventListener(player.Event.REQUESTED_EXIT_FULLSCREEN, () => done());
player.notifyEnterFullscreen();
player.exitFullscreen();
});

it("should not fire REQUESTED_EXIT_FULLSCREEN event when player is not in fullscreen", (done) => {
player.addEventListener(player.Event.REQUESTED_EXIT_FULLSCREEN, () => done(new Error('fail')));
player.notifyExitFullscreen();
player.exitFullscreen();
setTimeout(() => done(), 500);
});
});
});

describe('Track enum', function () {
let playerContainer;

Expand Down

0 comments on commit 3373c8c

Please sign in to comment.