Show:

File: app/mixins/full-screen.js

import Ember from 'ember';

let {
    $
} = Ember;

/**
 * @module exp-player
 * @submodule mixins
 */

/**
 *
 * Reference for DEVELOPERS of new frames only!
 *
 * Allow components to specify fullscreen capabilities based on minimal configuration options
 * @class Full-screen
 */
export default Ember.Mixin.create({
    /**
     *  The element ID of the thing to make full screen (video element, div, etc)
     * @property {String} fullScreenElementId
     * @private
     */
    fullScreenElementId: 'experiment-player',

    /**
     * Whether to display this frame fullscreen
     * @property {Boolean} displayFullscreen
     * @default false
     * @private
     */
    displayFullscreen: false,

    /**
     * The element ID of a button to show if the user leaves fullscreen mode
     * @property {String} fsButtonID
     * @private
     */
    fsButtonID: false,

    // These are ridiculous workarounds for rare but reproducible problems with
    // updating the isFullscreen field...

    counter: 0,

    updatedIsFullscreen: Ember.computed('counter', function () {
        return this.checkFullscreen();
    }),

    isFullscreen: false, // Keep track of state

    checkFullscreen: function () {  // Abstract away vendor-prefixed APIs

        var opts = ['fullscreenElement', 'webkitFullscreenElement', 'mozFullScreenElement', 'msFullscreenElement'];
        for (var opt of opts) {
            if (!!document[opt]) {  // eslint-disable-line no-extra-boolean-cast
                return true;
            }
        }
        return false;
    },

    onFullscreen: function ($element) {
        if (this.get('isDestroyed')) {
            // Short-circuit if object is destroyed (eg we leave fullscreen because a video frame ended)
            return false;
        }
        this.set('counter', this.get('counter') + 1);

        var isFS = this.checkFullscreen();
        this.set('isFullscreen', isFS);

        var $button = $(`#${this.get('fsButtonID')}`);
        if (isFS) { // just entered FS mode
            if (this.get('displayFullscreenOverride') && !this.get('displayFullscreen')) {
                $element.addClass('player-fullscreen-override');
            } else {
                $element.addClass('player-fullscreen');
            }
            if (this.get('displayFullscreen') && this.get('fsButtonID')) {
                $button.hide();
            }
            /**
             * Upon detecting change to fullscreen mode
             *
             * @event enteredFullscreen
            */
            this.send('setTimeEvent', 'enteredFullscreen');
        } else { // just exited FS mode
            $element.removeClass('player-fullscreen');
            $element.removeClass('player-fullscreen-override');
            if (this.get('displayFullscreen') && this.get('fsButtonID')) {
                $button.show();
            }
            /**
             * Upon detecting change out of fullscreen mode
             *
             * @event leftFullscreen
            */
            this.send('setTimeEvent', 'leftFullscreen');
        }
    },

    displayError(error) {  // eslint-disable-line no-unused-vars
        // Exit fullscreen first to make sure error is visible to users.
        this.send('exitFullscreen');
        return this._super(...arguments);
    },

    actions: {
        /**
         * Make a specified element fullscreen
         * @method showFullscreen
         */
        showFullscreen: function () {

            if (!this.checkFullscreen()) {
                var elementId = this.get('fullScreenElementId');
                if (!elementId) {
                    throw Error('Must specify element Id to make fullscreen');
                }

                var selector = Ember.$(`#${elementId}`);
                var elem = selector[0];
                if (elem.requestFullscreen) {
                    elem.requestFullscreen();
                } else if (elem.msRequestFullscreen) {
                    elem.msRequestFullscreen();
                } else if (elem.mozRequestFullScreen) {
                    elem.mozRequestFullScreen();
                } else if (elem.webkitRequestFullscreen) {
                    elem.webkitRequestFullscreen();
                } else {
                    console.warn('Your browser does not appear to support fullscreen rendering.');
                }
            }
        },
        /**
         * Exit fullscreen mode
         * @method exitFullscreen
         */
        exitFullscreen: function () {
            if (this.checkFullscreen()) {
                if (document.exitFullscreen) {
                    document.exitFullscreen();
                } else if (document.msExitFullscreen) {
                    document.msExitFullscreen();
                } else if (document.mozCancelFullScreen) {
                    document.mozCancelFullScreen();
                } else if (document.webkitExitFullscreen) {
                    document.webkitExitFullscreen();
                }
            }
            this.set('isFullscreen', false);
            // Note: we may be leaving fullscreen from a different frame, and no longer
            // know which element .player-fullscreen was attached to. Remove it from all
            // elements, otherwise we don't leave cleanly if a custom ID was specified!
            Ember.$('*').removeClass('player-fullscreen');
            Ember.$('*').removeClass('player-fullscreen-override');
        }
    },

    frameSchemaProperties: {
        /**
         * Set to `true` to display this frame in fullscreen mode, even if the frame type
         * is not always displayed fullscreen. (For instance, you might use this to keep
         * a survey between test trials in fullscreen mode.)
         *
         * @property {String} displayFullscreenOverride
         * @default false
         */
        displayFullscreenOverride: {
            type: 'boolean',
            description: 'Whether to override default and display this frame as fullscreen',
            default: false
        }
    },

    didInsertElement() {
        var buttonId = this.get('fsButtonID');
        var elementId = this.get('fullScreenElementId');
        var buttonSel = $(`#${buttonId}`);
        var selector = Ember.$(`#${elementId}`);
        Ember.$(document).off('webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange');
        Ember.$(document).on('webkitfullscreenchange mozfullscreenchange fullscreenchange MSFullscreenChange', this.onFullscreen.bind(this, selector, buttonSel));
        this._super(...arguments);
    },



});