mirror of https://github.com/artf/grapesjs.git
Browse Source
* Covert Modal module into class * Convert Modal into ts * Convert rest of the Modal to ts * Update ModalView testpull/4487/head
committed by
GitHub
7 changed files with 300 additions and 323 deletions
@ -1,283 +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/modal_dialog/config/config.js)
|
|
||||
* ```js
|
|
||||
* const editor = grapesjs.init({ |
|
||||
* modal: { |
|
||||
* // 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 modal = editor.Modal; |
|
||||
* ``` |
|
||||
* |
|
||||
* ## Available Events |
|
||||
* * `modal:open` - Modal is opened |
|
||||
* * `modal:close` - Modal is closed |
|
||||
* * `modal` - Event triggered on any change related to the modal. An object containing all the available data about the triggered event is passed as an argument to the callback. |
|
||||
* |
|
||||
* ## Methods |
|
||||
* * [open](#open) |
|
||||
* * [close](#close) |
|
||||
* * [isOpen](#isopen) |
|
||||
* * [setTitle](#settitle) |
|
||||
* * [getTitle](#gettitle) |
|
||||
* * [setContent](#setcontent) |
|
||||
* * [getContent](#getcontent) |
|
||||
* * [onceClose](#onceclose) |
|
||||
* * [onceOpen](#onceopen) |
|
||||
* |
|
||||
* @module Modal |
|
||||
*/ |
|
||||
|
|
||||
import { debounce, isFunction, isString } from 'underscore'; |
|
||||
import { createText } from '../utils/dom'; |
|
||||
import defaults from './config/config'; |
|
||||
import ModalM from './model/Modal'; |
|
||||
import ModalView from './view/ModalView'; |
|
||||
|
|
||||
export default () => { |
|
||||
var c = {}; |
|
||||
var model, modal; |
|
||||
|
|
||||
const triggerEvent = (enable, em) => { |
|
||||
em && em.trigger(`modal:${enable ? 'open' : 'close'}`); |
|
||||
}; |
|
||||
|
|
||||
return { |
|
||||
/** |
|
||||
* Name of the module |
|
||||
* @type {String} |
|
||||
* @private |
|
||||
*/ |
|
||||
name: 'Modal', |
|
||||
|
|
||||
getConfig() { |
|
||||
return c; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* Initialize module. Automatically called with a new instance of the editor |
|
||||
* @param {Object} config Configurations |
|
||||
* @private |
|
||||
*/ |
|
||||
init(config = {}) { |
|
||||
c = { |
|
||||
...defaults, |
|
||||
...config, |
|
||||
}; |
|
||||
|
|
||||
const em = c.em; |
|
||||
this.em = em; |
|
||||
var ppfx = c.pStylePrefix; |
|
||||
if (ppfx) c.stylePrefix = ppfx + c.stylePrefix; |
|
||||
|
|
||||
model = new ModalM(c); |
|
||||
model.on('change:open', (m, enb) => triggerEvent(enb, em)); |
|
||||
model.on( |
|
||||
'change', |
|
||||
debounce(() => { |
|
||||
const data = this._evData(); |
|
||||
const { custom } = this.getConfig(); |
|
||||
isFunction(custom) && custom(data); |
|
||||
em.trigger('modal', data); |
|
||||
}) |
|
||||
); |
|
||||
|
|
||||
return this; |
|
||||
}, |
|
||||
|
|
||||
_evData() { |
|
||||
const titl = this.getTitle(); |
|
||||
const cnt = this.getContent(); |
|
||||
const { open, attributes } = model.attributes; |
|
||||
return { |
|
||||
open, |
|
||||
attributes, |
|
||||
title: isString(titl) ? createText(titl) : titl, |
|
||||
content: isString(cnt) ? createText(cnt) : cnt.get ? cnt.get(0) : cnt, |
|
||||
close: () => this.close(), |
|
||||
}; |
|
||||
}, |
|
||||
|
|
||||
postRender(view) { |
|
||||
const el = view.model.getConfig().el || view.el; |
|
||||
const res = this.render(); |
|
||||
res && res.appendTo(el); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* Open the modal window |
|
||||
* @param {Object} [opts={}] Options |
|
||||
* @param {String|HTMLElement} [opts.title] Title to set for the modal |
|
||||
* @param {String|HTMLElement} [opts.content] Content to set for the modal |
|
||||
* @param {Object} [opts.attributes] Updates the modal wrapper with custom attributes |
|
||||
* @returns {this} |
|
||||
* @example |
|
||||
* modal.open({ |
|
||||
* title: 'My title', |
|
||||
* content: 'My content', |
|
||||
* attributes: { class: 'my-class' }, |
|
||||
* }); |
|
||||
*/ |
|
||||
open(opts = {}) { |
|
||||
const attr = opts.attributes || {}; |
|
||||
opts.title && this.setTitle(opts.title); |
|
||||
opts.content && this.setContent(opts.content); |
|
||||
model.set('attributes', attr); |
|
||||
model.open(); |
|
||||
modal && modal.updateAttr(attr); |
|
||||
return this; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* Close the modal window |
|
||||
* @returns {this} |
|
||||
* @example |
|
||||
* modal.close(); |
|
||||
*/ |
|
||||
close() { |
|
||||
model.close(); |
|
||||
return this; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* Execute callback when the modal will be closed. |
|
||||
* The callback will be called one only time |
|
||||
* @param {Function} clb Callback to call |
|
||||
* @returns {this} |
|
||||
* @example |
|
||||
* modal.onceClose(() => { |
|
||||
* console.log('The modal is closed'); |
|
||||
* }); |
|
||||
*/ |
|
||||
onceClose(clb) { |
|
||||
this.em.once('modal:close', clb); |
|
||||
return this; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* Execute callback when the modal will be opened. |
|
||||
* The callback will be called one only time |
|
||||
* @param {Function} clb Callback to call |
|
||||
* @returns {this} |
|
||||
* @example |
|
||||
* modal.onceOpen(() => { |
|
||||
* console.log('The modal is opened'); |
|
||||
* }); |
|
||||
*/ |
|
||||
onceOpen(clb) { |
|
||||
this.em.once('modal:open', clb); |
|
||||
return this; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* Checks if the modal window is open |
|
||||
* @returns {Boolean} |
|
||||
* @example |
|
||||
* modal.isOpen(); // true | false
|
|
||||
*/ |
|
||||
isOpen() { |
|
||||
return !!model.get('open'); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* Set the title to the modal window |
|
||||
* @param {string | HTMLElement} title Title |
|
||||
* @returns {this} |
|
||||
* @example |
|
||||
* // pass a string
|
|
||||
* modal.setTitle('Some title'); |
|
||||
* // or an HTMLElement
|
|
||||
* const el = document.createElement('div'); |
|
||||
* el.innerText = 'New title'; |
|
||||
* modal.setTitle(el); |
|
||||
*/ |
|
||||
setTitle(title) { |
|
||||
model.set('title', title); |
|
||||
return this; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* Returns the title of the modal window |
|
||||
* @returns {string | HTMLElement} |
|
||||
* @example |
|
||||
* modal.getTitle(); |
|
||||
*/ |
|
||||
getTitle() { |
|
||||
return model.get('title'); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* Set the content of the modal window |
|
||||
* @param {string | HTMLElement} content Content |
|
||||
* @returns {this} |
|
||||
* @example |
|
||||
* // pass a string
|
|
||||
* modal.setContent('Some content'); |
|
||||
* // or an HTMLElement
|
|
||||
* const el = document.createElement('div'); |
|
||||
* el.innerText = 'New content'; |
|
||||
* modal.setContent(el); |
|
||||
*/ |
|
||||
setContent(content) { |
|
||||
model.set('content', ' '); |
|
||||
model.set('content', content); |
|
||||
return this; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* Get the content of the modal window |
|
||||
* @returns {string | HTMLElement} |
|
||||
* @example |
|
||||
* modal.getContent(); |
|
||||
*/ |
|
||||
getContent() { |
|
||||
return model.get('content'); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* Returns content element |
|
||||
* @return {HTMLElement} |
|
||||
* @private |
|
||||
*/ |
|
||||
getContentEl() { |
|
||||
return modal.getContent().get(0); |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* Returns modal model |
|
||||
* @return {Model} |
|
||||
* @private |
|
||||
*/ |
|
||||
getModel() { |
|
||||
return model; |
|
||||
}, |
|
||||
|
|
||||
/** |
|
||||
* Render the modal window |
|
||||
* @return {HTMLElement} |
|
||||
* @private |
|
||||
*/ |
|
||||
render() { |
|
||||
if (this.getConfig().custom) return; |
|
||||
const View = ModalView.extend(c.extend); |
|
||||
const el = modal && modal.el; |
|
||||
modal = new View({ |
|
||||
el, |
|
||||
model, |
|
||||
config: c, |
|
||||
}); |
|
||||
return modal.render().$el; |
|
||||
}, |
|
||||
|
|
||||
destroy() { |
|
||||
modal && modal.remove(); |
|
||||
[c, model, modal].forEach(i => (i = {})); |
|
||||
this.em = {}; |
|
||||
}, |
|
||||
}; |
|
||||
}; |
|
||||
@ -0,0 +1,264 @@ |
|||||
|
/** |
||||
|
* 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/modal_dialog/config/config.js)
|
||||
|
* ```js
|
||||
|
* const editor = grapesjs.init({ |
||||
|
* modal: { |
||||
|
* // 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 modal = editor.Modal; |
||||
|
* ``` |
||||
|
* |
||||
|
* ## Available Events |
||||
|
* * `modal:open` - Modal is opened |
||||
|
* * `modal:close` - Modal is closed |
||||
|
* * `modal` - Event triggered on any change related to the modal. An object containing all the available data about the triggered event is passed as an argument to the callback. |
||||
|
* |
||||
|
* ## Methods |
||||
|
* * [open](#open) |
||||
|
* * [close](#close) |
||||
|
* * [isOpen](#isopen) |
||||
|
* * [setTitle](#settitle) |
||||
|
* * [getTitle](#gettitle) |
||||
|
* * [setContent](#setcontent) |
||||
|
* * [getContent](#getcontent) |
||||
|
* * [onceClose](#onceclose) |
||||
|
* * [onceOpen](#onceopen) |
||||
|
* |
||||
|
* @module Modal |
||||
|
*/ |
||||
|
|
||||
|
import { EventHandler } from 'backbone'; |
||||
|
import { debounce, isFunction, isString } from 'underscore'; |
||||
|
import { Module } from '../abstract'; |
||||
|
import EditorModel from '../editor/model/Editor'; |
||||
|
import { createText } from '../utils/dom'; |
||||
|
import defaults from './config/config'; |
||||
|
import ModalM from './model/Modal'; |
||||
|
import ModalView from './view/ModalView'; |
||||
|
|
||||
|
export default class ModalManager extends Module<typeof defaults> { |
||||
|
modal?: ModalView; |
||||
|
|
||||
|
/** |
||||
|
* Initialize module. Automatically called with a new instance of the editor |
||||
|
* @param {Object} config Configurations |
||||
|
* @private |
||||
|
*/ |
||||
|
constructor(em: EditorModel) { |
||||
|
super(em, 'Modal', defaults); |
||||
|
|
||||
|
this.model = new ModalM(this); |
||||
|
this.model.on('change:open', (enable: boolean) => { |
||||
|
em.trigger(`modal:${enable ? 'open' : 'close'}`); |
||||
|
}); |
||||
|
this.model.on( |
||||
|
'change', |
||||
|
debounce(() => { |
||||
|
const data = this._evData(); |
||||
|
const { custom } = this.config; |
||||
|
//@ts-ignore
|
||||
|
isFunction(custom) && custom(data); |
||||
|
em.trigger('modal', data); |
||||
|
}, 0) |
||||
|
); |
||||
|
|
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
_evData() { |
||||
|
const titl = this.getTitle(); |
||||
|
const cnt = this.getContent(); |
||||
|
const { open, attributes } = this.model.attributes; |
||||
|
return { |
||||
|
open, |
||||
|
attributes, |
||||
|
title: isString(titl) ? createText(titl) : titl, |
||||
|
//@ts-ignore
|
||||
|
content: isString(cnt) ? createText(cnt) : cnt.get ? cnt.get(0) : cnt, |
||||
|
close: () => this.close(), |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
postRender(view: ModalView) { |
||||
|
//@ts-ignore
|
||||
|
const el = view.model.config.el || view.el; |
||||
|
const res = this.render(); |
||||
|
res && res.appendTo(el); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Open the modal window |
||||
|
* @param {Object} [opts={}] Options |
||||
|
* @param {String|HTMLElement} [opts.title] Title to set for the modal |
||||
|
* @param {String|HTMLElement} [opts.content] Content to set for the modal |
||||
|
* @param {Object} [opts.attributes] Updates the modal wrapper with custom attributes |
||||
|
* @returns {this} |
||||
|
* @example |
||||
|
* modal.open({ |
||||
|
* title: 'My title', |
||||
|
* content: 'My content', |
||||
|
* attributes: { class: 'my-class' }, |
||||
|
* }); |
||||
|
*/ |
||||
|
open(opts: any = {}) { |
||||
|
const attr = opts.attributes || {}; |
||||
|
opts.title && this.setTitle(opts.title); |
||||
|
opts.content && this.setContent(opts.content); |
||||
|
this.model.set('attributes', attr); |
||||
|
this.model.open(); |
||||
|
this.modal && this.modal.updateAttr(attr); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Close the modal window |
||||
|
* @returns {this} |
||||
|
* @example |
||||
|
* modal.close(); |
||||
|
*/ |
||||
|
close() { |
||||
|
this.model.close(); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Execute callback when the modal will be closed. |
||||
|
* The callback will be called one only time |
||||
|
* @param {Function} clb Callback to call |
||||
|
* @returns {this} |
||||
|
* @example |
||||
|
* modal.onceClose(() => { |
||||
|
* console.log('The modal is closed'); |
||||
|
* }); |
||||
|
*/ |
||||
|
onceClose(clb: EventHandler) { |
||||
|
this.em.once('modal:close', clb); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Execute callback when the modal will be opened. |
||||
|
* The callback will be called one only time |
||||
|
* @param {Function} clb Callback to call |
||||
|
* @returns {this} |
||||
|
* @example |
||||
|
* modal.onceOpen(() => { |
||||
|
* console.log('The modal is opened'); |
||||
|
* }); |
||||
|
*/ |
||||
|
onceOpen(clb: EventHandler) { |
||||
|
this.em.once('modal:open', clb); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Checks if the modal window is open |
||||
|
* @returns {Boolean} |
||||
|
* @example |
||||
|
* modal.isOpen(); // true | false
|
||||
|
*/ |
||||
|
isOpen() { |
||||
|
return !!this.model.get('open'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set the title to the modal window |
||||
|
* @param {string | HTMLElement} title Title |
||||
|
* @returns {this} |
||||
|
* @example |
||||
|
* // pass a string
|
||||
|
* modal.setTitle('Some title'); |
||||
|
* // or an HTMLElement
|
||||
|
* const el = document.createElement('div'); |
||||
|
* el.innerText = 'New title'; |
||||
|
* modal.setTitle(el); |
||||
|
*/ |
||||
|
setTitle(title: string) { |
||||
|
this.model.set('title', title); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns the title of the modal window |
||||
|
* @returns {string | HTMLElement} |
||||
|
* @example |
||||
|
* modal.getTitle(); |
||||
|
*/ |
||||
|
getTitle() { |
||||
|
return this.model.get('title'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Set the content of the modal window |
||||
|
* @param {string | HTMLElement} content Content |
||||
|
* @returns {this} |
||||
|
* @example |
||||
|
* // pass a string
|
||||
|
* modal.setContent('Some content'); |
||||
|
* // or an HTMLElement
|
||||
|
* const el = document.createElement('div'); |
||||
|
* el.innerText = 'New content'; |
||||
|
* modal.setContent(el); |
||||
|
*/ |
||||
|
setContent(content: string | HTMLElement) { |
||||
|
this.model.set('content', ' '); |
||||
|
this.model.set('content', content); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Get the content of the modal window |
||||
|
* @returns {string | HTMLElement} |
||||
|
* @example |
||||
|
* modal.getContent(); |
||||
|
*/ |
||||
|
getContent(): string | HTMLElement { |
||||
|
return this.model.get('content'); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns content element |
||||
|
* @return {HTMLElement} |
||||
|
* @private |
||||
|
*/ |
||||
|
getContentEl() { |
||||
|
//@ts-ignore
|
||||
|
return this.modal?.getContent().get(0); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Returns modal model |
||||
|
* @return {Model} |
||||
|
* @private |
||||
|
*/ |
||||
|
getModel() { |
||||
|
return this.model; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* Render the modal window |
||||
|
* @return {HTMLElement} |
||||
|
* @private |
||||
|
*/ |
||||
|
render() { |
||||
|
if (this.config.custom) return; |
||||
|
const View = ModalView.extend(this.config.extend); |
||||
|
const el = this.modal && this.modal.el; |
||||
|
this.modal = new View({ |
||||
|
el, |
||||
|
model: this.model, |
||||
|
config: this.config, |
||||
|
}); |
||||
|
return this.modal?.render().$el; |
||||
|
} |
||||
|
|
||||
|
destroy() { |
||||
|
this.modal?.remove(); |
||||
|
} |
||||
|
} |
||||
@ -1,6 +1,7 @@ |
|||||
import { Model } from '../../common'; |
import ModalManager from '..'; |
||||
|
import { Model } from '../../abstract'; |
||||
|
|
||||
export default class Modal extends Model { |
export default class Modal extends Model<ModalManager> { |
||||
defaults() { |
defaults() { |
||||
return { |
return { |
||||
title: '', |
title: '', |
||||
Loading…
Reference in new issue