141 lines
4.0 KiB
JavaScript
141 lines
4.0 KiB
JavaScript
import Cetra from '../../lib/lib.js';
|
|
/**
|
|
* Represents a base component class.
|
|
*/
|
|
export default class BaseComponent {
|
|
#data = new Map([
|
|
['type', 'BaseComponent'],
|
|
['selector', 'cetra-component'],
|
|
['variables', new Map()],
|
|
['cetraId', ''],
|
|
]);
|
|
|
|
/**
|
|
* Constructs a new instance of the BaseComponent class.
|
|
* @param {Map} data - The initial data for the component.
|
|
*/
|
|
constructor(data = new Map()) {
|
|
for (const key of this.#data.keys()) {
|
|
if (
|
|
!data.has(key) ||
|
|
typeof data.get(key) != typeof this.#data.get(key)
|
|
)
|
|
continue;
|
|
this.#data.set(key, data.get(key));
|
|
}
|
|
this.#data = data;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the value associated with the specified key from the data map.
|
|
* @param {string} key - The key to retrieve the value for.
|
|
* @returns {*} - The value associated with the key.
|
|
*/
|
|
get(key) {
|
|
return this.#data.get(key);
|
|
}
|
|
|
|
/**
|
|
* Sets a key-value pair in the component's data.
|
|
* @param {string} key - The key to set.
|
|
* @param {*} value - The value to set.
|
|
* @returns {BaseComponent} - The updated component instance.
|
|
*/
|
|
set(key, value) {
|
|
this.#data.set(key, value);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the value of a variable by its name.
|
|
*
|
|
* @param {string} varName - The name of the variable.
|
|
* @returns {*} - The value of the variable, or null if the variable is not found.
|
|
* @throws {Error} - If no Cetra instance is found.
|
|
*/
|
|
getValue(varName) {
|
|
if (typeof varName != 'string') return null;
|
|
if (varName.startsWith('$')) varName = varName.slice(1);
|
|
if (!this.get('variables').has(varName)) return null;
|
|
const frameWork = Cetra.getInstance(this.get('cetraId'));
|
|
if (!frameWork) throw new Error('no cetra instance found');
|
|
const varValue = frameWork.convertValue(
|
|
this.get('variables').get(varName).get('type'),
|
|
this.getVarNodes(varName).shift().textContent
|
|
);
|
|
return varValue;
|
|
}
|
|
|
|
/**
|
|
* Retrieves the value of a variable.
|
|
* @param {string} varName - The name of the variable.
|
|
* @returns {*} - The value of the variable.
|
|
*/
|
|
getVal(varName) {
|
|
return this.getValue(varName);
|
|
}
|
|
|
|
/**
|
|
* Retrieves the value of a variable by its name.
|
|
*
|
|
* @param {string} varName - The name of the variable.
|
|
* @returns {*} - The value of the variable.
|
|
*/
|
|
getVar(varName) {
|
|
return this.get('variables').get(varName);
|
|
}
|
|
|
|
/**
|
|
* Retrieves the DOM node associated with the component.
|
|
* @returns {HTMLElement} The DOM node.
|
|
* @throws {Error} If no node is found.
|
|
*/
|
|
getNode() {
|
|
let node = document.querySelector(this.get('selector'));
|
|
|
|
if (!node) node = document.getElementById(this.get('id'));
|
|
if (!node) throw new Error('no node found');
|
|
|
|
return node;
|
|
}
|
|
|
|
/**
|
|
* Retrieves all DOM nodes that have a data attribute matching the specified variable name.
|
|
* @param {string} varName - The name of the variable to search for.
|
|
* @returns {Array<HTMLElement>} - An array of DOM nodes matching the variable name.
|
|
* @throws {Error} - Throws an error if no cetra instance is found.
|
|
*/
|
|
getVarNodes(varName) {
|
|
const frameWork = Cetra.getInstance(this.get('cetraId'));
|
|
if (!frameWork) throw new Error('no cetra instance found');
|
|
const varNodeSelector = `[data-${frameWork.getOption(
|
|
'selector'
|
|
)}-var^="${varName}"]`;
|
|
return [...this.getNode().querySelectorAll(varNodeSelector)];
|
|
}
|
|
|
|
/**
|
|
* Updates the component with the given deltas.
|
|
* @param {Array} deltas - An array of deltas to apply.
|
|
* @throws {TypeError} If deltas is not an array.
|
|
* @throws {Error} If no cetra instance is found.
|
|
*/
|
|
update(deltas) {
|
|
if (!Array.isArray(deltas))
|
|
throw new TypeError('deltas must be an array');
|
|
|
|
const frameWork = Cetra.getInstance(this.get('cetraId'));
|
|
if (!frameWork) throw new Error('no cetra instance found');
|
|
|
|
for (const delta of deltas) {
|
|
const { new: value, old: oldValue, varName } = delta;
|
|
if (!this.get('variables').has(varName)) continue;
|
|
const variable = this.get('variables').get(varName);
|
|
|
|
this.getVarNodes(varName).forEach((el) => {
|
|
el.textContent = value ?? variable.get('default');
|
|
});
|
|
}
|
|
}
|
|
}
|