0
Fork 0
mirror of https://github.com/penpot/penpot.git synced 2025-03-09 06:11:23 -05:00
penpot/frontend/text-editor/editor/controllers/ChangeController.js
2024-11-19 17:05:30 +01:00

92 lines
1.9 KiB
JavaScript

/**
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
* Copyright (c) KALEIDOS INC
*/
/**
* Change controller is responsible of notifying when a change happens.
*/
export class ChangeController extends EventTarget {
/**
* Keeps the timeout id.
*
* @type {number}
*/
#timeout = null;
/**
* Keeps the time at which we're going to
* call the debounced change calls.
*
* @type {number}
*/
#time = 1000;
/**
* Keeps if we have some pending changes or not.
*
* @type {boolean}
*/
#hasPendingChanges = false;
/**
* Constructor
*
* @param {number} [time=500]
*/
constructor(time = 500) {
super()
if (typeof time === "number" && (!Number.isInteger(time) || time <= 0)) {
throw new TypeError("Invalid time");
}
this.#time = time ?? 500;
}
/**
* Indicates that there are some pending changes.
*
* @type {boolean}
*/
get hasPendingChanges() {
return this.#hasPendingChanges;
}
#onTimeout = () => {
this.dispatchEvent(new Event("change"));
};
/**
* Tells the ChangeController that a change has been made
* but that you need to delay the notification (and debounce)
* for sometime.
*/
notifyDebounced() {
this.#hasPendingChanges = true;
clearTimeout(this.#timeout);
this.#timeout = setTimeout(this.#onTimeout, this.#time);
}
/**
* Tells the ChangeController that a change should be notified
* immediately.
*/
notifyImmediately() {
clearTimeout(this.#timeout);
this.#onTimeout();
}
/**
* Disposes the referenced resources.
*/
dispose() {
if (this.hasPendingChanges) {
this.notifyImmediately();
}
clearTimeout(this.#timeout);
}
}
export default ChangeController;