UNPKG

grapesjs_codeapps

Version:

Free and Open Source Web Builder Framework/SC Modification

241 lines (217 loc) 6.32 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/block_manager/config/config.js) * ```js * const editor = grapesjs.init({ * blockManager: { * // 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 blockManager = editor.BlockManager; * ``` * * [add](#add) * * [get](#get) * * [getAll](#getall) * * [getAllVisible](#getallvisible) * * [remove](#remove) * * [getConfig](#getconfig) * * [getCategories](#getcategories) * * [getContainer](#getcontainer) * * [render](#render) * * @module BlockManager */ import { isElement } from 'underscore'; module.exports = () => { var c = {}, defaults = require('./config/config'), Blocks = require('./model/Blocks'), BlockCategories = require('./model/Categories'), BlocksView = require('./view/BlocksView'); var blocks, blocksVisible, blocksView; var categories = []; return { /** * Name of the module * @type {String} * @private */ name: 'BlockManager', /** * Initialize module. Automatically called with a new instance of the editor * @param {Object} config Configurations * @return {this} * @private */ init(config) { c = config || {}; const em = c.em; for (let name in defaults) { if (!(name in c)) { c[name] = defaults[name]; } } // Global blocks collection blocks = new Blocks([]); blocksVisible = new Blocks([]); (categories = new BlockCategories()), (blocksView = new BlocksView( { // Visible collection collection: blocksVisible, categories }, c )); // Setup the sync between the global and public collections blocks.listenTo(blocks, 'add', model => { blocksVisible.add(model); em && em.trigger('block:add', model); }); blocks.listenTo(blocks, 'remove', model => { blocksVisible.remove(model); em && em.trigger('block:remove', model); }); blocks.listenTo(blocks, 'reset', coll => { blocksVisible.reset(coll.models); }); return this; }, /** * Get configuration object * @return {Object} */ getConfig() { return c; }, /** * Load default blocks if the collection is empty */ onLoad() { const blocks = this.getAll(); !blocks.length && blocks.reset(c.blocks); }, postRender() { const elTo = this.getConfig().appendTo; if (elTo) { const el = isElement(elTo) ? elTo : document.querySelector(elTo); el.appendChild(this.render()); } }, /** * Add new block to the collection. * @param {string} id Block id * @param {Object} opts Options * @param {string} opts.label Name of the block * @param {string} opts.content HTML content * @param {string|Object} opts.category Group the block inside a catgegory. * You should pass objects with id property, eg: * {id: 'some-uid', label: 'My category'} * The string will be converted in: * 'someid' => {id: 'someid', label: 'someid'} * @param {Object} [opts.attributes={}] Block attributes * @return {Block} Added block * @example * blockManager.add('h1-block', { * label: 'Heading', * content: '<h1>Put your title here</h1>', * category: 'Basic', * attributes: { * title: 'Insert h1 block' * } * }); */ add(id, opts) { var obj = opts || {}; obj.id = id; return blocks.add(obj); }, /** * Return the block by id * @param {string} id Block id * @example * const block = blockManager.get('h1-block'); * console.log(JSON.stringify(block)); * // {label: 'Heading', content: '<h1>Put your ...', ...} */ get(id) { return blocks.get(id); }, /** * Return all blocks * @return {Collection} * @example * const blocks = blockManager.getAll(); * console.log(JSON.stringify(blocks)); * // [{label: 'Heading', content: '<h1>Put your ...'}, ...] */ getAll() { return blocks; }, /** * Return the visible collection, which containes blocks actually rendered * @return {Collection} */ getAllVisible() { return blocksVisible; }, /** * Remove a block by id * @param {string} id Block id * @return {Block} Removed block */ remove(id) { return blocks.remove(id); }, /** * Get all available categories. * It's possible to add categories only within blocks via 'add()' method * @return {Array|Collection} */ getCategories() { return categories; }, /** * Return the Blocks container element * @return {HTMLElement} */ getContainer() { return blocksView.el; }, /** * Render blocks * @param {Array} blocks Blocks to render, without the argument will render * all global blocks * @return {HTMLElement} Rendered element * @example * // Render all blocks (inside the global collection) * blockManager.render(); * * // Render new set of blocks * const blocks = blockManager.getAll(); * blockManager.render(blocks.filter( * block => block.get('category') == 'sections' * )); * // Or a new set from an array * blockManager.render([ * {label: 'Label text', content: '<div>Content</div>'} * ]); * * // Back to blocks from the global collection * blockManager.render(); */ render(blocks) { const toRender = blocks || this.getAll().models; if (!blocksView.rendered) { blocksView.render(); blocksView.rendered = 1; } blocksView.collection.reset(toRender); return this.getContainer(); } }; };