UNPKG

@silexlabs/grapesjs-symbols

Version:
167 lines 6.71 kB
"use strict"; var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) { if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) { if (ar || !(i in from)) { if (!ar) ar = Array.prototype.slice.call(from, 0, i); ar[i] = from[i]; } } return to.concat(ar || Array.prototype.slice.call(from)); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.makeInstanceIdsUnique = makeInstanceIdsUnique; /** * Attributes that can contain references to element IDs. * These should be updated when IDs are made unique. */ var ID_REFERENCE_ATTRIBUTES = [ 'for', // <label for="..."> 'aria-labelledby', // ARIA: labels 'aria-describedby', // ARIA: descriptions 'aria-controls', // ARIA: controls 'aria-owns', // ARIA: ownership 'aria-activedescendant', // ARIA: active descendant 'aria-flowto', // ARIA: flow 'aria-errormessage', // ARIA: error message 'list', // <input list="..."> for datalist 'form', // <input form="..."> for form association 'headers', // <td headers="..."> for table headers ]; /** * Attributes that contain ID references prefixed with # */ var HASH_ID_ATTRIBUTES = [ 'href', // <a href="#id"> 'data-target', // Bootstrap 4: data-target="#id" 'data-bs-target', // Bootstrap 5: data-bs-target="#id" ]; /** * Helper to get all components under a root component in depth-first order. */ function flattenComponents(root) { var components = []; root.onAll(function (c) { return components.push(c); }); return components; } /** * Build a map from main symbol component IDs to instance component IDs * Uses component order to correlate since both have the same structure */ function buildIdMap(mainSymbol, instance) { var idMap = new Map(); var mainComponents = flattenComponents(mainSymbol); var instanceComponents = flattenComponents(instance); var n = Math.min(mainComponents.length, instanceComponents.length); for (var i = 0; i < n; i++) { var mainId = mainComponents[i].getAttributes().id; var instanceId = instanceComponents[i].getAttributes().id; if (mainId && instanceId) { idMap.set(mainId, instanceId); } } return idMap; } /** * Collect all ID reference values from the main symbol. * Returns a map of: referenced ID -> list of {component index, attribute name, isHash} */ function collectIdReferences(mainSymbol) { var refs = new Map(); flattenComponents(mainSymbol).forEach(function (component, index) { var attrs = component.getAttributes(); var _loop_1 = function (attr) { var value = attrs[attr]; if (typeof value === 'string' && value) { var ids = value.split(/\s+/); ids.forEach(function (id) { if (!refs.has(id)) refs.set(id, []); refs.get(id).push({ index: index, attr: attr, isHash: false }); }); } }; // Check direct ID references for (var _i = 0, ID_REFERENCE_ATTRIBUTES_1 = ID_REFERENCE_ATTRIBUTES; _i < ID_REFERENCE_ATTRIBUTES_1.length; _i++) { var attr = ID_REFERENCE_ATTRIBUTES_1[_i]; _loop_1(attr); } // Check hash-prefixed ID references for (var _a = 0, HASH_ID_ATTRIBUTES_1 = HASH_ID_ATTRIBUTES; _a < HASH_ID_ATTRIBUTES_1.length; _a++) { var attr = HASH_ID_ATTRIBUTES_1[_a]; var value = attrs[attr]; if (typeof value === 'string' && value.startsWith('#')) { var id = value.substring(1); if (!refs.has(id)) refs.set(id, []); refs.get(id).push({ index: index, attr: attr, isHash: true }); } } }); return refs; } /** * Update ID references in a symbol instance to match the new unique IDs. * * This function: * 1. Gets the main symbol for this instance * 2. Builds a map of main symbol IDs -> instance IDs * 3. Finds all ID references in the main symbol (for, aria-*, href="#...", etc.) * 4. Updates those references in the instance to use the new IDs * * @param editor - The GrapesJS editor instance * @param instance - The root component of the symbol instance */ function makeInstanceIdsUnique(editor, instance) { var symbolInfo = editor.Components.getSymbolInfo(instance); if (!(symbolInfo === null || symbolInfo === void 0 ? void 0 : symbolInfo.main)) return; var mainSymbol = symbolInfo.main; var idMap = buildIdMap(mainSymbol, instance); if (idMap.size === 0) return; var refs = collectIdReferences(mainSymbol); var instanceComponents = flattenComponents(instance); refs.forEach(function (refList, referencedId) { // Prefer exact match, fallback to prefix match (e.g., for GrapesJS suffixes) var newId; idMap.forEach(function (instanceId, mainId) { if (mainId === referencedId || mainId.startsWith(referencedId + '-')) { newId = instanceId; } }); if (!newId) return; refList.forEach(function (ref) { var _a; var component = instanceComponents[ref.index]; if (!component) return; var attrs = component.getAttributes(); var currentValue = attrs[ref.attr]; var newValue; if (ref.isHash) { newValue = "#".concat(newId); } else if (typeof currentValue === 'string' && currentValue.includes(' ')) { // Handle space-separated list of IDs newValue = currentValue .split(/\s+/) .map(function (id) { return id === referencedId ? newId : id; }) .join(' '); } else { newValue = newId; } // Temporarily add symbol override for attributes, then set attribute, then restore overrides var overrides = component.getSymbolOverride() || []; var overridesArray = Array.isArray(overrides) ? overrides : []; var hasAttrOverride = overridesArray.includes('attributes'); if (!hasAttrOverride) component.setSymbolOverride(__spreadArray(__spreadArray([], overridesArray, true), ['attributes'], false)); component.setAttributes((_a = {}, _a[ref.attr] = newValue, _a)); if (!hasAttrOverride) component.setSymbolOverride(overrides); }); }); } //# sourceMappingURL=id-utils.js.map