Browse Source

Update yarn.lock

pull/4487/head
Artur Arseniev 4 years ago
parent
commit
1a8634d2ba
  1. 2
      package.json
  2. 37
      src/abstract/Collection.ts
  3. 21
      src/abstract/DomainViews.ts
  4. 39
      src/abstract/View.ts
  5. 8
      src/canvas/model/Frame.ts
  6. 12
      src/canvas/model/Frames.ts
  7. 5
      src/pages/model/Page.ts
  8. 245
      src/panels/index.js
  9. 232
      src/panels/index.ts
  10. 30
      src/panels/model/Button.js
  11. 62
      src/panels/model/Button.ts
  12. 19
      src/panels/model/Buttons.ts
  13. 20
      src/panels/model/Panel.js
  14. 31
      src/panels/model/Panel.ts
  15. 6
      src/panels/model/Panels.js
  16. 11
      src/panels/model/Panels.ts
  17. 70
      src/panels/view/ButtonView.ts
  18. 28
      src/panels/view/ButtonsView.ts
  19. 29
      src/panels/view/PanelView.ts
  20. 33
      src/panels/view/PanelsView.ts
  21. 12
      test/specs/panels/index.js
  22. 4
      test/specs/panels/model/PanelModels.js
  23. 11
      test/specs/panels/view/ButtonView.js
  24. 9
      test/specs/panels/view/ButtonsView.js
  25. 21
      test/specs/panels/view/PanelView.js
  26. 10
      test/specs/panels/view/PanelsView.js
  27. 6153
      yarn.lock

2
package.json

@ -16,7 +16,7 @@
"url": "https://github.com/artf/grapesjs.git"
},
"dependencies": {
"backbone": "1.3.3",
"backbone": "1.4.1",
"backbone-undo": "^0.2.5",
"codemirror": "^5.63.0",
"codemirror-formatting": "^1.0.0",

37
src/abstract/Collection.ts

@ -1,6 +1,35 @@
import Backbone from 'backbone';
import Backbone, { AddOptions } from 'backbone';
import { isArray, isObject, isUndefined } from 'underscore';
import Model from './Model';
export default class Collection<
TModel extends Model = Model
> extends Backbone.Collection<TModel> {}
type Module<TModel extends Model> = TModel extends Model<infer M> ? M : unknown;
type ModelConstructor<TModel extends Model> = { new (mod: Module<TModel>, attr: any): TModel };
export default class Collection<TModel extends Model = Model> extends Backbone.Collection<TModel> {
module!: Module<TModel>;
private newModel!: ModelConstructor<TModel>;
add(model: Array<Record<string, any>> | TModel, options?: AddOptions): TModel;
add(models: Array<Array<Record<string, any>> | TModel>, options?: AddOptions): TModel[];
add(model?: unknown, options?: AddOptions): any {
//Note: the undefined case needed because backbonejs not handle the reset() correctly
var models = isArray(model) ? model : !isUndefined(model) ? [model] : undefined;
models = models?.map(m => (m instanceof this.newModel ? m : new this.newModel(this.module, m))) ?? [undefined];
return super.add(isArray(model) ? models : models[0], options);
}
constructor(
module: Module<TModel>,
models: TModel[] | Array<Record<string, any>>,
modelConstructor: ModelConstructor<TModel>
) {
super(models, { module, modelConstructor });
}
preinitialize(models?: TModel[] | Array<Record<string, any>>, options?: any) {
this.newModel = options.modelConstructor;
this.module = options.module;
}
}

21
src/abstract/DomainViews.ts

@ -1,13 +1,13 @@
import { includes } from 'underscore';
import Backbone from 'backbone';
import View from './View';
import Collection from './Collection';
import Model from './Model';
/*interface DomainView<TView, TModel>{
constructor(model: TModel): TView
}*/
type TModel<TCollection> = TCollection extends Backbone.Collection<infer TModel>? TModel: Model;
export default abstract class DomainViews<TCollection extends Backbone.Collection<Model>, TItemView extends View> extends View<TModel<TCollection>> {
export default abstract class DomainViews<
TCollection extends Collection,
TItemView extends View
> extends View<TCollection> {
// Defines the View per type
itemsView = '';
@ -26,7 +26,7 @@ export default abstract class DomainViews<TCollection extends Backbone.Collectio
* @param {Model} model
* @private
* */
private addTo(model: TModel<TCollection>) {
private addTo(model: Model) {
this.add(model);
}
@ -35,7 +35,7 @@ export default abstract class DomainViews<TCollection extends Backbone.Collectio
const warn = `${ns ? `[${ns}]: ` : ''}'${type}' type not found`;
em?.logWarning(warn);*/
}
protected abstract renderView(model: TModel<TCollection>, itemType: string): TItemView;
protected abstract renderView(model: Model, itemType: string): TItemView;
/**
* Render new model inside the view
@ -43,7 +43,7 @@ export default abstract class DomainViews<TCollection extends Backbone.Collectio
* @param {Object} fragment Fragment collection
* @private
* */
private add(model: TModel<TCollection>, fragment?: DocumentFragment) {
private add(model: Model, fragment?: DocumentFragment) {
const { reuseView, viewCollection, itemsView = {} } = this;
var frag = fragment || null;
var typeField = model.get(this.itemType);
@ -69,10 +69,7 @@ export default abstract class DomainViews<TCollection extends Backbone.Collectio
this.clearItems();
this.$el.empty();
if (this.collection.length)
this.collection.each((model) => {
this.add(model, frag);
}, this);
if (this.collection.length) this.collection.each(model => this.add(model, frag));
this.$el.append(frag);
this.onRender();

39
src/abstract/View.ts

@ -1,29 +1,46 @@
import Backbone from 'backbone';
import Collection from './Collection';
import Model from './Model';
import Module, { IBaseModule } from './Module';
import { IBaseModule } from './Module';
export default class View<TModel extends Model = Model, TElement extends Element = HTMLElement> extends Backbone.View<
TModel,
TElement
> {
type ModuleFromModel<TModel extends Model> = TModel extends Model<infer M> ? M : unknown;
type Module<TItem extends Model | Collection> = TItem extends Collection<infer M>
? ModuleFromModel<M>
: TItem extends Model<infer M>
? M
: unknown;
type TCollection<TItem extends Model | Collection> = TItem extends Collection ? TItem : unknown;
export default class View<
TModel extends Model | Collection = Model,
TElement extends Element = HTMLElement
> extends Backbone.View<TModel extends Model ? TModel : undefined, TElement> {
protected get pfx() {
return this.ppfx + this.config.stylePrefix || '';
return this.ppfx + (this.config as any).stylePrefix || '';
}
protected get ppfx() {
return (this.em.config as any).stylePrefix || '';
return this.em.config.stylePrefix || '';
}
protected get module(): TModel extends Model<infer M> ? M : unknown {
//console.log((this.collection.first as any).module)
return this.model?.module ?? (this.collection as any).module;
collection!: TModel extends Model ? Collection<Model> : TModel;
protected get module(): Module<TModel> {
return (this.model as any)?.module ?? this.collection.module;
}
protected get em() {
return this.module.em;
}
protected get config(): TModel extends Model<infer M> ? (M extends IBaseModule<infer C> ? C : unknown) : unknown {
protected get config(): Module<TModel> extends IBaseModule<infer C> ? C : unknown {
return this.module.config as any;
}
public className!: string;
preinitialize(options?: any) {
this.className = '';
}
}

8
src/canvas/model/Frame.ts

@ -38,8 +38,8 @@ export default class Frame extends Model<CanvasModule> {
/**
* @hideconstructor
*/
constructor(module: CanvasModule, props: any) {
super(module, props);
constructor(module: CanvasModule, attr: any) {
super(module, attr);
const { em } = this;
const { styles, component } = this.attributes;
const domc = em.get('DomComponents');
@ -82,8 +82,8 @@ export default class Frame extends Model<CanvasModule> {
this.set('styles', allRules);
}
!props.width && this.set(keyAutoW, 1);
!props.height && this.set(keyAutoH, 1);
!attr.width && this.set(keyAutoW, 1);
!attr.height && this.set(keyAutoH, 1);
}
get head(): { tag: string; attributes: any }[] {

12
src/canvas/model/Frames.ts

@ -1,6 +1,6 @@
import { bindAll } from 'underscore';
import CanvasModule from '..';
import { Collection } from '../../common';
import { Collection } from '../../abstract';
import Page from '../../pages/model/Page';
import Frame from './Frame';
@ -8,11 +8,9 @@ export default class Frames extends Collection<Frame> {
loadedItems = 0;
itemsToLoad = 0;
page?: Page;
module: CanvasModule
constructor(module: CanvasModule, models: Frame[] = []) {
super(models);
this.module = module;
constructor(module: CanvasModule, models: Frame[] | Array<Record<string, any>> = []) {
super(module, models, Frame);
bindAll(this, 'itemLoaded');
this.on('reset', this.onReset);
this.on('remove', this.onRemove);
@ -20,7 +18,7 @@ export default class Frames extends Collection<Frame> {
onReset(m: Frame, opts?: { previousModels?: Frame[] }) {
const prev = opts?.previousModels || [];
prev.map((p) => this.onRemove(p));
prev.map(p => this.onRemove(p));
}
onRemove(removed?: Frame) {
@ -43,6 +41,6 @@ export default class Frames extends Collection<Frame> {
}
listenToLoadItems(on: boolean) {
this.forEach((item) => item[on ? 'on' : 'off']('loaded', this.itemLoaded));
this.forEach(item => item[on ? 'on' : 'off']('loaded', this.itemLoaded));
}
}

5
src/pages/model/Page.ts

@ -24,10 +24,7 @@ export default class Page extends Model {
['component', 'styles'].map(i => this.unset(i));
}
const frms: any[] = props.frames || [defFrame];
const frames = new Frames(
em.get('Canvas'),
frms?.map(model => new Frame(em.get('Canvas'), model))
);
const frames = new Frames(em.get('Canvas'), frms);
frames.page = this;
this.set('frames', frames);
!this.getId() && this.set('id', em?.get('PageManager')._createId());

245
src/panels/index.js

@ -1,245 +0,0 @@
/**
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/panels/config/config.js)
* ```js
* const editor = grapesjs.init({
* panels: {
* // options
* }
* })
* ```
*
* Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance
*
* ```js
* const panelManager = editor.Panels;
* ```
*
* * [addPanel](#addpanel)
* * [addButton](#addbutton)
* * [getButton](#getbutton)
* * [getPanel](#getpanel)
* * [getPanels](#getpanels)
* * [getPanelsEl](#getpanelsel)
* * [removePanel](#removepanel)
* * [removeButton](#removebutton)
*
* @module Panels
*/
import defaults from './config/config';
import Panel from './model/Panel';
import Panels from './model/Panels';
import PanelsView from './view/PanelsView';
export default () => {
var c = {};
var panels, PanelsViewObj;
return {
/**
* Name of the module
* @type {String}
* @private
*/
name: 'Panels',
/**
* Initialize module. Automatically called with a new instance of the editor
* @param {Object} config Configurations
* @private
*/
init(config) {
c = config || {};
for (var name in defaults) {
if (!(name in c)) c[name] = defaults[name];
}
var ppfx = c.pStylePrefix;
if (ppfx) c.stylePrefix = ppfx + c.stylePrefix;
panels = new Panels(c.defaults);
return this;
},
/**
* Returns the collection of panels
* @return {Collection} Collection of panel
*/
getPanels() {
return panels;
},
/**
* Returns panels element
* @return {HTMLElement}
*/
getPanelsEl() {
return PanelsViewObj && PanelsViewObj.el;
},
/**
* Add new panel to the collection
* @param {Object|Panel} panel Object with right properties or an instance of Panel
* @return {Panel} Added panel. Useful in case passed argument was an Object
* @example
* var newPanel = panelManager.addPanel({
* id: 'myNewPanel',
* visible : true,
* buttons : [...],
* });
*/
addPanel(panel) {
return panels.add(panel);
},
/**
* Remove a panel from the collection
* @param {Object|Panel|String} panel Object with right properties or an instance of Panel or Painel id
* @return {Panel} Removed panel. Useful in case passed argument was an Object
* @example
* const newPanel = panelManager.removePanel({
* id: 'myNewPanel',
* visible : true,
* buttons : [...],
* });
*
* const newPanel = panelManager.removePanel('myNewPanel');
*
*/
removePanel(panel) {
return panels.remove(panel);
},
/**
* Get panel by ID
* @param {string} id Id string
* @return {Panel|null}
* @example
* var myPanel = panelManager.getPanel('myNewPanel');
*/
getPanel(id) {
var res = panels.where({ id });
return res.length ? res[0] : null;
},
/**
* Add button to the panel
* @param {string} panelId Panel's ID
* @param {Object|Button} button Button object or instance of Button
* @return {Button|null} Added button. Useful in case passed button was an Object
* @example
* var newButton = panelManager.addButton('myNewPanel',{
* id: 'myNewButton',
* className: 'someClass',
* command: 'someCommand',
* attributes: { title: 'Some title'},
* active: false,
* });
* // It's also possible to pass the command as an object
* // with .run and .stop methods
* ...
* command: {
* run: function(editor) {
* ...
* },
* stop: function(editor) {
* ...
* }
* },
* // Or simply like a function which will be evaluated as a single .run command
* ...
* command: function(editor) {
* ...
* }
*/
addButton(panelId, button) {
var pn = this.getPanel(panelId);
return pn ? pn.get('buttons').add(button) : null;
},
/**
* Remove button from the panel
* @param {String} panelId Panel's ID
* @param {String} buttonId Button's ID
* @return {Button|null} Removed button.
* @example
* const removedButton = panelManager.addButton('myNewPanel',{
* id: 'myNewButton',
* className: 'someClass',
* command: 'someCommand',
* attributes: { title: 'Some title'},
* active: false,
* });
*
* const removedButton = panelManager.removeButton('myNewPanel', 'myNewButton');
*
*/
removeButton(panelId, button) {
var pn = this.getPanel(panelId);
return pn && pn.get('buttons').remove(button);
},
/**
* Get button from the panel
* @param {string} panelId Panel's ID
* @param {string} id Button's ID
* @return {Button|null}
* @example
* var button = panelManager.getButton('myPanel','myButton');
*/
getButton(panelId, id) {
var pn = this.getPanel(panelId);
if (pn) {
var res = pn.get('buttons').where({ id });
return res.length ? res[0] : null;
}
return null;
},
/**
* Render panels and buttons
* @return {HTMLElement}
* @private
*/
render() {
PanelsViewObj && PanelsViewObj.remove();
PanelsViewObj = new PanelsView({
collection: panels,
config: c,
});
return PanelsViewObj.render().el;
},
/**
* Active activable buttons
* @private
*/
active() {
this.getPanels().each(p => {
p.get('buttons').each(btn => {
btn.get('active') && btn.trigger('updateActive');
});
});
},
/**
* Disable buttons flagged as disabled
* @private
*/
disableButtons() {
this.getPanels().each(p => {
p.get('buttons').each(btn => {
if (btn.get('disable')) btn.trigger('change:disable');
});
});
},
destroy() {
panels.reset();
panels.stopListening();
PanelsViewObj && PanelsViewObj.remove();
[c, panels, PanelsViewObj].forEach(i => (i = {}));
},
Panel,
};
};

232
src/panels/index.ts

@ -0,0 +1,232 @@
/**
* You can customize the initial state of the module from the editor initialization, by passing the following [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/panels/config/config.js)
* ```js
* const editor = grapesjs.init({
* panels: {
* // options
* }
* })
* ```
*
* Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance
*
* ```js
* const panelManager = editor.Panels;
* ```
*
* * [addPanel](#addpanel)
* * [addButton](#addbutton)
* * [getButton](#getbutton)
* * [getPanel](#getpanel)
* * [getPanels](#getpanels)
* * [getPanelsEl](#getpanelsel)
* * [removePanel](#removepanel)
* * [removeButton](#removebutton)
*
* @module Panels
*/
import { Module } from '../abstract';
import EditorModel from '../editor/model/Editor';
import defaults from './config/config';
import Button from './model/Button';
import Panel from './model/Panel';
import Panels from './model/Panels';
import PanelsView from './view/PanelsView';
export default class PanelManager extends Module<typeof defaults> {
//config = {};
panels: Panels;
PanelsViewObj?: PanelsView;
/**
* Initialize module. Automatically called with a new instance of the editor
* @param {Object} config Configurations
* @private
*/
constructor(em: EditorModel) {
super(em, 'Panels', defaults);
this.panels = new Panels(this, this.config.defaults);
for (var name in defaults) {
//@ts-ignore
if (!(name in this.config)) this.config[name] = defaults[name];
}
return this;
}
/**
* Returns the collection of panels
* @return {Collection} Collection of panel
*/
getPanels() {
return this.panels;
}
/**
* Returns panels element
* @return {HTMLElement}
*/
getPanelsEl() {
return this.PanelsViewObj && this.PanelsViewObj.el;
}
/**
* Add new panel to the collection
* @param {Object|Panel} panel Object with right properties or an instance of Panel
* @return {Panel} Added panel. Useful in case passed argument was an Object
* @example
* var newPanel = panelManager.addPanel({
* id: 'myNewPanel',
* visible : true,
* buttons : [...],
* });
*/
addPanel(panel: Panel | Array<Record<string, any>>) {
return this.panels.add(panel);
}
/**
* Remove a panel from the collection
* @param {Object|Panel|String} panel Object with right properties or an instance of Panel or Painel id
* @return {Panel} Removed panel. Useful in case passed argument was an Object
* @example
* const newPanel = panelManager.removePanel({
* id: 'myNewPanel',
* visible : true,
* buttons : [...],
* });
*
* const newPanel = panelManager.removePanel('myNewPanel');
*
*/
removePanel(panel: Panel) {
return this.panels.remove(panel);
}
/**
* Get panel by ID
* @param {string} id Id string
* @return {Panel|null}
* @example
* var myPanel = panelManager.getPanel('myNewPanel');
*/
getPanel(id: string) {
var res = this.panels.where({ id });
return res.length ? res[0] : null;
}
/**
* Add button to the panel
* @param {string} panelId Panel's ID
* @param {Object|Button} button Button object or instance of Button
* @return {Button|null} Added button. Useful in case passed button was an Object
* @example
* var newButton = panelManager.addButton('myNewPanel',{
* id: 'myNewButton',
* className: 'someClass',
* command: 'someCommand',
* attributes: { title: 'Some title'},
* active: false,
* });
* // It's also possible to pass the command as an object
* // with .run and .stop methods
* ...
* command: {
* run: function(editor) {
* ...
* },
* stop: function(editor) {
* ...
* }
* },
* // Or simply like a function which will be evaluated as a single .run command
* ...
* command: function(editor) {
* ...
* }
*/
addButton(panelId: string, button: any) {
var pn = this.getPanel(panelId);
return pn ? pn.get('buttons').add(button) : null;
}
/**
* Remove button from the panel
* @param {String} panelId Panel's ID
* @param {String} buttonId Button's ID
* @return {Button|null} Removed button.
* @example
* const removedButton = panelManager.addButton('myNewPanel',{
* id: 'myNewButton',
* className: 'someClass',
* command: 'someCommand',
* attributes: { title: 'Some title'},
* active: false,
* });
*
* const removedButton = panelManager.removeButton('myNewPanel', 'myNewButton');
*
*/
removeButton(panelId: string, button: any) {
var pn = this.getPanel(panelId);
return pn && pn.get('buttons').remove(button);
}
/**
* Get button from the panel
* @param {string} panelId Panel's ID
* @param {string} id Button's ID
* @return {Button|null}
* @example
* var button = panelManager.getButton('myPanel','myButton');
*/
getButton(panelId: string, id: string) {
var pn = this.getPanel(panelId);
if (pn) {
var res = pn.get('buttons').where({ id });
return res.length ? res[0] : null;
}
return null;
}
/**
* Render panels and buttons
* @return {HTMLElement}
*/
render() {
this.PanelsViewObj && this.PanelsViewObj.remove();
this.PanelsViewObj = new PanelsView(this.panels);
return this.PanelsViewObj.render().el;
}
/**
* Active activable buttons
* @private
*/
active() {
this.getPanels().each(p => {
//@ts-ignore
p.get('buttons').each(btn => {
btn.get('active') && btn.trigger('updateActive');
});
});
}
/**
* Disable buttons flagged as disabled
* @private
*/
disableButtons() {
this.getPanels().each(p => {
//@ts-ignore
p.get('buttons').each(btn => {
if (btn.get('disable')) btn.trigger('change:disable');
});
});
}
destroy() {
this.panels.reset();
this.panels.stopListening();
this.PanelsViewObj && this.PanelsViewObj.remove();
}
}

30
src/panels/model/Button.js

@ -1,30 +0,0 @@
import { Model } from '../../common';
export default class Button extends Model {
defaults() {
return {
id: '',
label: '',
tagName: 'span',
className: '',
command: '',
context: '',
buttons: [],
attributes: {},
options: {},
active: false,
dragDrop: false,
togglable: true,
runDefaultCommand: true,
stopDefaultCommand: false,
disable: false,
};
}
initialize(options) {
if (this.get('buttons').length) {
var Buttons = require('./Buttons').default;
this.set('buttons', new Buttons(this.get('buttons')));
}
}
}

62
src/panels/model/Button.ts

@ -0,0 +1,62 @@
import PanelManager from '..';
import { Model } from '../../abstract';
import EditorModel from '../../editor/model/Editor';
import Buttons from './Buttons';
export default class Button extends Model<PanelManager> {
defaults() {
return {
id: '',
label: '',
tagName: 'span',
className: '',
command: '',
context: '',
buttons: [],
attributes: {},
options: {},
active: false,
dragDrop: false,
togglable: true,
runDefaultCommand: true,
stopDefaultCommand: false,
disable: false,
};
}
get className(): string {
return this.get('className');
}
get command(): string {
return this.get('command');
}
get active(): boolean {
return this.get('active');
}
set active(isActive: boolean) {
this.set('active', isActive);
}
get togglable(): boolean {
return this.get('togglable');
}
get runDefaultCommand(): boolean {
return this.get('runDefaultCommand');
}
get stopDefaultCommand(): boolean {
return this.get('stopDefaultCommand');
}
get disable(): boolean {
return this.get('disable');
}
constructor(module: PanelManager, options: any) {
super(module, options);
if (this.get('buttons').length) {
this.set('buttons', new Buttons(this.module, this.get('buttons')));
}
}
}

19
src/panels/model/Buttons.js → src/panels/model/Buttons.ts

@ -1,7 +1,11 @@
import { Collection } from '../../common';
import PanelManager from '..';
import { Collection } from '../../abstract';
import Button from './Button';
export default class Buttons extends Collection {
export default class Buttons extends Collection<Button> {
constructor(module: PanelManager, models: Button[]) {
super(module, models, Button);
}
/**
* Deactivate all buttons, except one passed
* @param {Object} except Model to ignore
@ -9,7 +13,7 @@ export default class Buttons extends Collection {
*
* @return void
* */
deactivateAllExceptOne(except, r) {
deactivateAllExceptOne(except: Button, r: boolean) {
this.forEach((model, index) => {
if (model !== except) {
model.set('active', false);
@ -24,11 +28,12 @@ export default class Buttons extends Collection {
*
* @return void
* */
deactivateAll(ctx, sender) {
deactivateAll(ctx?: string, sender?: any) {
const context = ctx || '';
this.forEach(model => {
if (model.get('context') == context && model !== sender) {
model.set('active', false, { fromCollection: 1 });
//@ts-ignore
model.set('active', false, { fromCollection: true });
}
});
}
@ -39,7 +44,7 @@ export default class Buttons extends Collection {
*
* @return void
* */
disableAllButtons(ctx) {
disableAllButtons(ctx?: string) {
var context = ctx || '';
this.forEach((model, index) => {
if (model.get('context') == context) {
@ -55,7 +60,7 @@ export default class Buttons extends Collection {
*
* @return void
* */
disableAllButtonsExceptOne(except, r) {
disableAllButtonsExceptOne(except: Button, r: boolean) {
this.forEach((model, index) => {
if (model !== except) {
model.set('disable', true);

20
src/panels/model/Panel.js

@ -1,20 +0,0 @@
import { Model } from '../../common';
import Buttons from './Buttons';
export default class Panel extends Model {
defaults() {
return {
id: '',
content: '',
visible: true,
buttons: [],
attributes: {},
};
}
initialize(options) {
this.btn = this.get('buttons') || [];
this.buttons = new Buttons(this.btn);
this.set('buttons', this.buttons);
}
}

31
src/panels/model/Panel.ts

@ -0,0 +1,31 @@
import PanelManager from '..';
import { Model } from '../../abstract';
import Buttons from './Buttons';
export default class Panel extends Model<PanelManager> {
defaults() {
return {
id: '',
content: '',
visible: true,
buttons: [],
attributes: {},
};
}
get buttons() {
return this.get('buttons');
}
private set buttons(buttons: Buttons) {
this.set('buttons', buttons);
}
view?: any;
constructor(module: PanelManager, options: any) {
super(module, options);
var btn = this.get('buttons') || [];
this.buttons = new Buttons(module, btn);
}
}

6
src/panels/model/Panels.js

@ -1,6 +0,0 @@
import { Collection } from '../../common';
import Panel from './Panel';
export default class Panels extends Collection {}
Panels.prototype.model = Panel;

11
src/panels/model/Panels.ts

@ -0,0 +1,11 @@
import PanelManager from '..';
import { Collection } from '../../abstract';
import Panel from './Panel';
export default class Panels extends Collection<Panel> {
constructor(module: PanelManager, models: Panel[] | Array<Record<string, any>>) {
super(module, models, Panel);
}
}
Panels.prototype.model = Panel;

70
src/panels/view/ButtonView.js → src/panels/view/ButtonView.ts

@ -1,7 +1,10 @@
import { isString, isObject, isFunction } from 'underscore';
import { View } from '../../common';
import { View } from '../../abstract';
import Button from '../model/Button';
import Buttons from '../model/Buttons';
export default class ButtonView extends View {
export default class ButtonView extends View<Button> {
//@ts-ignore
tagName() {
return this.model.get('tagName');
}
@ -12,18 +15,20 @@ export default class ButtonView extends View {
};
}
initialize(o) {
const { model } = this;
const cls = model.get('className');
commands: any;
activeCls: string;
disableCls: string;
btnsVisCls: string;
//Note: I don't think this is working
$buttons?: any;
constructor(o: any) {
super(o);
const { model, em, pfx, ppfx } = this;
const cls = model.className;
const { command, listen } = model.attributes;
const config = o.config || {};
const { em } = config;
this.config = config;
this.em = em;
const pfx = this.config.stylePrefix || '';
const ppfx = this.config.pStylePrefix || '';
this.pfx = pfx;
this.ppfx = this.config.pStylePrefix || '';
this.id = pfx + model.get('id');
this.activeCls = `${pfx}active ${ppfx}four-color`;
this.disableCls = `${ppfx}disabled`;
@ -38,7 +43,7 @@ export default class ButtonView extends View {
this.listenTo(model, 'change:disable', this.updateDisable);
if (em && isString(command) && listen) {
const chnOpt = { fromListen: 1 };
const chnOpt: any = { fromListen: true };
this.listenTo(em, `run:${command}`, () => model.set('active', true, chnOpt));
this.listenTo(em, `stop:${command}`, () => model.set('active', false, chnOpt));
}
@ -51,9 +56,9 @@ export default class ButtonView extends View {
*
* @return void
* */
updateClassName() {
private updateClassName() {
const { model, pfx } = this;
const cls = model.get('className');
const cls = model.className;
const attrCls = model.get('attributes').class;
const classStr = `${attrCls ? attrCls : ''} ${pfx}btn ${cls ? cls : ''}`;
this.$el.attr('class', classStr.trim());
@ -64,7 +69,7 @@ export default class ButtonView extends View {
*
* @return void
* */
updateAttributes() {
private updateAttributes() {
const { em, model, $el } = this;
const attr = model.get('attributes') || {};
const title = em && em.t && em.t(`panels.buttons.titles.${model.id}`);
@ -79,7 +84,7 @@ export default class ButtonView extends View {
*
* @return void
* */
updateBtnsVis() {
private updateBtnsVis() {
if (!this.$buttons) return;
if (this.model.get('bntsVis')) this.$buttons.addClass(this.btnsVisCls);
@ -91,12 +96,12 @@ export default class ButtonView extends View {
*
* @return void
* */
updateActive(m, v, opts = {}) {
private updateActive(m: any, v: any, opts: any = {}) {
const { model, commands, $el, activeCls } = this;
const { fromCollection, fromListen } = opts;
const context = model.get('context');
const options = model.get('options');
const commandName = model.get('command');
const commandName = model.command;
let command = {};
if (!commandName) return;
@ -109,12 +114,13 @@ export default class ButtonView extends View {
command = commands.create(commandName);
}
if (model.get('active')) {
!fromCollection && model.collection.deactivateAll(context, model);
if (model.active) {
!fromCollection && (model.collection as Buttons)?.deactivateAll(context, model);
model.set('active', true, { silent: true }).trigger('checkActive');
!fromListen && commands.runCommand(command, { ...options, sender: model });
// Disable button if the command has no stop method
//@ts-ignore
command.noStop && model.set('active', false);
} else {
$el.removeClass(activeCls);
@ -124,7 +130,7 @@ export default class ButtonView extends View {
updateDisable() {
const { disableCls, model } = this;
const disable = model.get('disable');
const disable = model.disable;
this.$el[disable ? 'addClass' : 'removeClass'](disableCls);
}
@ -135,7 +141,7 @@ export default class ButtonView extends View {
* */
checkActive() {
const { model, $el, activeCls } = this;
model.get('active') ? $el.addClass(activeCls) : $el.removeClass(activeCls);
model.active ? $el.addClass(activeCls) : $el.removeClass(activeCls);
}
/**
@ -144,31 +150,31 @@ export default class ButtonView extends View {
*
* @return void
* */
clicked(e) {
clicked(e: Event) {
const { model } = this;
if (model.get('bntsVis') || model.get('disable') || !model.get('command')) return;
if (model.get('bntsVis') || model.disable || !model.command) return;
this.toggleActive();
}
toggleActive() {
private toggleActive() {
const { model, em } = this;
const { active, togglable } = model.attributes;
const { active, togglable } = model;
if (active && !togglable) return;
model.set('active', !active);
model.active = !active;
// If the stop is requested
if (active) {
if (model.get('runDefaultCommand')) em.runDefault();
if (model.runDefaultCommand) em.runDefault();
} else {
if (model.get('stopDefaultCommand')) em.stopDefault();
if (model.stopDefaultCommand) em.stopDefault();
}
}
render() {
public render() {
const { model } = this;
const label = model.get('label');
const { $el } = this;

28
src/panels/view/ButtonsView.js → src/panels/view/ButtonsView.ts

@ -1,13 +1,12 @@
import { result } from 'underscore';
import { View } from '../../common';
import { View } from '../../abstract';
import Button from '../model/Button';
import Buttons from '../model/Buttons';
import ButtonView from './ButtonView';
export default class ButtonsView extends View {
initialize(o) {
this.opt = o || {};
this.config = this.opt.config || {};
this.pfx = this.config.stylePrefix || '';
this.parentM = this.opt.parentM || null;
export default class ButtonsView extends View<Buttons> {
constructor(collection: Buttons) {
super({ collection });
this.listenTo(this.collection, 'add', this.addTo);
this.listenTo(this.collection, 'reset remove', this.render);
this.className = this.pfx + 'buttons';
@ -19,7 +18,7 @@ export default class ButtonsView extends View {
*
* @return Object
* */
addTo(model) {
private addTo(model: Button) {
this.addToCollection(model);
}
@ -30,15 +29,12 @@ export default class ButtonsView extends View {
*
* @return Object Object created
* */
addToCollection(model, fragmentEl) {
private addToCollection(model: Button, fragmentEl?: DocumentFragment) {
const fragment = fragmentEl || null;
const viewObject = ButtonView;
const el = model.get('el');
const view = new viewObject({
const view = new ButtonView({
el,
model,
config: this.config,
parentM: this.parentM,
});
const rendered = view.render().el;
@ -51,13 +47,11 @@ export default class ButtonsView extends View {
return rendered;
}
render() {
public render() {
var fragment = document.createDocumentFragment();
this.$el.empty();
this.collection.each(function (model) {
this.addToCollection(model, fragment);
}, this);
this.collection.each(model => this.addToCollection(model, fragment));
this.$el.append(fragment);
this.$el.attr('class', result(this, 'className'));

29
src/panels/view/PanelView.js → src/panels/view/PanelView.ts

@ -1,14 +1,10 @@
import { View } from '../../common';
import { View } from '../../abstract';
import Panel from '../model/Panel';
import ButtonsView from './ButtonsView';
export default class PanelView extends View {
initialize(o) {
const config = o.config || {};
const model = this.model;
this.config = config;
this.pfx = config.stylePrefix || '';
this.ppfx = config.pStylePrefix || '';
this.buttons = model.get('buttons');
export default class PanelView extends View<Panel> {
constructor(model: Panel) {
super({ model, el: model.get('el') });
this.className = this.pfx + 'panel';
this.id = this.pfx + model.get('id');
this.listenTo(model, 'change:appendContent', this.appendContent);
@ -39,12 +35,13 @@ export default class PanelView extends View {
this.$el.removeClass(`${this.ppfx}hidden`);
}
//@ts-ignore
attributes() {
return this.model.get('attributes');
}
initResize() {
const em = this.config.em;
const em = this.em;
const editor = em ? em.get('Editor') : '';
const resizable = this.model.get('resizable');
@ -85,7 +82,7 @@ export default class PanelView extends View {
onEnd() {
em && em.trigger('change:canvasOffset');
},
posFetcher: (el, { target }) => {
posFetcher: (el: HTMLElement, { target }: any) => {
const style = el.style;
const config = resizer.getConfig();
const keyWidth = config.keyWidth;
@ -111,6 +108,7 @@ export default class PanelView extends View {
}
render() {
const { buttons } = this.model;
const $el = this.$el;
const ppfx = this.ppfx;
const cls = `${this.className} ${this.id} ${ppfx}one-bg ${ppfx}two-color`;
@ -118,12 +116,9 @@ export default class PanelView extends View {
this.toggleVisible();
if (this.buttons.length) {
var buttons = new ButtonsView({
collection: this.buttons,
config: this.config,
});
$el.append(buttons.render().el);
if (buttons.length) {
var buttonsView = new ButtonsView(buttons);
$el.append(buttonsView.render().el);
}
$el.append(this.model.get('content'));

33
src/panels/view/PanelsView.js → src/panels/view/PanelsView.ts

@ -1,19 +1,18 @@
import { View } from '../../common';
import { View } from '../../abstract';
import Panel from '../model/Panel';
import Panels from '../model/Panels';
import PanelView from './PanelView';
export default class PanelsView extends View {
initialize(o) {
this.opt = o || {};
this.config = this.opt.config || {};
this.pfx = this.config.stylePrefix || '';
const items = this.collection;
this.listenTo(items, 'add', this.addTo);
this.listenTo(items, 'reset', this.render);
this.listenTo(items, 'remove', this.onRemove);
export default class PanelsView extends View<Panels> {
constructor(target: Panels) {
super({ collection: target });
this.listenTo(target, 'add', this.addTo);
this.listenTo(target, 'reset', this.render);
this.listenTo(target, 'remove', this.onRemove);
this.className = this.pfx + 'panels';
}
onRemove(model) {
private onRemove(model: Panel) {
const view = model.view;
view && view.remove();
}
@ -25,7 +24,7 @@ export default class PanelsView extends View {
* @return Object
* @private
* */
addTo(model) {
private addTo(model: Panel) {
this.addToCollection(model);
}
@ -38,15 +37,11 @@ export default class PanelsView extends View {
* @return Object Object created
* @private
* */
addToCollection(model, fragmentEl) {
private addToCollection(model: Panel, fragmentEl?: DocumentFragment) {
const fragment = fragmentEl || null;
const config = this.config;
const el = model.get('el');
const view = new PanelView({
el,
model,
config,
});
const view = new PanelView(model);
const rendered = view.render().el;
const appendTo = model.get('appendTo');
@ -67,7 +62,7 @@ export default class PanelsView extends View {
return rendered;
}
render() {
public render() {
const $el = this.$el;
const frag = document.createDocumentFragment();
$el.empty();

12
test/specs/panels/index.js

@ -1,11 +1,15 @@
import Panels from 'panels';
import Panel from 'panels/model/Panel';
import Editor from 'editor/model/Editor';
describe('Panels', () => {
describe('Main', () => {
var em;
var obj;
beforeEach(() => {
obj = new Panels().init();
em = new Editor({});
obj = new Panels(em);
});
afterEach(() => {
@ -31,7 +35,7 @@ describe('Panels', () => {
});
test('Adds new panel correctly via Panel instance', () => {
var oPanel = new obj.Panel({ id: 'test' });
var oPanel = new Panel(obj, { id: 'test' });
var panel = obj.addPanel(oPanel);
expect(panel).toEqual(oPanel);
expect(panel.get('id')).toEqual('test');
@ -127,7 +131,7 @@ describe('Panels', () => {
});
test('Removes panel correctly via Panel instance', () => {
var oPanel = new obj.Panel({ id: 'test' });
var oPanel = new Panel(obj, { id: 'test' });
var panel = obj.addPanel(oPanel);
expect(panel).toEqual(oPanel);
expect(panel.get('id')).toEqual('test');
@ -136,7 +140,7 @@ describe('Panels', () => {
});
test('Removes panel correctly via id', () => {
var oPanel = new obj.Panel({ id: 'test' });
var oPanel = new Panel(obj, { id: 'test' });
var panel = obj.addPanel(oPanel);
expect(panel).toEqual(oPanel);
expect(panel.get('id')).toEqual('test');

4
test/specs/panels/model/PanelModels.js

@ -22,7 +22,7 @@ describe('Button', () => {
});
test('Init with other buttons inside correctly', () => {
obj = new Button({
obj = new Button(null, {
buttons: [{}],
});
expect(obj.get('buttons') instanceof Buttons).toEqual(true);
@ -109,7 +109,7 @@ describe('Panel', () => {
});
test('Init with buttons inside correctly', () => {
obj = new Panel({
obj = new Panel(null, {
buttons: [{}],
});
expect(obj.get('buttons') instanceof Buttons).toEqual(true);

11
test/specs/panels/view/ButtonView.js

@ -1,14 +1,17 @@
import ButtonView from 'panels/view/ButtonView';
import Button from 'panels/model/Button';
import Editor from 'editor';
describe('ButtonView', () => {
var fixtures;
var em;
var model;
var view;
var btnClass = 'btn';
var btnClass = 'gjs-pn-btn';
beforeEach(() => {
model = new Button({ command: 'fake-command' });
em = new Editor({});
model = new Button(em.Panels, { command: 'fake-command' });
view = new ButtonView({
model: model,
});
@ -40,7 +43,7 @@ describe('ButtonView', () => {
test('Check enable active', () => {
model.set('active', true, { silent: true });
view.checkActive();
expect(view.el.getAttribute('class')).toContain(btnClass + ' active');
expect(view.el.getAttribute('class')).toContain(btnClass + ' gjs-pn-active');
});
test('Check disable active', () => {
@ -54,7 +57,7 @@ describe('ButtonView', () => {
test('Disable the button', () => {
model.set('disable', true, { silent: true });
view.updateDisable();
expect(view.el.getAttribute('class')).toEqual(btnClass + ' disabled');
expect(view.el.getAttribute('class')).toEqual(btnClass + ' gjs-disabled');
});
test('Enable the disabled button', () => {

9
test/specs/panels/view/ButtonsView.js

@ -1,16 +1,17 @@
import ButtonsView from 'panels/view/ButtonsView';
import Buttons from 'panels/model/Buttons';
import Editor from 'editor';
describe('ButtonsView', () => {
var fixtures;
var em;
var model;
var view;
beforeEach(() => {
model = new Buttons([]);
view = new ButtonsView({
collection: model,
});
em = new Editor({});
model = new Buttons(em.Panels, []);
view = new ButtonsView(model);
document.body.innerHTML = '<div id="fixtures"></div>';
fixtures = document.body.querySelector('#fixtures');
fixtures.appendChild(view.render().el);

21
test/specs/panels/view/PanelView.js

@ -1,16 +1,17 @@
import PanelView from 'panels/view/PanelView';
import Panel from 'panels/model/Panel';
import Editor from 'editor';
describe('PanelView', () => {
var fixtures;
var em;
var model;
var view;
beforeEach(() => {
model = new Panel();
view = new PanelView({
model,
});
em = new Editor();
model = new Panel(em.Panels);
view = new PanelView(model);
document.body.innerHTML = '<div id="fixtures"></div>';
fixtures = document.body.querySelector('#fixtures');
fixtures.appendChild(view.render().el);
@ -38,16 +39,16 @@ describe('PanelView', () => {
});
test('Hide panel', () => {
expect(view.$el.hasClass('hidden')).toBeFalsy();
expect(view.$el.hasClass('gjs-hidden')).toBeFalsy();
model.set('visible', false);
expect(view.$el.hasClass('hidden')).toBeTruthy();
expect(view.$el.hasClass('gjs-hidden')).toBeTruthy();
});
test('Show panel', () => {
model.set('visible', false);
expect(view.$el.hasClass('hidden')).toBeTruthy();
expect(view.$el.hasClass('gjs-hidden')).toBeTruthy();
model.set('visible', true);
expect(view.$el.hasClass('hidden')).toBeFalsy();
expect(view.$el.hasClass('gjs-hidden')).toBeFalsy();
});
describe('Init with options', () => {
@ -55,9 +56,7 @@ describe('PanelView', () => {
model = new Panel({
buttons: [{}],
});
view = new PanelView({
model,
});
view = new PanelView(model);
document.body.innerHTML = '<div id="fixtures"></div>';
fixtures = document.body.querySelector('#fixtures');
fixtures.appendChild(view.render().el);

10
test/specs/panels/view/PanelsView.js

@ -1,17 +1,17 @@
import PanelsView from 'panels/view/PanelsView';
import Panels from 'panels/model/Panels';
import Editor from 'editor';
describe('PanelsView', () => {
var fixtures;
var $fixture;
var em;
var model;
var view;
beforeEach(() => {
model = new Panels([]);
view = new PanelsView({
collection: model,
});
em = new Editor({});
model = new Panels(em.Panels);
view = new PanelsView(model);
document.body.innerHTML = '<div id="fixtures"></div>';
fixtures = document.body.querySelector('#fixtures');
fixtures.appendChild(view.render().el);

6153
yarn.lock

File diff suppressed because it is too large
Loading…
Cancel
Save