mirror of
https://github.com/ksyasuda/SubMiner.git
synced 2026-03-01 06:22:44 -08:00
initial commit
This commit is contained in:
131
vendor/yomitan/js/core/dynamic-property.js
vendored
Normal file
131
vendor/yomitan/js/core/dynamic-property.js
vendored
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
* Copyright (C) 2023-2025 Yomitan Authors
|
||||
* Copyright (C) 2019-2022 Yomichan Authors
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import {EventDispatcher} from './event-dispatcher.js';
|
||||
import {generateId} from './utilities.js';
|
||||
|
||||
/**
|
||||
* Class representing a generic value with an override stack.
|
||||
* Changes can be observed by listening to the 'change' event.
|
||||
* @template [T=unknown]
|
||||
* @augments EventDispatcher<import('dynamic-property').Events<T>>
|
||||
*/
|
||||
export class DynamicProperty extends EventDispatcher {
|
||||
/**
|
||||
* Creates a new instance with the specified value.
|
||||
* @param {T} value The value to assign.
|
||||
*/
|
||||
constructor(value) {
|
||||
super();
|
||||
/** @type {T} */
|
||||
this._value = value;
|
||||
/** @type {T} */
|
||||
this._defaultValue = value;
|
||||
/** @type {{value: T, priority: number, token: string}[]} */
|
||||
this._overrides = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default value for the property, which is assigned to the
|
||||
* public value property when no overrides are present.
|
||||
* @type {T}
|
||||
*/
|
||||
get defaultValue() {
|
||||
return this._defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Assigns the default value for the property. If no overrides are present
|
||||
* and if the value is different than the current default value,
|
||||
* the 'change' event will be triggered.
|
||||
* @param {T} value The value to assign.
|
||||
*/
|
||||
set defaultValue(value) {
|
||||
this._defaultValue = value;
|
||||
if (this._overrides.length === 0) { this._updateValue(); }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current value for the property, taking any overrides into account.
|
||||
* @type {T}
|
||||
*/
|
||||
get value() {
|
||||
return this._value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the number of overrides added to the property.
|
||||
* @type {number}
|
||||
*/
|
||||
get overrideCount() {
|
||||
return this._overrides.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an override value with the specified priority to the override stack.
|
||||
* Values with higher priority will take precedence over those with lower.
|
||||
* For tie breaks, the override value added first will take precedence.
|
||||
* If the newly added override has the highest priority of all overrides
|
||||
* and if the override value is different from the current value,
|
||||
* the 'change' event will be fired.
|
||||
* @param {T} value The override value to assign.
|
||||
* @param {number} [priority] The priority value to use, as a number.
|
||||
* @returns {import('core').TokenString} A string token which can be passed to the clearOverride function
|
||||
* to remove the override.
|
||||
*/
|
||||
setOverride(value, priority = 0) {
|
||||
const overridesCount = this._overrides.length;
|
||||
let i = 0;
|
||||
for (; i < overridesCount; ++i) {
|
||||
if (priority > this._overrides[i].priority) { break; }
|
||||
}
|
||||
const token = generateId(16);
|
||||
this._overrides.splice(i, 0, {value, priority, token});
|
||||
if (i === 0) { this._updateValue(); }
|
||||
return token;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a specific override value. If the removed override
|
||||
* had the highest priority, and the new value is different from
|
||||
* the previous value, the 'change' event will be fired.
|
||||
* @param {import('core').TokenString} token The token for the corresponding override which is to be removed.
|
||||
* @returns {boolean} `true` if an override was returned, `false` otherwise.
|
||||
*/
|
||||
clearOverride(token) {
|
||||
for (let i = 0, ii = this._overrides.length; i < ii; ++i) {
|
||||
if (this._overrides[i].token === token) {
|
||||
this._overrides.splice(i, 1);
|
||||
if (i === 0) { this._updateValue(); }
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates the current value using the current overrides and default value.
|
||||
* If the new value differs from the previous value, the 'change' event will be fired.
|
||||
*/
|
||||
_updateValue() {
|
||||
const value = this._overrides.length > 0 ? this._overrides[0].value : this._defaultValue;
|
||||
if (this._value === value) { return; }
|
||||
this._value = value;
|
||||
this.trigger('change', {value});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user