Source: observer/FocusObserver.js

(function() {
    const EVENT_TYPES = ['focus', 'blur', 'focusin', 'focusout'];

    /**
     * observes focus events within the current window
     * @augments Help4.observer.Observer
     */
    Help4.observer.FocusObserver = class extends Help4.observer.Observer {
        /**
         * @override
         * @param {Help4.observer.Callback} callback
         * @param {Window} [win = window] - the to-be-observed window
         */
        constructor(callback, win) {
            const onEvent = event => {
                // Help4.Event.stopObserving sometimes fails; therefore check this._callback
                const {_callback, _focussed} = this;

                if (_callback && (event = Help4.Event.normalize(event))) {
                    const isFocus = event.type === 'focus' || event.type === 'focusin';
                    const focussed = isFocus ? event.target : null;

                    // prevent to notify because of the same element more than once
                    if (focussed !== _focussed) {
                        this._focussed = focussed;
                        _callback(event);
                    }
                }

                return true;
            };

            super(callback, {
                statics: {
                    _focussed: {init: null, destroy: false},
                    _onEvent:  {init: onEvent, destroy: false},
                    _window:   {init: win || window, destroy: false}
                }
            });
        }

        /**
         * starts target observation; incompatible override!
         * @returns {Help4.observer.FocusObserver}
         */
        observe() {
            const {_window} = this;
            const target = _window.document;

            super.observe(target, null);

            for (const type of EVENT_TYPES) {
                Help4.Event.observe(target, {
                    manual: true,
                    type,
                    window: _window,
                    capture: true,
                    callback: this._onEvent
                });
            }

            return this;
        }

        /**
         * @override
         * @returns {Help4.observer.FocusObserver}
         */
        disconnect() {
            const {_window, _connections} = this;

            for (const {target} of _connections) {
                for (const type of EVENT_TYPES) {
                    Help4.Event.stopObserving(target, {
                        manual: true,
                        type,
                        window: _window,
                        capture: true,
                        callback: this._onEvent
                    });
                }
            }

            super.disconnect();
            return this;
        }
    }
})();