mirror of
https://github.com/FrankerFaceZ/FrankerFaceZ.git
synced 2025-06-28 15:27:43 +00:00
4.4.0
The Profile Update! Now, it's possible to create custom settings profiles. The important thing about profiles is that you can have different profiles run according to different rules. Want some settings to only apply on your dashboard? Use a Current Page rule set to Dashboard. Want your chat wider in theater mode? Create a profile for Theater Mode. * Added: Profile Editor. * Added: Ability to import and export specific profiles. * Added: Ability to update profiles from JSON files for more advanced users. * Fixed: Update `sortablejs` dependency to fix issue with sorting behavior. * Fixed: Several issues in the settings profile system which never came up because custom profiles weren't available. * Fixed: Hotkeys freezing chat when they shouldn't, up until the first time the mouse hovers over chat. * API Added: `deep_equals(object, other, ignore_undefined = false)` method of `FrankerFaceZ.utilities.object` for comparing two objects, deeply. * API Changed: `<setting-check-box />` controls can now display their indeterminate state. * API Fixed: `deep_copy()` eating Promises and Functions.
This commit is contained in:
parent
734a73eb0e
commit
c34b7e30e2
31 changed files with 1421 additions and 129 deletions
|
@ -172,6 +172,47 @@ export function array_equals(a, b) {
|
|||
}
|
||||
|
||||
|
||||
export function deep_equals(object, other, ignore_undefined = false, seen, other_seen) {
|
||||
if ( object === other )
|
||||
return true;
|
||||
if ( typeof object !== typeof other )
|
||||
return false;
|
||||
if ( typeof object !== 'object' )
|
||||
return false;
|
||||
|
||||
if ( ! seen )
|
||||
seen = new Set;
|
||||
|
||||
if ( ! other_seen )
|
||||
other_seen = new Set;
|
||||
|
||||
if ( seen.has(object) || other_seen.has(other) )
|
||||
throw new Error('recursive structure detected');
|
||||
|
||||
seen.add(object);
|
||||
other_seen.add(other);
|
||||
|
||||
const source_keys = Object.keys(object),
|
||||
dest_keys = Object.keys(other);
|
||||
|
||||
if ( ! ignore_undefined && ! array_equals(source_keys, dest_keys) )
|
||||
return false;
|
||||
|
||||
for(const key of source_keys)
|
||||
if ( ! deep_equals(object[key], other[key], ignore_undefined, new Set(seen), new Set(other_seen)) )
|
||||
return false;
|
||||
|
||||
if ( ignore_undefined )
|
||||
for(const key of dest_keys)
|
||||
if ( ! source_keys.includes(key) ) {
|
||||
if ( ! deep_equals(object[key], other[key], ignore_undefined, new Set(seen), new Set(other_seen)) )
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
export function shallow_object_equals(a, b) {
|
||||
if ( typeof a !== 'object' || typeof b !== 'object' || ! array_equals(Object.keys(a), Object.keys(b)) )
|
||||
return false;
|
||||
|
@ -312,6 +353,12 @@ export function deep_copy(object, seen) {
|
|||
else if ( object === undefined )
|
||||
return undefined;
|
||||
|
||||
if ( object instanceof Promise )
|
||||
return new Promise((s,f) => object.then(s).catch(f));
|
||||
|
||||
if ( typeof object === 'function' )
|
||||
return function(...args) { return object.apply(this, args); } // eslint-disable-line no-invalid-this
|
||||
|
||||
if ( typeof object !== 'object' )
|
||||
return object;
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue