@silexlabs/grapesjs-data-source
Version:
Grapesjs Data Source
236 lines • 8.22 kB
JavaScript
;
/*
* Silex website builder, free/libre no-code tool for makers.
* Copyright (c) 2023 lexoyo and Silex Labs foundation
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or 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 Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.COMPONENT_NAME_PREFIX = void 0;
exports.getPersistantId = getPersistantId;
exports.getOrCreatePersistantId = getOrCreatePersistantId;
exports.getComponentByPersistentId = getComponentByPersistentId;
exports.getChildByPersistantId = getChildByPersistantId;
exports.getParentByPersistentId = getParentByPersistentId;
exports.getStateDisplayName = getStateDisplayName;
exports.onStateChange = onStateChange;
exports.getStateIds = getStateIds;
exports.getStates = getStates;
exports.getStateVariableName = getStateVariableName;
exports.getState = getState;
exports.setState = setState;
exports.removeState = removeState;
/**
* @fileoverview This file contains the model for components states
* A state is a value which can be used in expressions
* If exported it will be available in the context of child components
*/
// Keys to store the states in the component
const EXPORTED_STATES_KEY = 'publicStates';
const PRIVATE_STATES_KEY = 'privateStates';
/**
* Persistant ID is used to identify a component reliably
* It will be stored with the website data
*/
const PERSISTANT_ID_KEY = 'id-plugin-data-source';
/**
* Override the prefix of state names
*/
exports.COMPONENT_NAME_PREFIX = 'nameForDataSource';
/**
* Get the persistant ID of a component
*/
function getPersistantId(component) {
var _a;
return (_a = component.get(PERSISTANT_ID_KEY)) !== null && _a !== void 0 ? _a : null;
}
/**
* Get the persistant ID of a component and create it if it does not exist
*/
function getOrCreatePersistantId(component) {
const persistantId = component.get(PERSISTANT_ID_KEY);
if (persistantId)
return persistantId;
const newPersistantId = `${component.ccid}-${Math.round(Math.random() * 10000)}`;
component.set(PERSISTANT_ID_KEY, newPersistantId);
return newPersistantId;
}
/**
* Find a component by its persistant ID in the current page
*/
function getComponentByPersistentId(id, editor) {
const pages = editor.Pages.getAll();
for (const page of pages) {
const body = page.getMainComponent();
const component = getChildByPersistantId(id, body);
if (component)
return component;
}
return null;
}
/**
* Find a component by its persistant ID in
*/
function getChildByPersistantId(id, parent) {
if (getPersistantId(parent) === id)
return parent;
for (const child of parent.components()) {
const component = getChildByPersistantId(id, child);
if (component)
return component;
}
return null;
}
/**
* Find a component by its persistant ID in the current page
*/
function getParentByPersistentId(id, component) {
if (!component)
return null;
if (getPersistantId(component) === id)
return component;
return getParentByPersistentId(id, component.parent());
}
/**
* Get the display name of a state
*/
function getStateDisplayName(child, state) {
var _a;
const component = getParentByPersistentId(state.componentId, child);
//const name = component?.getName() ?? '[Not found]'
const prefix = (_a = component === null || component === void 0 ? void 0 : component.get(exports.COMPONENT_NAME_PREFIX)) !== null && _a !== void 0 ? _a : ''; // `${name}'s`
return `${prefix ? prefix + ' ' : ''}${state.label || state.storedStateId}`;
}
/**
* Callbacks called when a state is changed
* @returns A function to remove the callback
*/
const _callbacks = [];
function onStateChange(callback) {
_callbacks.push(callback);
return () => {
const index = _callbacks.indexOf(callback);
if (index >= 0)
_callbacks.splice(index, 1);
};
}
function fireChange(state, component) {
_callbacks.forEach(callback => callback(state, component));
}
/**
* List all exported states
*/
function getStateIds(component, exported = true, before) {
var _a;
try {
const states = (_a = component.get(exported ? EXPORTED_STATES_KEY : PRIVATE_STATES_KEY)) !== null && _a !== void 0 ? _a : [];
const allStates = states
.sort((a, b) => { var _a, _b; return Number((_a = b.hidden) !== null && _a !== void 0 ? _a : false) - Number((_b = a.hidden) !== null && _b !== void 0 ? _b : false); }) // Hidden states first
.map(state => state.id);
if (before) {
const index = allStates.indexOf(before);
if (index < 0)
return allStates;
return allStates.slice(0, index);
}
return allStates;
}
catch (e) {
// this happens when the old deprecated state system is used
console.error('Error while getting state ids', e);
return [];
}
}
/**
* List all exported states
*/
function getStates(component, exported = true) {
var _a;
const states = (_a = component.get(exported ? EXPORTED_STATES_KEY : PRIVATE_STATES_KEY)) !== null && _a !== void 0 ? _a : [];
return states.map(state => ({
label: state.label,
hidden: state.hidden,
expression: state.expression,
}));
}
/**
* Get the name of a state variable
* Useful to generate code
*/
function getStateVariableName(componentId, stateId) {
return `state_${componentId}_${stateId}`;
}
/**
* Get a state
*/
function getState(component, id, exported = true) {
var _a, _b;
const states = (_a = component.get(exported ? EXPORTED_STATES_KEY : PRIVATE_STATES_KEY)) !== null && _a !== void 0 ? _a : [];
const state = (_b = states.find(state => state.id === id)) !== null && _b !== void 0 ? _b : null;
if (!state) {
return null;
}
return {
label: state.label,
hidden: state.hidden,
expression: state.expression,
};
}
/**
* Set a state
* The state will be updated or created at the end of the list
* Note: index is not used in this project anymore (maybe in apps using this plugins)
*/
function setState(component, id, state, exported = true, index = -1) {
var _a, _b;
const key = exported ? EXPORTED_STATES_KEY : PRIVATE_STATES_KEY;
const states = (_a = component.get(key)) !== null && _a !== void 0 ? _a : [];
const existing = (_b = states.find(s => s.id === id)) !== null && _b !== void 0 ? _b : null;
if (existing) {
component.set(key, states.map(s => s.id !== id ? s : Object.assign({ id }, state)));
}
else {
component.set(key, [
...states,
Object.assign({ id }, state),
]);
}
// Set the index if needed
if (index >= 0) {
const states = [...component.get(key)];
const state = states.find(s => s.id === id);
if (state && index < states.length) {
states.splice(states.indexOf(state), 1);
states.splice(index, 0, state);
component.set(key, states);
}
}
// Notify the change
fireChange({
label: state.label,
hidden: state.hidden,
expression: state.expression,
}, component);
}
/**
* Remove a state
*/
function removeState(component, id, exported = true) {
var _a;
const key = exported ? EXPORTED_STATES_KEY : PRIVATE_STATES_KEY;
const states = (_a = component.get(key)) !== null && _a !== void 0 ? _a : [];
const newStates = states.filter(s => s.id !== id);
component.set(key, newStates);
fireChange(null, component);
}
//# sourceMappingURL=state.js.map