Browse Source

Small bug fixes and improvements (#6067)

* If storage is not defined exit before triggering storage start

* Fix duplicate assets when added with the same `src`

* Add layer delegate to Component

* Enable test on keyframes

* Up ParserCss test

* Fix format
pull/6068/head
Artur Arseniev 1 year ago
committed by GitHub
parent
commit
b3d4c47e68
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      README.md
  2. 8
      src/dom_components/model/types.ts
  3. 3
      src/domain_abstract/model/TypeableCollection.ts
  4. 16
      src/navigator/index.ts
  5. 9
      src/navigator/view/ItemsView.ts
  6. 4
      src/storage_manager/index.ts
  7. 21
      test/specs/css_composer/index.ts
  8. 3
      test/specs/parser/model/ParserCss.ts

2
README.md

@ -5,6 +5,8 @@
[![CDNJS](https://img.shields.io/cdnjs/v/grapesjs.svg)](https://cdnjs.com/libraries/grapesjs)
[![npm](https://img.shields.io/npm/v/grapesjs.svg)](https://www.npmjs.com/package/grapesjs)
> If you looking to embed the [Studio](https://app.grapesjs.com/studio) editor in your application, we now offer the [Studio SDK](https://app.grapesjs.com/dashboard/sdk/licenses?ref=repo-readme), a ready-to-use visual builder that's easy to embed in external applications, with GrapesJS team support included.
<p align="center"><img src="http://grapesjs.com/assets/images/grapesjs-front-page-m.jpg" alt="GrapesJS" width="500" align="center"/></p>
GrapesJS is a free and open source Web Builder Framework which helps building HTML templates, faster and easily, to be delivered in sites, newsletters or mobile apps. Mainly, GrapesJS was designed to be used inside a [CMS] to speed up the creation of dynamic templates. To better understand this concept check the image below

8
src/dom_components/model/types.ts

@ -65,6 +65,14 @@ export interface ComponentDelegateProps {
* }
*/
select?: (cmp: Component) => Component | Nullable;
/**
* Delegate another component as a layer in the LayerManager.
* @example
* delegate: {
* layer: (cmp) => cmp.findType('other-type')[0],
* }
*/
layer?: (cmp: Component) => Component | Nullable;
}
export interface ComponentProperties {

3
src/domain_abstract/model/TypeableCollection.ts

@ -27,6 +27,9 @@ const TypeableCollection = {
const model = new Model(attrs, { ...options, em });
model.typeView = View;
// As we're using a dynamic model function, backbone collection is unable to
// get `model.prototype.idAttribute`
this.model.prototype = Model.prototype;
return model;
};
const init = this.init && this.init.bind(this);

16
src/navigator/index.ts

@ -127,9 +127,10 @@ export default class LayerManager extends Module<LayerManagerConfig> {
root = wrapper.find(component)[0] || wrapper;
}
this.model.set('root', root);
const result = this.__getLayerFromComponent(root);
this.model.set('root', result);
return root;
return result;
}
/**
@ -152,7 +153,10 @@ export default class LayerManager extends Module<LayerManagerConfig> {
* console.log(components);
*/
getComponents(component: Component): Component[] {
return component.components().filter((cmp: any) => this.__isLayerable(cmp));
return component
.components()
.map((cmp) => this.__getLayerFromComponent(cmp))
.filter((cmp: any) => this.__isLayerable(cmp));
}
/**
@ -360,12 +364,16 @@ export default class LayerManager extends Module<LayerManagerConfig> {
this.__trgCustom();
}
__getLayerFromComponent(cmp: Component) {
return cmp.delegate?.layer?.(cmp) || cmp;
}
__onComponent(component: Component) {
this.updateLayer(component);
}
__isLayerable(cmp: Component): boolean {
const tag = cmp.get('tagName');
const tag = cmp.tagName;
const hideText = this.config.hideTextnode;
const isValid = !hideText || (!cmp.isInstanceOf('textnode') && tag !== 'br');

9
src/navigator/view/ItemsView.ts

@ -4,12 +4,14 @@ import Component from '../../dom_components/model/Component';
import EditorModel from '../../editor/model/Editor';
import ItemView from './ItemView';
import Components from '../../dom_components/model/Components';
import LayerManager from '..';
export default class ItemsView extends View {
items: ItemView[];
opt: any;
config: any;
parentView: ItemView;
module: LayerManager;
/** @ts-ignore */
collection!: Components;
@ -19,6 +21,7 @@ export default class ItemsView extends View {
this.opt = opt;
const config = opt.config || {};
this.config = config;
this.module = opt.module;
this.parentView = opt.parentView;
const pfx = config.stylePrefix || '';
const ppfx = config.pStylePrefix || '';
@ -128,10 +131,12 @@ export default class ItemsView extends View {
}
render() {
const { el, module } = this;
const frag = document.createDocumentFragment();
const el = this.el;
el.innerHTML = '';
this.collection.each((model) => this.addToCollection(model, frag));
this.collection
.map((cmp) => module.__getLayerFromComponent(cmp))
.forEach((model) => this.addToCollection(model, frag));
el.appendChild(frag);
el.className = this.className!;
return this;

4
src/storage_manager/index.ts

@ -270,12 +270,12 @@ export default class StorageManager extends Module<
const { onStore, onLoad } = this.getConfig();
let result;
this.onStart(ev, data);
if (!storage) {
return data || {};
}
this.onStart(ev, data);
try {
const editor = this.em?.getEditor();
let response: any;

21
test/specs/css_composer/index.ts

@ -418,8 +418,7 @@ describe('Css Composer', () => {
expect(getCSS(obj)).toEqual(cssRule.trim());
});
// TODO update jest to be able to test keyframes
test.skip('Add rules with @keyframes at rule', () => {
test('Add rules with @keyframes at rule', () => {
const cssRule = `
@keyframes keyname {
from { width: 0% }
@ -428,14 +427,24 @@ describe('Css Composer', () => {
}
`;
const result = obj.addCollection(cssRule);
console.log({ result });
const [rule1, rule2, rule3] = result;
console.log({ result: JSON.parse(JSON.stringify(rule1)) });
expect(result.length).toEqual(3);
expect(obj.getAll().length).toEqual(3);
expect(rule1.get('mediaText')).toBe('keyname');
expect(rule1.get('atRuleType')).toBe('keyframes');
// TODO to complete
result.forEach((rule) => {
expect(rule.get('mediaText')).toBe('keyname');
expect(rule.get('atRuleType')).toBe('keyframes');
});
expect(rule1.getSelectorsString()).toBe('from');
expect(rule1.getStyle()).toEqual({ width: '0%' });
expect(rule2.getSelectorsString()).toBe('40%, 50%');
expect(rule2.getStyle()).toEqual({ width: '50%' });
expect(rule3.getSelectorsString()).toBe('to');
expect(rule3.getStyle()).toEqual({ width: '100%' });
});
});
});

3
test/specs/parser/model/ParserCss.ts

@ -251,8 +251,7 @@ describe('ParserCss', () => {
expect(obj.parse(str)).toEqual([result]);
});
// Can't test keyframes https://github.com/NV/CSSOM/issues/95
test.skip('Parse rule with a keyframes at-rule', () => {
test('Parse rule with a keyframes at-rule', () => {
var str = `@keyframes {
from {opacity: 0;}
to {opacity: 1;}

Loading…
Cancel
Save