mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-10-11 13:41:57 +00:00
4.20.16
* Changed: Metadata now uses the global FFZ tool-tip handler when rendering tool-tips. * Fixed: Metadata pop-ups not appearing when an element is open fullscreen. * API Added: Callback for changing popper options before opening a tool-tip. * API Added: Timing for module loading. WIP.
This commit is contained in:
parent
1c2bf202fc
commit
3d88836a0e
9 changed files with 172 additions and 17 deletions
|
@ -47,6 +47,7 @@ export class Module extends EventEmitter {
|
|||
this.__state = this.onLoad || this.onEnable ?
|
||||
State.DISABLED : State.ENABLED;
|
||||
|
||||
this.__time('instance');
|
||||
this.emit(':registered');
|
||||
}
|
||||
|
||||
|
@ -76,6 +77,20 @@ export class Module extends EventEmitter {
|
|||
}
|
||||
|
||||
|
||||
// ========================================================================
|
||||
// Timing
|
||||
// ========================================================================
|
||||
|
||||
__time(event) {
|
||||
if ( this.root.timing ) {
|
||||
if ( typeof event !== 'object' )
|
||||
event = {event};
|
||||
event.module = this.__path || 'core';
|
||||
this.root.timing.addEvent(event);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ========================================================================
|
||||
// State! Glorious State
|
||||
// ========================================================================
|
||||
|
@ -115,6 +130,7 @@ export class Module extends EventEmitter {
|
|||
|
||||
chain.push(this);
|
||||
|
||||
this.__time('load-start');
|
||||
this.__load_state = State.LOADING;
|
||||
return this.__load_promise = (async () => {
|
||||
if ( this.load_requires ) {
|
||||
|
@ -130,17 +146,21 @@ export class Module extends EventEmitter {
|
|||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
if ( this.onLoad )
|
||||
if ( this.onLoad ) {
|
||||
this.__time('load-self');
|
||||
return this.onLoad(...args);
|
||||
}
|
||||
|
||||
})().then(ret => {
|
||||
this.__load_state = State.LOADED;
|
||||
this.__load_promise = null;
|
||||
this.__time('load-end');
|
||||
this.emit(':loaded', this);
|
||||
return ret;
|
||||
}).catch(err => {
|
||||
this.__load_state = State.UNLOADED;
|
||||
this.__load_promise = null;
|
||||
this.__time('load-end');
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
@ -166,7 +186,7 @@ export class Module extends EventEmitter {
|
|||
return Promise.reject(new CyclicDependencyError(`cyclic load requirements when unloading ${initial}`, chain));
|
||||
|
||||
chain.push(this);
|
||||
|
||||
this.__time('unload-start');
|
||||
this.__load_state = State.UNLOADING;
|
||||
return this.__load_promise = (async () => {
|
||||
if ( this.__state !== State.DISABLED )
|
||||
|
@ -185,16 +205,19 @@ export class Module extends EventEmitter {
|
|||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
this.__time('unload-self');
|
||||
return this.onUnload(...args);
|
||||
|
||||
})().then(ret => {
|
||||
this.__load_state = State.UNLOADED;
|
||||
this.__load_promise = null;
|
||||
this.__time('unload-end');
|
||||
this.emit(':unloaded', this);
|
||||
return ret;
|
||||
}).catch(err => {
|
||||
this.__load_state = State.LOADED;
|
||||
this.__load_promise = null;
|
||||
this.__time('unload-end');
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
@ -217,7 +240,7 @@ export class Module extends EventEmitter {
|
|||
return Promise.reject(new CyclicDependencyError(`cyclic requirements when enabling ${initial}`, chain));
|
||||
|
||||
chain.push(this);
|
||||
|
||||
this.__time('enable-start');
|
||||
this.__state = State.ENABLING;
|
||||
return this.__state_promise = (async () => {
|
||||
const promises = [],
|
||||
|
@ -242,18 +265,22 @@ export class Module extends EventEmitter {
|
|||
}
|
||||
|
||||
await Promise.all(promises);
|
||||
if ( this.onEnable )
|
||||
if ( this.onEnable ) {
|
||||
this.__time('enable-self');
|
||||
return this.onEnable(...args);
|
||||
}
|
||||
|
||||
})().then(ret => {
|
||||
this.__state = State.ENABLED;
|
||||
this.__state_promise = null;
|
||||
this.__time('enable-end');
|
||||
this.emit(':enabled', this);
|
||||
return ret;
|
||||
|
||||
}).catch(err => {
|
||||
this.__state = State.DISABLED;
|
||||
this.__state_promise = null;
|
||||
this.__time('enable-end');
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
@ -279,7 +306,7 @@ export class Module extends EventEmitter {
|
|||
return Promise.reject(new CyclicDependencyError(`cyclic requirements when disabling ${initial}`, chain));
|
||||
|
||||
chain.push(this);
|
||||
|
||||
this.__time('disable-start');
|
||||
this.__state = State.DISABLING;
|
||||
return this.__state_promise = (async () => {
|
||||
if ( this.__load_state !== State.LOADED )
|
||||
|
@ -300,17 +327,20 @@ export class Module extends EventEmitter {
|
|||
await Promise.all(promises);
|
||||
}
|
||||
|
||||
this.__time('disable-self');
|
||||
return this.onDisable(...args);
|
||||
|
||||
})().then(ret => {
|
||||
this.__state = State.DISABLED;
|
||||
this.__state_promise = null;
|
||||
this.__time('disable-end');
|
||||
this.emit(':disabled', this);
|
||||
return ret;
|
||||
|
||||
}).catch(err => {
|
||||
this.__state = State.ENABLED;
|
||||
this.__state_promise = null;
|
||||
this.__time('disable-end');
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
|
24
src/utilities/timing.js
Normal file
24
src/utilities/timing.js
Normal file
|
@ -0,0 +1,24 @@
|
|||
'use strict';
|
||||
|
||||
// ============================================================================
|
||||
// Timing Tracker
|
||||
// For figuring out FFZ loading
|
||||
// ============================================================================
|
||||
|
||||
import Module from 'utilities/module';
|
||||
|
||||
|
||||
export default class Timing extends Module {
|
||||
constructor(...args) {
|
||||
super(...args);
|
||||
|
||||
this.events = [];
|
||||
}
|
||||
|
||||
__time() { /* no-op */ } // eslint-disable-line class-methods-use-this
|
||||
|
||||
addEvent(event) {
|
||||
event.ts = performance.now();
|
||||
this.events.push(event);
|
||||
}
|
||||
}
|
|
@ -291,7 +291,7 @@ export class Tooltip {
|
|||
const use_html = maybe_call(opts.html, null, target, tip),
|
||||
setter = use_html ? 'innerHTML' : 'textContent';
|
||||
|
||||
const pop_opts = Object.assign({
|
||||
let pop_opts = Object.assign({
|
||||
modifiers: {
|
||||
flip: {
|
||||
behavior: ['top', 'bottom', 'left', 'right']
|
||||
|
@ -300,6 +300,9 @@ export class Tooltip {
|
|||
arrowElement: arrow
|
||||
}, opts.popper);
|
||||
|
||||
if ( opts.popperConfig )
|
||||
pop_opts = opts.popperConfig(target, tip, pop_opts) ?? pop_opts;
|
||||
|
||||
pop_opts.onUpdate = tip._on_update = debounce(() => {
|
||||
if ( ! opts.no_auto_remove && ! document.contains(tip.target) )
|
||||
this.hide(tip);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue