UNPKG

grapesjs-clot

Version:

Free and Open Source Web Builder Framework

234 lines (210 loc) 6.84 kB
/** * 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/device_manager/config/config.js) * ```js * const editor = grapesjs.init({ * deviceManager: { * // 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 deviceManager = editor.Devices; * ``` * ## Available Events * * `device:add` - Added new device. The [Device] is passed as an argument to the callback * * `device:remove` - Device removed. The [Device] is passed as an argument to the callback * * `device:select` - New device selected. The newly selected [Device] and the previous one, are passed as arguments to the callback * * `device:update` - Device updated. The updated [Device] and the object containing changes are passed as arguments to the callback * * `device` - Catch-all event for all the events mentioned above. An object containing all the available data about the triggered event is passed as an argument to the callback * * ## Methods * * [add](#add) * * [get](#get) * * [getDevices](#getdevices) * * [remove](#remove) * * [select](#select) * * [getSelected](#getselected) * * [Device]: device.html * * @module Devices */ import { isString } from 'underscore'; import Module from 'common/module'; import defaults from './config/config'; import Device from './model/Device'; import Devices from './model/Devices'; import DevicesView from './view/DevicesView'; export const evAll = 'device'; export const evPfx = `${evAll}:`; export const evSelect = `${evPfx}select`; export const evSelectBefore = `${evSelect}:before`; export const evUpdate = `${evPfx}update`; export const evAdd = `${evPfx}add`; export const evAddBefore = `${evAdd}:before`; export const evRemove = `${evPfx}remove`; export const evRemoveBefore = `${evRemove}:before`; const chnSel = 'change:device'; export default () => { let c = {}; let devices; let view; return { ...Module, name: 'DeviceManager', Device, Devices, events: { all: evAll, select: evSelect, // selectBefore: evSelectBefore, update: evUpdate, add: evAdd, // addBefore: evAddBefore, remove: evRemove, removeBefore: evRemoveBefore }, init(config = {}) { c = { ...defaults, ...config }; const { em } = c; devices = new Devices(); c.devices.forEach(dv => this.add(dv)); this.em = em; this.all = devices; this.select(c.default || devices.at(0)); this.__initListen(); em.on(chnSel, this._onSelect, this); return this; }, _onSelect(m, deviceId, opts) { const { em, events } = this; const prevId = m.previous('device'); const newDevice = this.get(deviceId); const ev = events.select; em.trigger(ev, newDevice, this.get(prevId)); this.__catchAllEvent(ev, newDevice, opts); }, /** * Add new device * @param {Object} props Device properties * @returns {[Device]} Added device * @example * const device1 = deviceManager.add({ * // Without an explicit ID, the `name` will be taken. In case of missing `name`, a random ID will be created. * id: 'tablet', * name: 'Tablet', * width: '900px', // This width will be applied on the canvas frame and for the CSS media * }); * const device2 = deviceManager.add({ * id: 'tablet2', * name: 'Tablet 2', * width: '800px', // This width will be applied on the canvas frame * widthMedia: '810px', // This width that will be used for the CSS media * height: '600px', // Height will be applied on the canvas frame * }); */ add(props, options = {}) { let result; let opts = options; // Support old API if (isString(props)) { const width = options; opts = arguments[2] || {}; result = { ...opts, id: props, name: opts.name || props, width }; } else { result = props; } if (!result.id) { result.id = result.name || this._createId(); } return devices.add(result, opts); }, /** * Return device by ID * @param {String} id ID of the device * @returns {[Device]|null} * @example * const device = deviceManager.get('Tablet'); * console.log(JSON.stringify(device)); * // {name: 'Tablet', width: '900px'} */ get(id) { // Support old API const byName = this.getAll().filter(d => d.get('name') === id)[0]; return byName || devices.get(id) || null; }, /** * Remove device * @param {String|[Device]} device Device or device id * @returns {[Device]} Removed device * @example * const removed = deviceManager.remove('device-id'); * // or by passing the Device * const device = deviceManager.get('device-id'); * deviceManager.remove(device); */ remove(device, opts = {}) { return this.__remove(device, opts); }, /** * Return all devices * @returns {Array<[Device]>} * @example * const devices = deviceManager.getDevices(); * console.log(JSON.stringify(devices)); * // [{name: 'Desktop', width: ''}, ...] */ getDevices() { return devices.models; }, /** * Change the selected device. This will update the frame in the canvas * @param {String|[Device]} device Device or device id * @example * deviceManager.select('some-id'); * // or by passing the page * const device = deviceManager.get('some-id'); * deviceManager.select(device); */ select(device, opts = {}) { const md = isString(device) ? this.get(device) : device; md && this.em.set('device', md.get('id'), opts); return this; }, /** * Get the selected device * @returns {[Device]} * @example * const selected = deviceManager.getSelected(); */ getSelected() { return this.get(this.em.get('device')); }, getAll() { return devices; }, render() { view && view.remove(); view = new DevicesView({ collection: devices, config: c }); return view.render().el; }, destroy() { devices.stopListening(); devices.reset(); view && view.remove(); [devices, view].forEach(i => (i = null)); c = {}; } }; };