nbsrc/provider/ResizeProvider.js

goog.module('nbsrc.provider.ResizeProvider');

const {getViewportSize} = goog.require('goog.dom');
const {listen} = goog.require('goog.events');
const Event = goog.require('goog.events.Event');
const EventTarget = goog.require('goog.events.EventTarget');
const EventType = goog.require('goog.events.EventType');
const userAgent = goog.require('goog.userAgent');
const Size = goog.require('goog.math.Size');

/**
 * This provider (singleton) is used for uniform monitoring of window size changes.
 * @extends {EventTarget}
 */
class ResizeProvider extends EventTarget
{
    constructor()
    {
        super();

        /**
         * Update events are only fired if the window viewport width has changed.
         * @type {boolean}
         */
        this.updateOnlyOnWidthChanges = true;

        /**
         * Size of the window viewport
         * @type {!Size}
         * @private
         */
        this.viewportSize_ = getViewportSize();

        listen(window, EventType.RESIZE, this.handleResize_, false, this);
    }

    /**
     * Checks if the window viewport size has changed from the stored size and fires the `EventType.UPDATE` event if it has changed.
     * @param {boolean=} opt_alwaysBubbleEvent Forces the update event to be sent even if no resize is detected for the window size.
     */
    update(opt_alwaysBubbleEvent = false)
    {
        const alwaysBubbleEvent = opt_alwaysBubbleEvent || false;
        let registerChange = false;

        const viewportSize = /** @type {!Size} */ (getViewportSize());

        if (this.updateOnlyOnWidthChanges && userAgent.MOBILE && (this.viewportSize_.width === viewportSize.width))
        {
            // don't trigger resize when mobile device changes innerHeight but not innerWidth for example when nav bar
            // at top is showed / hidden
        }
        else
        {
            this.viewportSize_ = viewportSize;

            registerChange = true;
        }

        if (alwaysBubbleEvent || registerChange)
        {
            this.dispatchEvent(new Event(EventType.RESIZE));
        }
    }

    /**
     * @private
     */
    handleResize_()
    {
        this.update();
    }

    /**
     * @returns {!Size}
     */
    getViewportSize()
    {
        if(this.viewportSize_.width == 0)
            this.update(true);

        return this.viewportSize_;
    }
}

goog.addSingletonGetter(ResizeProvider);

exports = ResizeProvider;