Skip to content

Commit

Permalink
Allow user to define element other than map container for full screen…
Browse files Browse the repository at this point in the history
… control (#7548)
  • Loading branch information
ryanhamley authored Nov 13, 2018
1 parent d3c7405 commit 361769f
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 20 deletions.
52 changes: 33 additions & 19 deletions src/ui/control/fullscreen_control.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,40 @@ import window from '../../util/window';

import type Map from '../map';

type Options = {
container?: HTMLElement
};

/**
* A `FullscreenControl` control contains a button for toggling the map in and out of fullscreen mode.
*
* @implements {IControl}
* @param {Object} [options]
* @param {HTMLElement} [options.container] `container` is the [compatible DOM element](https://developer.mozilla.org/en-US/docs/Web/API/Element/requestFullScreen#Compatible_elements) which should be made full screen. By default, the map container element will be made full screen.
*
* @example
* map.addControl(new mapboxgl.FullscreenControl());
* map.addControl(new mapboxgl.FullscreenControl({container: document.querySelector('body')}));
* @see [View a fullscreen map](https://www.mapbox.com/mapbox-gl-js/example/fullscreen/)
*/

class FullscreenControl {
_map: Map;
_mapContainer: HTMLElement;
_container: HTMLElement;
_controlContainer: HTMLElement;
_fullscreen: boolean;
_fullscreenchange: string;
_fullscreenButton: HTMLElement;
_className: string;
_container: HTMLElement;

constructor() {
constructor(options: Options) {
this._fullscreen = false;
if (options && options.container) {
if (options.container instanceof window.HTMLElement) {
this._container = options.container;
} else {
warnOnce('Full screen control \'container\' must be a DOM element.');
}
}
bindAll([
'_onClickFullscreen',
'_changeIcon'
Expand All @@ -45,19 +59,19 @@ class FullscreenControl {

onAdd(map: Map) {
this._map = map;
this._mapContainer = this._map.getContainer();
this._container = DOM.create('div', `${this._className} mapboxgl-ctrl-group`);
if (!this._container) this._container = this._map.getContainer();
this._controlContainer = DOM.create('div', `${this._className} mapboxgl-ctrl-group`);
if (this._checkFullscreenSupport()) {
this._setupUI();
} else {
this._container.style.display = 'none';
this._controlContainer.style.display = 'none';
warnOnce('This device does not support fullscreen mode.');
}
return this._container;
return this._controlContainer;
}

onRemove() {
DOM.remove(this._container);
DOM.remove(this._controlContainer);
this._map = (null: any);
window.document.removeEventListener(this._fullscreenchange, this._changeIcon);
}
Expand All @@ -72,7 +86,7 @@ class FullscreenControl {
}

_setupUI() {
const button = this._fullscreenButton = DOM.create('button', (`${this._className}-icon ${this._className}-fullscreen`), this._container);
const button = this._fullscreenButton = DOM.create('button', (`${this._className}-icon ${this._className}-fullscreen`), this._controlContainer);
button.setAttribute("aria-label", "Toggle fullscreen");
button.type = 'button';
this._fullscreenButton.addEventListener('click', this._onClickFullscreen);
Expand All @@ -90,7 +104,7 @@ class FullscreenControl {
(window.document: any).webkitFullscreenElement ||
(window.document: any).msFullscreenElement;

if ((fullscreenElement === this._mapContainer) !== this._fullscreen) {
if ((fullscreenElement === this._container) !== this._fullscreen) {
this._fullscreen = !this._fullscreen;
this._fullscreenButton.classList.toggle(`${this._className}-shrink`);
this._fullscreenButton.classList.toggle(`${this._className}-fullscreen`);
Expand All @@ -108,14 +122,14 @@ class FullscreenControl {
} else if (window.document.webkitCancelFullScreen) {
(window.document: any).webkitCancelFullScreen();
}
} else if (this._mapContainer.requestFullscreen) {
this._mapContainer.requestFullscreen();
} else if ((this._mapContainer: any).mozRequestFullScreen) {
(this._mapContainer: any).mozRequestFullScreen();
} else if ((this._mapContainer: any).msRequestFullscreen) {
(this._mapContainer: any).msRequestFullscreen();
} else if ((this._mapContainer: any).webkitRequestFullscreen) {
(this._mapContainer: any).webkitRequestFullscreen();
} else if (this._container.requestFullscreen) {
this._container.requestFullscreen();
} else if ((this._container: any).mozRequestFullScreen) {
(this._container: any).mozRequestFullScreen();
} else if ((this._container: any).msRequestFullscreen) {
(this._container: any).msRequestFullscreen();
} else if ((this._container: any).webkitRequestFullscreen) {
(this._container: any).webkitRequestFullscreen();
}
}
}
Expand Down
17 changes: 16 additions & 1 deletion test/unit/ui/control/fullscreen.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ test('FullscreenControl appears when fullscreen is enabled', (t) => {
t.end();
});

test('FullscreenControl does not appears when fullscreen is not enabled', (t) => {
test('FullscreenControl does not appear when fullscreen is not enabled', (t) => {
window.document.fullscreenEnabled = false;

const consoleWarn = t.stub(console, 'warn');
Expand All @@ -27,3 +27,18 @@ test('FullscreenControl does not appears when fullscreen is not enabled', (t) =>
t.equal(consoleWarn.getCall(0).args[0], 'This device does not support fullscreen mode.');
t.end();
});

test('FullscreenControl makes optional container element full screen', (t) => {
window.document.fullscreenEnabled = true;

const map = createMap(t);
const fullscreen = new FullscreenControl({container: window.document.querySelector('body')});
map.addControl(fullscreen);
const control = map._controls.find((ctrl) => {
return ctrl.hasOwnProperty('_fullscreen');
});
control._onClickFullscreen();

t.equal(control._container.tagName, 'BODY');
t.end();
});

0 comments on commit 361769f

Please sign in to comment.