Browse Source

Merge branch 'dev' into page-manager

pull/3411/head
Artur Arseniev 5 years ago
parent
commit
5f5d2d117a
  1. 4
      dist/grapes.min.js
  2. 2
      dist/grapes.min.js.map
  3. 2
      package-lock.json
  4. 2
      package.json
  5. 44
      src/dom_components/model/Component.js
  6. 48
      src/dom_components/model/Components.js
  7. 67
      test/specs/dom_components/model/Symbols.js

4
dist/grapes.min.js

File diff suppressed because one or more lines are too long

2
dist/grapes.min.js.map

File diff suppressed because one or more lines are too long

2
package-lock.json

@ -1,6 +1,6 @@
{
"name": "grapesjs",
"version": "0.16.41",
"version": "0.16.42",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

2
package.json

@ -1,7 +1,7 @@
{
"name": "grapesjs",
"description": "Free and Open Source Web Builder Framework",
"version": "0.16.41",
"version": "0.16.42",
"author": "Artur Arseniev",
"license": "BSD-3-Clause",
"homepage": "http://grapesjs.com",

44
src/dom_components/model/Component.js

@ -206,7 +206,7 @@ const Component = Backbone.Model.extend(Styleable).extend(
if (!opt.temporary) {
this.init();
this.__isSymbol() && this.__initSymb();
this.__isSymbolOrInst() && this.__initSymb();
em && em.trigger('component:create', this);
}
},
@ -619,24 +619,56 @@ const Component = Backbone.Model.extend(Styleable).extend(
return isArray(this.get(keySymbols));
},
__isSymbolOrInst() {
return !!(this.__isSymbol() || this.get(keySymbol));
},
__isSymbolTop() {
const parent = this.parent();
const symb = this.__isSymbolOrInst();
return (
!parent || (parent && !parent.__isSymbol() && !parent.__getSymbol())
symb &&
(!parent || (parent && !parent.__isSymbol() && !parent.__getSymbol()))
);
},
__getAllById() {
const { em } = this;
return em ? em.get('DomComponents').allById() : {};
},
__getSymbol() {
return this.get(keySymbol);
let symb = this.get(keySymbol);
if (symb && isString(symb)) {
const ref = this.__getAllById()[symb];
if (ref) {
symb = ref;
this.set(keySymbol, ref);
} else {
symb = 0;
}
}
return symb;
},
__getSymbols() {
return this.get(keySymbols);
let symbs = this.get(keySymbols);
if (symbs && isArray(symbs)) {
symbs.forEach((symb, idx) => {
if (symb && isString(symb)) {
symbs[idx] = this.__getAllById()[symb];
}
});
symbs = symbs.filter(symb => symb && !isString(symb));
}
return symbs;
},
__getSymbToUp(opts = {}) {
const { em } = this;
const symbEnabled = em && em.get('symbols');
const { fromInstance } = opts;
const symbols = this.get(keySymbols) || [];
const symbols = this.__getSymbols() || [];
const symbol = this.__getSymbol();
let result =
symbol && !fromInstance
@ -647,7 +679,7 @@ const Component = Backbone.Model.extend(Styleable).extend(
result = result.filter(i => i !== fromInstance);
}
return result;
return symbEnabled ? result : [];
},
__getSymbTop(opts) {

48
src/dom_components/model/Components.js

@ -257,28 +257,30 @@ export default Backbone.Collection.extend({
},
__onAddEnd: debounce(function() {
const { domc } = this;
const allComp = (domc && domc.allById()) || {};
const firstAdd = this.__firstAdd;
const toCheck = isArray(firstAdd) ? firstAdd : [firstAdd];
const silent = { silent: true };
const onAll = comps => {
comps.forEach(comp => {
const symbol = comp.get(keySymbols);
const symbolOf = comp.get(keySymbol);
if (symbol && isArray(symbol) && isString(symbol[0])) {
comp.set(
keySymbols,
symbol.map(smb => allComp[smb]).filter(i => i),
silent
);
}
if (isString(symbolOf)) {
comp.set(keySymbol, allComp[symbolOf], silent);
}
onAll(comp.components());
});
};
onAll(toCheck);
// TODO to check symbols on load, probably this might be removed as symbols
// are always recovered from the model
// const { domc } = this;
// const allComp = (domc && domc.allById()) || {};
// const firstAdd = this.__firstAdd;
// const toCheck = isArray(firstAdd) ? firstAdd : [firstAdd];
// const silent = { silent: true };
// const onAll = comps => {
// comps.forEach(comp => {
// const symbol = comp.get(keySymbols);
// const symbolOf = comp.get(keySymbol);
// if (symbol && isArray(symbol) && isString(symbol[0])) {
// comp.set(
// keySymbols,
// symbol.map(smb => allComp[smb]).filter(i => i),
// silent
// );
// }
// if (isString(symbolOf)) {
// comp.set(keySymbol, allComp[symbolOf], silent);
// }
// onAll(comp.components());
// });
// };
// onAll(toCheck);
})
});

67
test/specs/dom_components/model/Symbols.js

@ -14,6 +14,10 @@ describe('Symbols', () => {
comp.parent().append(cloned, { at: comp.index() + 1 });
return cloned;
};
const simpleCompDef = {
type: 'text',
components: [{ type: 'textnode', content: 'Component' }]
};
const simpleComp = '<div data-a="b">Component</div>';
const simpleComp2 = '<div data-b="c">Component 3</div>';
const compMultipleNodes = `<div data-v="a">
@ -26,9 +30,25 @@ describe('Symbols', () => {
const getInnerComp = (cmp, i = 0) => cmp.components().at(i);
const getFirstInnSymbol = cmp => getInnerComp(cmp).__getSymbol();
const getInnSymbol = (cmp, i = 0) => getInnerComp(cmp, i).__getSymbol();
const basicSymbUpdate = (cFrom, cTo) => {
const rand = (Math.random() + 1).toString(36).slice(-7);
const newAttr = { class: `cls-${rand}`, [`myattr-${rand}`]: `val-${rand}` };
cFrom.setAttributes(newAttr);
cFrom.components(`New text content ${rand}`);
const toAttr = cTo.getAttributes();
delete toAttr.id;
const htmlOpts = {
attributes: (m, attr) => {
delete attr.id;
return attr;
}
};
expect(toAttr).toEqual(newAttr);
expect(cFrom.toHTML(htmlOpts)).toBe(cTo.toHTML(htmlOpts));
};
beforeAll(() => {
editor = new Editor();
editor = new Editor({ symbols: 1 });
wrapper = editor.getWrapper();
});
@ -43,6 +63,15 @@ describe('Symbols', () => {
wrapper.components().reset();
});
test("Simple clone doesn't create any symbol", () => {
const comp = wrapper.append(simpleComp)[0];
const cloned = comp.clone();
[comp, cloned].forEach(item => {
expect(item.__getSymbol()).toBeFalsy();
expect(item.__getSymbols()).toBeFalsy();
});
});
test('Create symbol from a component', () => {
const comp = wrapper.append(simpleComp)[0];
const symbol = createSymbol(comp);
@ -89,6 +118,42 @@ describe('Symbols', () => {
expect(jsonSymb[keySymbols]).toEqual([idComp]);
});
test('Serialized symbol references are always recovered', () => {
const comp = wrapper.append(simpleComp)[0];
const symbol = createSymbol(comp);
const idComp = comp.getId();
const idSymb = symbol.getId();
// Serialize symbols
comp.set(keySymbol, idSymb);
symbol.set(keySymbols, [idComp]);
// Check updates from instance
basicSymbUpdate(comp, symbol);
// Check updates from symbol
basicSymbUpdate(symbol, comp);
});
test('Symbols recovers correctly from serialization', () => {
const idComp = 'c1';
const idSymb = 's1';
const defComp = {
...simpleCompDef,
[keySymbol]: idSymb,
attributes: { id: idComp }
};
const defSymb = {
...simpleCompDef,
[keySymbols]: [idComp],
attributes: { id: idSymb }
};
const [comp, symbol] = wrapper.append([defComp, defSymb]);
expect(comp.__getSymbol()).toBe(symbol);
expect(comp.get(keySymbol)).toBe(symbol);
expect(symbol.__getSymbols()[0]).toBe(comp);
expect(symbol.get(keySymbols)[0]).toBe(comp);
basicSymbUpdate(comp, symbol);
basicSymbUpdate(symbol, comp);
});
test("Removing one instance doesn't affect others", () => {
const comp = wrapper.append(simpleComp)[0];
const symbol = createSymbol(comp);

Loading…
Cancel
Save