Browse Source

Provide symbol instance detach

symbols-api
Artur Arseniev 2 years ago
parent
commit
8604b50086
  1. 5
      src/dom_components/index.ts
  2. 15
      src/dom_components/model/SymbolUtils.ts
  3. 10
      src/dom_components/model/Symbols.ts
  4. 21
      test/specs/dom_components/model/Symbols.ts

5
src/dom_components/index.ts

@ -104,6 +104,7 @@ import ComponentsView from './view/ComponentsView';
import ComponentHead, { type as typeHead } from './model/ComponentHead';
import { getSymbolMain, getSymbolInstances, getSymbolsToUpdate, isSymbolMain } from './model/SymbolUtils';
import { SymbolInfo } from './types';
import Symbols from './model/Symbols';
export type ComponentEvent =
| 'component:create'
@ -297,7 +298,7 @@ export default class ComponentManager extends ItemManagerModule<DomComponentsCon
keySymbols = 'symbols';
shallow?: Component;
symbols: Components;
symbols: Symbols;
/**
* Initialize module. Called on a new instance of the editor with configurations passed
@ -308,7 +309,7 @@ export default class ComponentManager extends ItemManagerModule<DomComponentsCon
constructor(em: EditorModel) {
super(em, 'DomComponents', new Components(undefined, { em }));
const { config } = this;
this.symbols = new Components([], { em, config });
this.symbols = new Symbols([], { em, config });
if (em) {
//@ts-ignore

15
src/dom_components/model/SymbolUtils.ts

@ -57,7 +57,7 @@ export const getSymbolInstances = (symbol?: Component): Component[] | undefined
symbs = symbs.filter(symb => symb && !isString(symb));
}
return symbs;
return symbs || undefined;
};
export const isSymbolOverride = (symbol?: Component, prop = '') => {
@ -105,6 +105,19 @@ export const getSymbolTop = (symbol: Component, opts?: any) => {
return result;
};
export const detachSymbolInstance = (symbol: Component, opts: { skipRefs?: boolean } = {}) => {
const symbolMain = getSymbolMain(symbol);
const symbs = symbolMain && getSymbolInstances(symbolMain);
!opts.skipRefs &&
symbs &&
symbolMain.set(
keySymbols,
symbs.filter(s => s !== symbol)
);
symbol.set(keySymbol, 0);
symbol.components().forEach(s => detachSymbolInstance(s, opts));
};
export const logSymbol = (symb: Component, type: string, toUp: Component[], opts: any = {}) => {
const symbol = getSymbolMain(symb);
const symbols = getSymbolInstances(symb);

10
src/dom_components/model/Symbols.ts

@ -0,0 +1,10 @@
import Component from './Component';
import Components from './Components';
import { detachSymbolInstance, getSymbolInstances } from './SymbolUtils';
export default class Symbols extends Components {
removeChildren(removed: Component, coll?: Components, opts: any = {}) {
super.removeChildren(removed, coll, opts);
getSymbolInstances(removed)?.forEach(i => detachSymbolInstance(i, { skipRefs: true }));
}
}

21
test/specs/dom_components/model/Symbols.ts

@ -189,6 +189,27 @@ describe('Symbols', () => {
expect(toHTML(comp2)).toBe(toHTML(symbol));
});
test('When symbol is removed, all instances are detached', () => {
const comp = wrapper.append(compMultipleNodes)[0];
const symbol = createSymbol(comp);
[comp, ...comp.components().models].forEach(i => {
expect(getSymbolInfo(i).isInstance).toBe(true);
});
symbol.remove();
[comp, ...comp.components().models].forEach(i => {
expect(getSymbolInfo(i)).toEqual({
isSymbol: false,
isMain: false,
isInstance: false,
instances: [],
relatives: [],
});
});
});
test('Symbols and instances are correctly serialized', () => {
const comp = wrapper.append(simpleComp)[0];
const symbol = createSymbol(comp);

Loading…
Cancel
Save