(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;
}
}
})();