From 0f88854daa63609c3589f4e0c0764c35cd2c8d2b Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Thu, 24 Feb 2022 13:39:37 +0100 Subject: [PATCH] Add index.d.ts --- index.d.ts | 5288 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 5288 insertions(+) create mode 100644 index.d.ts diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 000000000..45a714640 --- /dev/null +++ b/index.d.ts @@ -0,0 +1,5288 @@ +declare namespace Backbone { + interface ModelProperties {} + + class Model { + constructor(attr?:T, opt?:any) + attributes : T + collection: Collection + cid: string + get(prop:K) : T[K] + set(prop:K , val:T[K]) : void + defaults() : T + on(eventName: string, callback: (...args: any[]) => void) + toJSON(options?: any): any + } + + class Collection> { + models: TModel[]; + length: number; + + add(model: {} | TModel): TModel; + add(models: Array<{} | TModel>): TModel[]; + find(iterator: (item : TModel) => boolean, context?: any): TModel; + remove(model: {} | TModel): TModel; + remove(models: Array<{} | TModel>): TModel[]; + reset(models?: Array<{} | TModel>): TModel[]; + } + + interface GenericModel extends Model<{}> {} + } + + declare module grapesjs { + interface EditorConfig { + /** Selector which indicates where render the editor */ + container?: string | HTMLElement + + /** If true, auto-render the content */ + autorender? : boolean + + /** Array of plugins to execute on start */ + plugins? : [] + + /** Custom options for plugins */ + pluginsOpts?: Record + + /** Init headless editor */ + headless?: boolean + + /** Style prefix */ + stylePrefix?: string + + /** HTML string or object of components */ + components?: string, + + /** CSS string or object of rules */ + style?: string, + + /** If true, will fetch HTML and CSS from selected container */ + fromElement?: boolean, + + /** Show an alert before unload the page with unsaved changes */ + noticeOnUnload?: number, + + /** Show paddings and margins */ + showOffsets?: boolean, + + /** Show paddings and margins on selected component */ + showOffsetsSelected?: boolean, + + /** On creation of a new Component (via object), if the 'style' attribute is not + * empty, all those roles will be moved in its new class */ + forceClass?: boolean, + + /** Height for the editor container */ + height?: string, + + /** Width for the editor container */ + width?: string, + + /** Type of logs to print with the logger (by default is used the devtool console). + * Available by default: debug, info, warning, error + * You can use `false` to disable all of them or `true` to print all of them */ + log?: ('debug'|'info'|'warning'|'error')[] + + /** By default Grapes injects base CSS into the canvas. For example, it sets body margin to 0 + * and sets a default background color of white. This CSS is desired in most cases. + * use this property if you wish to overwrite the base CSS to your own CSS. This is most + * useful if for example your template is not based off a document with 0 as body margin. */ + baseCss?: string, + + /** CSS that could only be seen (for instance, inside the code viewer) */ + protectedCss?: string, + + /** CSS for the iframe which containing the canvas, useful if you need to custom something inside + * (eg. the style of the selected component) */ + canvasCss?: string, + + /** Default command */ + defaultCommand?: string, + + /** Show a toolbar when the component is selected */ + showToolbar?: boolean, + + // Allow script tag importing + // @deprecated in favor of `config.parser.optionsHtml.allowScripts` + // allowScripts: 0, + + /** If true render a select of available devices */ + showDevices?: boolean, + + /** When enabled, on device change media rules won't be created */ + devicePreviewMode?: boolean, + + /** The condition to use for media queries, eg. 'max-width' + * Comes handy for mobile-first cases */ + mediaCondition?: string, + + /** Starting tag for variable inside scripts in Components */ + tagVarStart?: string, + + /** Ending tag for variable inside scripts in Components */ + tagVarEnd?: string, + + /** When false, removes empty text nodes when parsed, unless they contain a space */ + keepEmptyTextNodes?: boolean, + + /** Return JS of components inside HTML from 'editor.getHtml()' */ + jsInHtml?: boolean, + + /** Enable native HTML5 drag and drop */ + nativeDnD?: boolean, + + /** Enable multiple selection */ + multipleSelection?: boolean, + + /** Show the wrapper component in the final code, eg. in editor.getHtml() */ + exportWrapper?: boolean, + + /** The wrapper, if visible, will be shown as a `` */ + wrapperIsBody?: boolean, + + /** Pass default available options wherever `editor.getHtml()` is called */ + optsHtml?: Record, + + /** Pass default available options wherever `editor.getCss()` is called */ + optsCss?: Record, + + /** Usually when you update the `style` of the component this changes the + * element's `style` attribute. Unfortunately, inline styling doesn't allow + * use of media queries (@media) or even pseudo selectors (eg. :hover). + * When `avoidInlineStyle` is true all styles are inserted inside the css rule + * @deprecated Don't use this option, we don't support inline styling anymore */ + avoidInlineStyle?: boolean, + + /** Avoid default properties from storable JSON data, like `components` and `styles`. + * With this option enabled your data will be smaller (usefull if need to + * save some storage space) */ + avoidDefaults?: boolean, + + /** (experimental) + * The structure of components is always on the screen but it's not the same + * for style rules. When you delete a component you might leave a lot of styles + * which will never be used again, therefore they might be removed. + * With this option set to true, styles not used from the CSS generator (so in + * any case where `CssGenerator.build` is used) will be removed automatically. + * But be careful, not always leaving the style not used mean you wouldn't + * use it later, but this option comes really handy when deal with big templates. */ + clearStyles?: boolean, + + /** Specify the global drag mode of components. By default, components are moved + * following the HTML flow. Two other options are available: + * 'absolute' - Move components absolutely (design tools way) + * 'translate' - Use translate CSS from transform property + * To get more about this feature read: https://github.com/artf/grapesjs/issues/1936 */ + dragMode?: boolean, + + /** When the editor is placed in a scrollable container (eg. modals) this might + * cause elements inside the canvas (eg. floating toolbars) to be misaligned. + * To avoid that, you can specify an array of DOM elements on which their scroll will + * trigger the canvas update. + * Be default, if the array is empty, the first parent element will be appended. + * listenToEl: [document.querySelector('#scrollable-el')], */ + listenToEl?: HTMLElement[], + + /** Import asynchronously CSS to use as icons */ + cssIcons?: string, + + /** Dom element */ + el?: string, + + /** Configurations for I18n */ + i18n?: Record, + + /** Configurations for Undo Manager */ + undoManager?: Record | boolean, + + /** Configurations for Asset Manager */ + assetManager?: AssetManagerConfig | boolean, + + /** Configurations for Canvas */ + canvas?: CanvasConfig | boolean, + + /** Configurations for Layers */ + layers?: Record | boolean, + + /** Configurations for Storage Manager */ + storageManager?: StorageManagerConfig | boolean, + + /** Configurations for Rich Text Editor */ + richTextEditor?: RichTextEditorConfig | boolean, + + /** Configurations for DomComponents */ + domComponents?: DomComponentsConfig | boolean, + + /** Configurations for Modal Dialog */ + modal?: ModalConfig | boolean, + + /** Configurations for Code Manager */ + codeManager?: CodeManagerConfig | boolean, + + /** Configurations for Panels */ + panels?: PanelsConfig | boolean, + + /** Configurations for Commands */ + commands?: CommandsConfig | boolean, + + /** Configurations for Css Composer */ + cssComposer?: CssComposerConfig | boolean, + + /** Configurations for Selector Manager */ + selectorManager?: SelectorManagerConfig | boolean, + + /** Configurations for Device Manager */ + deviceManager?: DeviceManagerConfig | boolean, + + /** Configurations for Style Manager */ + styleManager?: StyleManagerConfig | boolean, + + /** Configurations for Block Manager */ + blockManager?: BlockManagerConfig | boolean, + + /** Configurations for Trait Manager */ + traitManager?: TraitManagerConfig | boolean, + + /** Texts **/ + textViewCode?: string, + + /** Keep unused styles within the editor **/ + keepUnusedStyles?: 0, + } + + interface AssetManagerConfig { + assets?: Array; + noAssets?: string; + stylePrefix?: string; + upload?: boolean; + uploadName?: string; + headers?: object; + params?: object; + credentials?: RequestCredentials; + multiUpload?: boolean; + autoAdd?: boolean; + uploadText?: string; + addBtnText?: string; + customFetch?: Function; + uploadFile?: Function; + embedAsBase64?: boolean; + handleAdd?: Function; + dropzone?: boolean; + openAssetsOnDrop?: number; + dropzoneContent?: string; + modalTitle?: string; + inputPlaceholder?: string; + } + + interface CanvasConfig { + stylePrefix?: string; + scripts?: Array; + styles?: Array; + customBadgeLabel?: Function; + autoscrollLimit?: number; + notTextable?: Array; + } + + interface StyleManagerConfig { + stylePrefix?: string; + sectors?: Array; + appendTo?: HTMLElement | string; + textNoElement?: string; + hideNotStylable?: boolean; + highlightChanged?: boolean; + highlightComputed?: boolean; + showComputed?: boolean; + clearProperties?: boolean; + avoidComputed?: Array; + } + + interface BlockManagerConfig { + appendTo?: HTMLElement | string; + blocks: Array; + } + + interface RichTextEditorConfig { + stylePrefix?: string; + adjustToolbar?: boolean; + actions?: Array; + } + + interface TraitManagerConfig { + stylePrefix?: string; + appendTo?: HTMLElement | string; + labelContainer?: string; + labelPlhText?: string; + labelPlhRef?: string; + optionsTarget?: Array; + textNoElement?: string; + } + + interface StorageManagerConfig { + id?: string; + autosave?: boolean; + autoload?: boolean; + type?: "local" | "remote"; + stepsBeforeSave?: number; + storeComponents?: boolean; + storeStyles?: boolean; + storeHtml?: boolean; + storeCss?: boolean; + checkLocal?: boolean; + params?: object; + headers?: object; + urlStore?: string; + urlLoad?: string; + contentTypeJson?: boolean; + credentials?: RequestCredentials; + + beforeSend(jqXHR: any, settings: object): void; + onComplete(jqXHR: any, status: any): void; + } + + interface DomComponentsConfig { + stylePrefix?: string; + wrapperId?: string; + wrapperName?: string; + wrapper?: DomComponentsWrapperConfig; + components?: Array; + imageCompClass?: string; + oAssetsOnCreate?: boolean; + storeWrapper?: boolean; + voidElements?: Array; + } + + interface DomComponentsWrapperConfig { + removable?: boolean, + copyable?: boolean, + draggable?: boolean, + // TODO: Type custom blocks and components + components?: Array, + traits?: Array, + stylable?: Array + } + + interface ModalConfig { + stylePrefix?: string; + title?: string; + content?: string; + backdrop?: boolean; + } + + interface CodeManagerConfig { + stylePrefix?: string; + inlineCss?: boolean; + } + + interface PanelsConfig { + stylePrefix?: string; + defaults?: Array; + em?: object; + delayBtnsShow?: number; + } + + interface CommandsConfig { + ESCAPE_KEY?: number; + stylePrefix?: string; + defaults?: Array; + em?: object; + firstCentered?: boolean; + newFixedH?: boolean; + minComponentH?: number; + minComponentW?: number; + } + + interface CssComposerConfig { + stylePrefix?: string; + staticRules?: string; + rules?: Array; + } + + interface SelectorManagerConfig { + stylePrefix?: string; + appendTo?: HTMLElement | string; + selectors?: Array; + label?: string; + statesLabel?: string; + selectedLabel?: string; + states?: Array; + } + + interface DeviceManagerConfig { + devices?: Array; + deviceLabel?: string; + } + + function init(config : EditorConfig) : Editor; + + interface Trait extends Backbone.Model { + target : Component + + /** Return all the properties */ + props() : TraitOptions; + targetUpdated() : void; + getValue(): string; + getTargetValue(): string; + setTargetValue(value: any, opts: object) : void + setValueFromInput(value : any, final: boolean, opts: object) : void + /** + * Get the initial value of the trait + */ + getInitValue() : string + } + + type TraitType = 'text' + | 'number' + | 'checkbox' + | 'select' + | string + + interface TraitOptions { + type: TraitType; + label: string, + name: string, + min?: string, + max?: string, + unit?: string, + step?: number, + value?: string, + target?: Component, + default?: string, + placeholder?: string, + changeProp?: number, + options?: SelectOption[] + [key: string]: any + } + + interface PanelOptions { + id: string, + content: string, + visible: boolean, + buttons: Button[], + } + + interface Panel extends Backbone.Model { + + } + + interface Button extends Backbone.Model { + + } + + interface ButtonOptions { + id: string, + label: string, + tagName: 'span', + className: string, + command: string | ((editor : Editor, opts? : any) => void), + context: string, + buttons: any[], + attributes: object, + options: object, + active: boolean, + dragDrop: boolean, + togglable: boolean, + runDefaultCommand: boolean, + stopDefaultCommand: boolean, + disable: boolean + } + + interface ComponentView { + model : Component + + onRender(opts: { + editor?: Editor, + model? : Component, + el? : HTMLElement + }) : void; + } + + interface View {} + + interface LayerManager { + /** + * Set new root for layers + * @param el Component to be set as the root + */ + setRoot(el : HTMLElement|Component|String) : this + /** Get the root of layers */ + getRoot() : Component + /** Return the view of layers */ + getAll() : View + } + + interface TraitView { + noLabel?: boolean + templateInput?: string | ((options: { + trait : Trait + }) => string) + eventCapture? : string[] + + onEvent? : (options: { + elInput : HTMLElement, + component : Component, + event : any + }) => void + onUpdate? : (options: { + elInput : HTMLElement, + component : Component + }) => void + createInput? : (options: { + trait : Trait + }) => HTMLElement + createLabel?: (options: { + label : string + }) => string + } + + interface TraitManager { + /** + * Add new trait type + * @param name Type name + * @param methods Object representing the trait + */ + addType(name : string, trait : TraitView) : void + /** + * Get trait type + * @param name Type name + */ + getType(name : string) : Object + /** + * Get all trait types + */ + getTypes() : Object + } + + /** + * Editor contains the top level API which you'll probably use to customize the editor or extend it with plugins. + * You get the Editor instance on init method and you can pass options via its [Configuration Object](https://github.com/artf/grapesjs/blob/master/src/editor/config/config.js) + * + * ```js + * const editor = grapesjs.init({ + * // options + * }); + * ``` + * + * ## Available Events + * + * You can make use of available events in this way + * ```js + * editor.on('EVENT-NAME', (some, argument) => { + * // do something + * }) + * ``` + * + * * `update` - The structure of the template is updated (its HTML/CSS) + * * `undo` - Undo executed + * * `redo` - Redo executed + * * `load` - Editor is loaded + * + * ### Components + * Check the [Components](/api/components.html) module. + * ### Keymaps + * Check the [Keymaps](/api/keymaps.html) module. + * ### Style Manager + * Check the [Style Manager](/api/style_manager.html) module. + * ### Storage + * Check the [Storage](/api/storage_manager.html) module. + * ### Canvas + * Check the [Canvas](/api/canvas.html) module. + * ### RTE + * Check the [Rich Text Editor](/api/rich_text_editor.html) module. + * ### Commands + * Check the [Commands](/api/commands.html) module. + * ### Selectors + * Check the [Selectors](/api/selector_manager.html) module. + * ### Blocks + * Check the [Blocks](/api/block_manager.html) module. + * ### Assets + * Check the [Assets](/api/assets.html) module. + * ### Modal + * Check the [Modal](/api/modal_dialog.html) module. + * ### Devices + * Check the [Devices](/api/device_manager.html) module. + * ### Parser + * Check the [Parser](/api/parser.html) module. + * ### Pages + * Check the [Pages](/api/pages.html) module. + * + * ## Methods + */ + interface Editor { + DomComponents: Components; + LayerManager: LayerManager; + CssComposer: CssComposer; + StorageManager: StorageManager; + AssetManager: AssetManager; + BlockManager: BlockManager; + TraitManager: TraitManager; + SelectorManager: SelectorManager; + CodeManager: object; + Commands: Commands; + Keymaps: Keymaps; + Modal: Modal; + Panels: Panels; + StyleManager: StyleManager; + Canvas: Canvas; + UndoManager: UndoManager; + DeviceManager: object; + RichTextEditor: RichTextEditor; + Parser: Parser; + Utils: object; + Config: EditorConfig | object; + + /** + * Returns configuration object + * @param [prop] - Property name + * @returns Returns the configuration object or + * the value of the specified property + */ + getConfig(prop?: string): EditorConfig | object; + /** + * Returns HTML built inside canvas + * @param [opts = {}] - Options + * @param [opts.component] - Return the HTML of a specific Component + * @param [opts.cleanId = false] - Remove unnecessary IDs (eg. those created automatically) + * @returns HTML string + */ + getHtml(opts?: { + component?: Component; + cleanId?: boolean; + }): string; + /** + * Returns CSS built inside canvas + * @param [opts = {}] - Options + * @param [opts.component] - Return the CSS of a specific Component + * @param [opts.json = false] - Return an array of CssRules instead of the CSS string + * @param [opts.avoidProtected = false] - Don't include protected CSS + * @param [opts.onlyMatched = false] - Return only rules matched by the passed component. + * @returns CSS string or array of CssRules + */ + getCss(opts?: { + component?: Component; + json?: boolean; + avoidProtected?: boolean; + onlyMatched?: boolean; + }): string | CssRule[]; + /** + * Returns JS of all components + * @param [opts = {}] - Options + * @param [opts.component] - Get the JS of a specific component + * @returns JS string + */ + getJs(opts?: { + component?: Component; + }): string; + /** + * Return the complete tree of components. Use `getWrapper` to include also the wrapper + */ + getComponents(): Components; + /** + * Return the wrapper and its all components + */ + getWrapper(): Component; + /** + * Set components inside editor's canvas. This method overrides actual components + * @example + * editor.setComponents('
New component
'); + * // or + * editor.setComponents({ + * type: 'text', + * classes:['cls'], + * content: 'New component' + * }); + * @param components - HTML string or components model + * @param opt - the options object to be used by the [setComponents]{@link em#setComponents} method + */ + setComponents(components: object[] | any | string, opt: any): any; + /** + * Add components + * @example + * editor.addComponents('
New component
'); + * // or + * editor.addComponents({ + * type: 'text', + * classes:['cls'], + * content: 'New component' + * }); + * @param components - HTML string or components model + * @param opts - Options + * @param [opts.avoidUpdateStyle = false] - If the HTML string contains styles, + * by default, they will be created and, if already exist, updated. When this option + * is true, styles already created will not be updated. + */ + addComponents(components: object[] | any | string, opts: { + avoidUpdateStyle?: boolean; + }): Component[]; + /** + * Returns style in JSON format object + */ + getStyle(): any; + /** + * Set style inside editor's canvas. This method overrides actual style + * @example + * editor.setStyle('.cls{color: red}'); + * //or + * editor.setStyle({ + * selectors: ['cls'], + * style: { color: 'red' } + * }); + * @param style - CSS string or style model + */ + setStyle(style: object[] | any | string): Editor; + /** + * Add styles to the editor + * @example + * editor.addStyle('.cls{color: red}'); + * @param style - CSS string or style model + * @returns Array of created CssRule instances + */ + addStyle(style: object[] | any | string): CssRule[]; + /** + * Returns the last selected component, if there is one + */ + getSelected(): Component | null; + /** + * Returns an array of all selected components + */ + getSelectedAll(): Component[]; + /** + * Get a stylable entity from the selected component. + * If you select a component without classes the entity is the Component + * itself and all changes will go inside its 'style' attribute. Otherwise, + * if the selected component has one or more classes, the function will + * return the corresponding CSS Rule + */ + getSelectedToStyle(): Component; // TODO: | CSSRule + /** + * Select a component + * @example + * // Select dropped block + * editor.on('block:drag:stop', function(model) { + * editor.select(model); + * }); + * @param el - Component to select + * @param [opts] - Options + * @param [opts.scroll] - Scroll canvas to the selected element + */ + select(el: Component | HTMLElement, opts?: { + scroll?: boolean; + }): Editor; + /** + * Add component to selection + * @example + * editor.selectAdd(model); + * @param el - Component to select + */ + selectAdd(el: Component | HTMLElement | any[]): Editor; + /** + * Remove component from selection + * @example + * editor.selectRemove(model); + * @param el - Component to select + */ + selectRemove(el: Component | HTMLElement | any[]): Editor; + /** + * Toggle component selection + * @example + * editor.selectToggle(model); + * @param el - Component to select + */ + selectToggle(el: Component | HTMLElement | any[]): Editor; + /** + * Returns, if active, the Component enabled in rich text editing mode. + * @example + * const textComp = editor.getEditing(); + * if (textComp) { + * console.log('HTML: ', textComp.toHTML()); + * } + */ + getEditing(): Component | null; + /** + * Set device to the editor. If the device exists it will + * change the canvas to the proper width + * @example + * editor.setDevice('Tablet'); + * @param name - Name of the device + */ + setDevice(name: string): Editor; + /** + * Return the actual active device + * @example + * var device = editor.getDevice(); + * console.log(device); + * // 'Tablet' + * @returns Device name + */ + getDevice(): string; + /** + * Execute command + * @example + * editor.runCommand('myCommand', {someValue: 1}); + * @param id - Command ID + * @param options - Custom options + * @returns The return is defined by the command + */ + runCommand(id: string, options: any): any; + /** + * Stop the command if stop method was provided + * @example + * editor.stopCommand('myCommand', {someValue: 1}); + * @param id - Command ID + * @param options - Custom options + * @returns The return is defined by the command + */ + stopCommand(id: string, options: any): any; + /** + * Store data to the current storage + * @param clb - Callback function + * @returns Stored data + */ + store(clb: (...params: any[]) => any): any; + /** + * Get the JSON data object, which could be stored and loaded back with `editor.loadData(json)` + * @example + * console.log(editor.storeData()); + * // { pages: [...], styles: [...], ... } + */ + storeData(): any; + /** + * Load data from the current storage + * @param clb - Callback function + * @returns Stored data + */ + load(clb: (...params: any[]) => any): any; + /** + * Load data from the JSON data object + * @example + * editor.loadData({ pages: [...], styles: [...], ... }) + * @param data - Data to load + * @returns Loaded object + */ + loadData(data: any): any; + /** + * Returns container element. The one which was indicated as 'container' + * on init method + */ + getContainer(): HTMLElement; + /** + * Return the count of changes made to the content and not yet stored. + * This count resets at any `store()` + */ + getDirtyCount(): number; + /** + * Update editor dimension offsets + * + * This method could be useful when you update, for example, some position + * of the editor element (eg. canvas, panels, etc.) with CSS, where without + * refresh you'll get misleading position of tools + * @param [options] - Options + * @param [options.tools = false] - Update the position of tools (eg. rich text editor, component highlighter, etc.) + */ + refresh(options?: { + tools?: boolean; + }): void; + /** + * Replace the built-in Rich Text Editor with a custom one. + * @example + * editor.setCustomRte({ + * // Function for enabling custom RTE + * // el is the HTMLElement of the double clicked Text Component + * // rte is the same instance you have returned the first time you call + * // enable(). This is useful if need to check if the RTE is already enabled so + * // ion this case you'll need to return the RTE and the end of the function + * enable: function(el, rte) { + * rte = new MyCustomRte(el, {}); // this depends on the Custom RTE API + * ... + * return rte; // return the RTE instance + * }, + * + * // Disable the editor, called for example when you unfocus the Text Component + * disable: function(el, rte) { + * rte.blur(); // this depends on the Custom RTE API + * } + * + * // Called when the Text Component is focused again. If you returned the RTE instance + * // from the enable function, the enable won't be called again instead will call focus, + * // in this case to avoid double binding of the editor + * focus: function (el, rte) { + * rte.focus(); // this depends on the Custom RTE API + * } + * }); + * @param obj - Custom RTE Interface + */ + setCustomRte(obj: any): void; + /** + * Replace the default CSS parser with a custom one. + * The parser function receives a CSS string as a parameter and expects + * an array of CSSRule objects as a result. If you need to remove the + * custom parser, pass `null` as the argument + * @example + * editor.setCustomParserCss(css => { + * const result = []; + * // ... parse the CSS string + * result.push({ + * selectors: '.someclass, div .otherclass', + * style: { color: 'red' } + * }) + * // ... + * return result; + * }); + * @param parser - Parser function + */ + setCustomParserCss(parser: ((...params: any[]) => any) | null): Editor; + /** + * Change the global drag mode of components. + * To get more about this feature read: https://github.com/artf/grapesjs/issues/1936 + * @param value - Drag mode, options: 'absolute' | 'translate' + */ + setDragMode(value: string): Editor; + /** + * Trigger event log message + * @example + * editor.log('Something done!', { ns: 'from-plugin-x', level: 'info' }); + * // This will trigger following events + * // `log`, `log:info`, `log-from-plugin-x`, `log-from-plugin-x:info` + * // Callbacks of those events will always receive the message and + * // options, as arguments, eg: + * // editor.on('log:info', (msg, opts) => console.info(msg, opts)) + * @param msg - Message to log + * @param [opts = {}] - Custom options + * @param [opts.ns = ''] - Namespace of the log (eg. to use in plugins) + * @param [opts.level = 'debug'] - Level of the log, `debug`, `info`, `warning`, `error` + */ + log(msg: any, opts?: { + ns?: string; + level?: string; + }): Editor; + /** + * Translate label + * @example + * editor.t('msg'); + * // use params + * editor.t('msg2', { params: { test: 'hello' } }); + * // custom local + * editor.t('msg2', { params: { test: 'hello' }, l: 'it' }); + * @param key - Label to translate + * @param [opts] - Options for the translation + * @param [opts.params] - Params for the translation + * @param [opts.noWarn] - Avoid warnings in case of missing resources + */ + t(key: string, opts?: { + params?: any; + noWarn?: boolean; + }): string; + /** + * Attach event + * @param event - Event name + * @param callback - Callback function + */ + on(event: GrapesEvent, callback: (...params: any[]) => any): Editor; + /** + * Attach event and detach it after the first run + * @param event - Event name + * @param callback - Callback function + */ + once(event: GrapesEvent, callback: (...params: any[]) => any): Editor; + /** + * Detach event + * @param event - Event name + * @param callback - Callback function + */ + off(event: GrapesEvent, callback: (...params: any[]) => any): Editor; + /** + * Trigger event + * @param event - Event to trigger + */ + trigger(event: GrapesEvent): Editor; + /** + * Destroy the editor + */ + destroy(): void; + /** + * Render editor + */ + render(): HTMLElement; + /** + * Trigger a callback once the editor is loaded and rendered. + * The callback will be executed immediately if the method is called on the already rendered editor. + * @example + * editor.onReady(() => { + * // perform actions + * }); + * @param clb - Callback to trigger + */ + onReady(clb: (...params: any[]) => any): void; + /** + * Print safe HTML by using ES6 tagged template strings. + * @example + * const unsafeStr = ''; + * const safeStr = 'Hello'; + * // Use `$${var}` to avoid escaping + * const strHtml = editor.html`Escaped ${unsafeStr}, unescaped $${safeStr}`; + */ + html(literals: string[], substs: string[]): string; + } + + type GrapesEvent = ComponentEvent + | BlockEvent + | AssetEvent + | KeymapEvent + | StyleManagerEvent + | StorageEvent + | CanvasEvent + | SelectorEvent + | RichTextEditorEvent + | ModalEvent + | CommandEvent + | GeneralEvent; + + type ComponentEvent = + 'component:create' + | 'component:mount' + | 'component:add' + | 'component:remove' + | 'component:remove:before' + | 'component:clone' + | 'component:update' + | 'component:styleUpdate' + | 'component:selected' + | 'component:deselected' + | 'component:toggled' + | 'component:type:add' + | 'component:type:update' + | 'component:drag:start' + | 'component:drag' + | 'component:drag:end'; + + type BlockEvent = + "block:add" + | "block:remove" + | "block:drag:start" + | "block:drag" + | "block:drag:stop"; + + type AssetEvent = + "asset:add" + | "asset:remove" + | "asset:upload:start" + | "asset:upload:end" + | "asset:upload:error" + | "asset:upload:response"; + + type KeymapEvent = + "keymap:add" + | "keymap:remove" + | "keymap:emit" + | "keymap:emit:{keymapId}"; + + type StyleManagerEvent = + "styleManager:update:target" + | "styleManager:change" + | "styleManager:change:{propertyName}"; + + type StorageEvent = + "storage:start" + | "storage:start:store" + | "storage:start:load" + | "storage:load" + | "storage:store" + | "storage:end" + | "storage:end:store" + | "storage:end:load" + | "storage:error" + | "storage:error:store" + | "storage:error:load"; + + type CanvasEvent = + "canvas:dragenter" + | "canvas:dragover" + | "canvas:drop" + | "canvas:dragend" + | "canvas:dragdata"; + + type SelectorEvent = "selector:add"; + + type RichTextEditorEvent = "rte:enable" | "rte:disable"; + + type ModalEvent = "modal:open" | "modal:close"; + + type CommandEvent = + "run:{commandName}" + | "stop:{commandName}" + | "run:{commandName}:before" + | "stop:{commandName}:before" + | "abort:{commandName}"; + + type GeneralEvent = + "canvasScroll" + | "undo" + | "redo" + | "load"; + + /** + * 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/asset_manager/config/config.js) + * ```js + * const editor = grapesjs.init({ + * assetManager: { + * // 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 assetManager = editor.AssetManager; + * ``` + * + * ## Available Events + * * `asset:open` - Asset Manager opened. + * * `asset:close` - Asset Manager closed. + * * `asset:add` - Asset added. The [Asset] is passed as an argument to the callback. + * * `asset:remove` - Asset removed. The [Asset] is passed as an argument to the callback. + * * `asset:update` - Asset updated. The updated [Asset] and the object containing changes are passed as arguments to the callback. + * * `asset:upload:start` - Before the upload is started. + * * `asset:upload:end` - After the upload is ended. + * * `asset:upload:error` - On any error in upload, passes the error as an argument. + * * `asset:upload:response` - On upload response, passes the result as an argument. + * * `asset` - 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. + * * `asset:custom` - Event for handling custom Asset Manager UI. + * + * ## Methods + * * [open](#open) + * * [close](#close) + * * [isOpen](#isopen) + * * [add](#add) + * * [get](#get) + * * [getAll](#getall) + * * [getAllVisible](#getallvisible) + * * [remove](#remove) + * * [store](#store) + * * [load](#load) + * * [getContainer](#getcontainer) + * + * [Asset]: asset.html + */ + interface AssetManager { + /** + * Open the asset manager. + * @example + * assetManager.open({ + * select(asset, complete) { + * const selected = editor.getSelected(); + * if (selected && selected.is('image')) { + * selected.addAttributes({ src: asset.getSrc() }); + * // The default AssetManager UI will trigger `select(asset, false)` on asset click + * // and `select(asset, true)` on double-click + * complete && assetManager.close(); + * } + * } + * }); + * // with your custom types (you should have assets with those types declared) + * assetManager.open({ types: ['doc'], ... }); + * @param [options] - Options for the asset manager. + * @param [options.types = ['image']] - Types of assets to show. + * @param [options.select] - Type of operation to perform on asset selection. If not specified, nothing will happen. + */ + open(options?: { + types?: String[]; + select?: (...params: any[]) => any; + }): void; + /** + * Close the asset manager. + * @example + * assetManager.close(); + */ + close(): void; + /** + * Checks if the asset manager is open + * @example + * assetManager.isOpen(); // true | false + */ + isOpen(): boolean; + /** + * Add new asset/s to the collection. URLs are supposed to be unique + * @example + * // As strings + * assetManager.add('http://img.jpg'); + * assetManager.add(['http://img.jpg', './path/to/img.png']); + * + * // Using objects you can indicate the type and other meta informations + * assetManager.add({ + * // type: 'image', // image is default + * src: 'http://img.jpg', + * height: 300, + * width: 200, + * }); + * assetManager.add([{ src: 'img2.jpg' }, { src: 'img2.png' }]); + * @param asset - URL strings or an objects representing the resource. + * @param [opts] - Options + */ + add(asset: string | any | String[] | object[], opts?: any): any; + /** + * Return asset by URL + * @example + * const asset = assetManager.get('http://img.jpg'); + * @param src - URL of the asset + */ + get(src: string): any; + /** + * Return the global collection, containing all the assets + */ + getAll(): any; + /** + * Return the visible collection, which contains assets actually rendered + */ + getAllVisible(): any; + /** + * Remove asset + * @example + * const removed = assetManager.remove('http://img.jpg'); + * // or by passing the Asset + * const asset = assetManager.get('http://img.jpg'); + * assetManager.remove(asset); + */ + remove(): any; + /** + * Store assets data to the selected storage + * @example + * var assets = assetManager.store(); + * @param noStore - If true, won't store + * @returns Data to store + */ + store(noStore: boolean): any; + /** + * Load data from the passed object. + * The fetched data will be added to the collection. + * @example + * var assets = assetManager.load({ + * assets: [...] + * }) + * @param data - Object of data to load + * @returns Loaded assets + */ + load(data: any): any; + /** + * Return the Asset Manager Container + */ + getContainer(): HTMLElement; + /** + * Render assets + * @example + * // Render all assets + * assetManager.render(); + * + * // Render some of the assets + * const assets = assetManager.getAll(); + * assetManager.render(assets.filter( + * asset => asset.get('category') == 'cats' + * )); + * @param assets - Assets to render, without the argument will render all global assets + */ + render(assets: any[]): HTMLElement; + } + + interface AssetOptions { + /** + * Asset type, eg. 'image'. + */ + type: string; + /** + * Asset URL, eg. 'https://.../image.png'. + */ + src: string; + } + + interface Asset extends Backbone.Model { + /** + * Get asset type. + * @example + * // Asset: { src: 'https://.../image.png', type: 'image' } + * asset.getType(); // -> 'image' + */ + getType(): string; + + /** + * Get asset URL. + * @example + * // Asset: { src: 'https://.../image.png' } + * asset.getSrc(); // -> 'https://.../image.png' + */ + getSrc(): string; + + /** + * Get filename of the asset (based on `src`). + * @example + * // Asset: { src: 'https://.../image.png' } + * asset.getFilename(); // -> 'image.png' + * // Asset: { src: 'https://.../image' } + * asset.getFilename(); // -> 'image' + */ + getFilename(): string; + + /** + * Get extension of the asset (based on `src`). + * @example + * // Asset: { src: 'https://.../image.png' } + * asset.getExtension(); // -> 'png' + * // Asset: { src: 'https://.../image' } + * asset.getExtension(); // -> '' + */ + getExtension(): string; + } + + /** + * 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 and listen to its events. Before using these methods, you should get the module from the instance. + * + * ```js + * // Listen to events + * editor.on('block:add', (block) => { ... }); + * + * // Use the API + * const blockManager = editor.BlockManager; + * blockManager.add(...); + * ``` + * + * ## Available Events + * * `block:add` - Block added. The [Block] is passed as an argument to the callback. + * * `block:remove` - Block removed. The [Block] is passed as an argument to the callback. + * * `block:update` - Block updated. The [Block] and the object containing changes are passed as arguments to the callback. + * * `block:drag:start` - Started dragging block, the [Block] is passed as an argument. + * * `block:drag` - Dragging block, the [Block] is passed as an argument. + * * `block:drag:stop` - Dragging of the block is stopped. The dropped [Component] (if dropped successfully) and the [Block] are passed as arguments. + * * `block` - 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) + * * [getAll](#getall) + * * [getAllVisible](#getallvisible) + * * [remove](#remove) + * * [getConfig](#getconfig) + * * [getCategories](#getcategories) + * * [getContainer](#getcontainer) + * * [render](#render) + * + * [Block]: block.html + * [Component]: component.html + */ + interface BlockManager { + /** + * Get configuration object + */ + getConfig(): BlockManagerConfig; + /** + * Add new block. + * @example + * blockManager.add('h1-block', { + * label: 'Heading', + * content: '

Put your title here

', + * category: 'Basic', + * attributes: { + * title: 'Insert h1 block' + * } + * }); + * @param id - Block ID + */ + add(id: string, block : BlockOptions): any; + /** + * Get the block by id. + * @example + * const block = blockManager.get('h1-block'); + * console.log(JSON.stringify(block)); + * // {label: 'Heading', content: '

Put your ...', ...} + * @param id - Block id + */ + get(id: string): any; + /** + * Return all blocks. + * @example + * const blocks = blockManager.getAll(); + * console.log(JSON.stringify(blocks)); + * // [{label: 'Heading', content: '

Put your ...'}, ...] + */ + getAll(): any; + /** + * Return the visible collection, which containes blocks actually rendered + */ + getAllVisible(): any; + /** + * Remove block. + * @example + * const removed = blockManager.remove('BLOCK_ID'); + * // or by passing the Block + * const block = blockManager.get('BLOCK_ID'); + * blockManager.remove(block); + */ + remove(): any; + /** + * Get all available categories. + * It's possible to add categories only within blocks via 'add()' method + */ + getCategories(): any[] | Backbone.Collection>; + /** + * Return the Blocks container element + */ + getContainer(): HTMLElement; + /** + * Render blocks + * @example + * // Render all blocks (inside the global collection) + * blockManager.render(); + * + * // Render new set of blocks + * const blocks = blockManager.getAll(); + * const filtered = blocks.filter(block => block.get('category') == 'sections') + * + * blockManager.render(filtered); + * // Or a new set from an array + * blockManager.render([ + * {label: 'Label text', content: '
Content
'} + * ]); + * + * // Back to blocks from the global collection + * blockManager.render(); + * + * // You can also render your blocks outside of the main block container + * const newBlocksEl = blockManager.render(filtered, { external: true }); + * document.getElementById('some-id').appendChild(newBlocksEl); + * @param blocks - Blocks to render, without the argument will render all global blocks + * @param [opts = {}] - Options + * @param [opts.external] - Render blocks in a new container (HTMLElement will be returned) + * @param [opts.ignoreCategories] - Render blocks without categories + * @returns Rendered element + */ + render(blocks: any[], opts?: { + external?: boolean; + ignoreCategories?: boolean; + }): HTMLElement; + } + + interface BlockOptions { + /** + * Block label, eg. `My block` + */ + label: string; + /** + * The content of the block. Might be an HTML string or a [Component Defintion](/modules/Components.html#component-definition) + */ + content: string | any; + /** + * HTML string for the media/icon of the block, eg. ` editor.getWrapper().append(block.get('content'))` + */ + onClick?: (...params: any[]) => any; + } + interface Block extends Backbone.Model { + /** + * Get block id + */ + getId(): string; + + /** + * Get block label + */ + getLabel(): string; + + /** + * Get block media + */ + getMedia(): string; + + /** + * Get block content + * @returns Component definition | HTML string + */ + getContent(): any | string | (object | String)[]; + + /** + * Get block category label + */ + getCategoryLabel(): string; + + self(): Block; + } + + /** + * 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/commands/config/config.js) + * ```js + * const editor = grapesjs.init({ + * commands: { + * // options + * } + * }) + * ``` + * + * Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance. + * + * ```js + * // Listen to events + * editor.on('run', () => { ... }); + * + * // Use the API + * const commands = editor.Commands; + * commands.add(...); + * ``` + * + * * ## Available Events + * * `run:{commandName}` - Triggered when some command is called to run (eg. editor.runCommand('preview')) + * * `stop:{commandName}` - Triggered when some command is called to stop (eg. editor.stopCommand('preview')) + * * `run:{commandName}:before` - Triggered before the command is called + * * `stop:{commandName}:before` - Triggered before the command is called to stop + * * `abort:{commandName}` - Triggered when the command execution is aborted (`editor.on(`run:preview:before`, opts => opts.abort = 1);`) + * * `run` - Triggered on run of any command. The id and the result are passed as arguments to the callback + * * `stop` - Triggered on stop of any command. The id and the result are passed as arguments to the callback + * + * ## Methods + * * [add](#add) + * * [get](#get) + * * [getAll](#getall) + * * [extend](#extend) + * * [has](#has) + * * [run](#run) + * * [stop](#stop) + * * [isActive](#isactive) + * * [getActive](#getactive) + */ + interface Commands { + /** + * Add new command to the collection + * @example + * commands.add('myCommand', { + * run(editor, sender) { + * alert('Hello world!'); + * }, + * stop(editor, sender) { + * }, + * }); + * // As a function + * commands.add('myCommand2', editor => { ... }); + */ + add(id : string, command : (editor : Editor) => void | { + run: (editor: Editor, sender? : any) => void; + stop: (editor: Editor, sender? : any) => void; + }) : void + /** + * Get command by ID + * @example + * var myCommand = commands.get('myCommand'); + * myCommand.run(); + * @param id - Command's ID + * @returns Object representing the command + */ + get(id: string): any; + /** + * Extend the command. The command to extend should be defined as an object + * @example + * commands.extend('old-command', { + * someInnerFunction() { + * // ... + * } + * }); + * @param id - Command's ID + * @param Object - with the new command functions + */ + extend(id: string, Object: any): Commands; + /** + * Check if command exists + * @param id - Command's ID + */ + has(id: string): boolean; + /** + * Get an object containing all the commands + */ + getAll(): any; + /** + * Execute the command + * @example + * commands.run('myCommand', { someOption: 1 }); + * @param id - Command ID + * @param [options = {}] - Options + * @returns The return is defined by the command + */ + run(id: string, options?: any): any; + /** + * Stop the command + * @example + * commands.stop('myCommand', { someOption: 1 }); + * @param id - Command ID + * @param [options = {}] - Options + * @returns The return is defined by the command + */ + stop(id: string, options?: any): any; + /** + * Check if the command is active. You activate commands with `run` + * and disable them with `stop`. If the command was created without `stop` + * method it can't be registered as active + * @example + * const cId = 'some-command'; + * commands.run(cId); + * commands.isActive(cId); + * // -> true + * commands.stop(cId); + * commands.isActive(cId); + * // -> false + * @param id - Command id + */ + isActive(id: string): boolean; + /** + * Get all active commands + * @example + * console.log(commands.getActive()); + * // -> { someCommand: itsLastReturn, anotherOne: ... }; + */ + getActive(): any; + } + + interface AddComponentOptions { + isComponent?: (el : HTMLElement) => boolean | ComponentProperties, + model?: ComponentModelDefinition + view?: ComponentViewDefinition + } + + interface ComponentModelDefinition { + defaults?: ComponentProperties + init?: (this: Component) => void + handlePropChange?: (this: Component) => void + handleAttrChange?: (this: Component) => void + handleTitleChange?: (this: Component) => void + } + + interface ComponentViewDefinition { + tagName : string, + events: Record + init?: (options: {model: Component}) => void + removed?: () => void + onRender?: (options: {el : HTMLElement, model: Component}) => void + } + + /** + * With this module is possible to manage components inside the canvas. 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/dom_components/config/config.js) + * ```js + * const editor = grapesjs.init({ + * domComponents: { + * // options + * } + * }) + * ``` + * + * Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance. + * + * ```js + * // Listen to events + * editor.on('component:create', () => { ... }); + * + * // Use the API + * const cmp = editor.Components; + * cmp.addType(...); + * ``` + * + * ## Available Events + * * `component:create` - Component is created (only the model, is not yet mounted in the canvas), called after the init() method + * * `component:mount` - Component is mounted to an element and rendered in canvas + * * `component:add` - Triggered when a new component is added to the editor, the model is passed as an argument to the callback + * * `component:remove` - Triggered when a component is removed, the model is passed as an argument to the callback + * * `component:remove:before` - Triggered before the remove of the component, the model, remove function (if aborted via options, with this function you can complete the remove) and options (use options.abort = true to prevent remove), are passed as arguments to the callback + * * `component:clone` - Triggered when a component is cloned, the new model is passed as an argument to the callback + * * `component:update` - Triggered when a component is updated (moved, styled, etc.), the model is passed as an argument to the callback + * * `component:update:{propertyName}` - Listen any property change, the model is passed as an argument to the callback + * * `component:styleUpdate` - Triggered when the style of the component is updated, the model is passed as an argument to the callback + * * `component:styleUpdate:{propertyName}` - Listen for a specific style property change, the model is passed as an argument to the callback + * * `component:selected` - New component selected, the selected model is passed as an argument to the callback + * * `component:deselected` - Component deselected, the deselected model is passed as an argument to the callback + * * `component:toggled` - Component selection changed, toggled model is passed as an argument to the callback + * * `component:type:add` - New component type added, the new type is passed as an argument to the callback + * * `component:type:update` - Component type updated, the updated type is passed as an argument to the callback + * * `component:drag:start` - Component drag started. Passed an object, to the callback, containing the `target` (component to drag), `parent` (parent of the component) and `index` (component index in the parent) + * * `component:drag` - During component drag. Passed the same object as in `component:drag:start` event, but in this case, `parent` and `index` are updated by the current pointer + * * `component:drag:end` - Component drag ended. Passed the same object as in `component:drag:start` event, but in this case, `parent` and `index` are updated by the final pointer + * + * ## Methods + * * [getWrapper](#getwrapper) + * * [getComponents](#getcomponents) + * * [addComponent](#addcomponent) + * * [clear](#clear) + * * [load](#load) + * * [store](#store) + * * [addType](#addtype) + * * [getType](#gettype) + * * [getTypes](#gettypes) + * * [render](#render) + */ + interface Components { + /** + * Load components from the passed object, if the object is empty will try to fetch them + * autonomously from the selected storage + * The fetched data will be added to the collection + * @param data - Object of data to load + * @returns Loaded data + */ + load(data: any): any; + /** + * Store components on the selected storage + * @param noStore - If true, won't store + * @returns Data to store + */ + store(noStore: boolean): any; + /** + * Returns root component inside the canvas. Something like `` inside HTML page + * The wrapper doesn't differ from the original Component Model + * @example + * // Change background of the wrapper and set some attribute + * var wrapper = cmp.getWrapper(); + * wrapper.set('style', {'background-color': 'red'}); + * wrapper.set('attributes', {'title': 'Hello!'}); + * @returns Root Component + */ + getWrapper(): Component; + /** + * Returns wrapper's children collection. Once you have the collection you can + * add other Components(Models) inside. Each component can have several nested + * components inside and you can nest them as more as you wish. + * @example + * // Let's add some component + * var wrapperChildren = cmp.getComponents(); + * var comp1 = wrapperChildren.add({ + * style: { 'background-color': 'red'} + * }); + * var comp2 = wrapperChildren.add({ + * tagName: 'span', + * attributes: { title: 'Hello!'} + * }); + * // Now let's add an other one inside first component + * // First we have to get the collection inside. Each + * // component has 'components' property + * var comp1Children = comp1.get('components'); + * // Procede as before. You could also add multiple objects + * comp1Children.add([ + * { style: { 'background-color': 'blue'}}, + * { style: { height: '100px', width: '100px'}} + * ]); + * // Remove comp2 + * wrapperChildren.remove(comp2); + * @returns Collection of components + */ + getComponents(): Components; + /** + * Add new components to the wrapper's children. It's the same + * as 'cmp.getComponents().add(...)' + * @example + * // Example of a new component with some extra property + * var comp1 = cmp.addComponent({ + * tagName: 'div', + * removable: true, // Can't remove it + * draggable: true, // Can't move it + * copyable: true, // Disable copy/past + * content: 'Content text', // Text inside component + * style: { color: 'red'}, + * attributes: { title: 'here' } + * }); + * @param component - Component/s to add + * @param [component.tagName = 'div'] - Tag name + * @param [component.type = ''] - Type of the component. Available: ''(default), 'text', 'image' + * @param [component.removable = true] - If component is removable + * @param [component.draggable = true] - If is possible to move the component around the structure + * @param [component.droppable = true] - If is possible to drop inside other components + * @param [component.badgable = true] - If the badge is visible when the component is selected + * @param [component.stylable = true] - If is possible to style component + * @param [component.copyable = true] - If is possible to copy&paste the component + * @param [component.content = ''] - String inside component + * @param [component.style = {}] - Style object + * @param [component.attributes = {}] - Attribute object + * @param opt - the options object to be used by the [Components.add]{@link getComponents} method + * @returns Component/s added + */ + addComponent(component: { + tagName?: string; + type?: string; + removable?: boolean; + draggable?: boolean; + droppable?: boolean; + badgable?: boolean; + stylable?: boolean; + copyable?: boolean; + content?: string; + style?: any; + attributes?: any; + }, opt: any): Component; + /** + * Render and returns wrapper element with all components inside. + * Once the wrapper is rendered, and it's what happens when you init the editor, + * the all new components will be added automatically and property changes are all + * updated immediately + */ + render(): HTMLElement; + /** + * Remove all components + */ + clear(): Components; + /** + * Add new component type. + * Read more about this in [Define New Component](https://grapesjs.com/docs/modules/Components.html#define-new-component) + * @param type - Component ID + * @param methods - Component methods + */ + addType(type: string, methods: AddComponentOptions): Components; + /** + * Get component type. + * Read more about this in [Define New Component](https://grapesjs.com/docs/modules/Components.html#define-new-component) + * @param type - Component ID + * @returns Component type definition, eg. `{ model: ..., view: ... }` + */ + getType(type: string): any; + /** + * Remove component type + * @param type - Component ID + * @returns Removed component type, undefined otherwise + */ + removeType(type: string): any | undefined; + /** + * Return the array of all types + */ + getTypes(): any[]; + } + + interface ComponentProperties { + /** + * Component type, eg. `text`, `image`, `video`, etc. + * @defaultValue '' + */ + type?: string; + /** + * HTML tag of the component, eg. `span`. Default: `div` + * @defaultValue 'div' + */ + tagName?: string; + /** + * Key-value object of the component's attributes, eg. `{ title: 'Hello' }` Default: `{}` + * @defaultValue {} + */ + attributes?: Record; + /** + * Name of the component. Will be used, for example, in Layers and badges + * @defaultValue '' + */ + name?: string; + /** + * When `true` the component is removable from the canvas, default: `true` + * @defaultValue true + */ + removable?: boolean; + /** + * Indicates if it's possible to drag the component inside others. + You can also specify a query string to indentify elements, + eg. `'.some-class[title=Hello], [data-gjs-type=column]'` means you can drag the component only inside elements + containing `some-class` class and `Hello` title, and `column` components. In the case of a function, target and destination components are passed as arguments, return a Boolean to indicate if the drag is possible. Default: `true` + * @defaultValue true + */ + draggable?: boolean | string | ((...params: any[]) => any); + /** + * Indicates if it's possible to drop other components inside. You can use + a query string as with `draggable`. In the case of a function, target and destination components are passed as arguments, return a Boolean to indicate if the drop is possible. Default: `true` + * @defaultValue true + */ + droppable?: boolean | string | ((...params: any[]) => any); + /** + * Set to false if you don't want to see the badge (with the name) over the component. Default: `true` + * @defaultValue true + */ + badgable?: boolean; + /** + * True if it's possible to style the component. + You can also indicate an array of CSS properties which is possible to style, eg. `['color', 'width']`, all other properties + will be hidden from the style manager. Default: `true` + * @defaultValue true + */ + stylable?: boolean | String[]; + ///** + // * Indicate an array of style properties to show up which has been marked as `toRequire`. Default: `[]` + // * @defaultValue [] + // */ + //`stylable-require`?: String[]; + /** + * Indicate an array of style properties which should be hidden from the style manager. Default: `[]` + * @defaultValue [] + */ + unstylable?: String[]; + /** + * It can be highlighted with 'dotted' borders if true. Default: `true` + * @defaultValue true + */ + highlightable?: boolean; + /** + * True if it's possible to clone the component. Default: `true` + * @defaultValue true + */ + copyable?: boolean; + /** + * Indicates if it's possible to resize the component. It's also possible to pass an object as [options for the Resizer](https://github.com/artf/grapesjs/blob/master/src/utils/Resizer.js). Default: `false` + */ + resizable?: boolean; + /** + * Allow to edit the content of the component (used on Text components). Default: `false` + */ + editable?: boolean; + /** + * Set to `false` if you need to hide the component inside Layers. Default: `true` + * @defaultValue true + */ + layerable?: boolean; + /** + * Allow component to be selected when clicked. Default: `true` + * @defaultValue true + */ + selectable?: boolean; + /** + * Shows a highlight outline when hovering on the element if `true`. Default: `true` + * @defaultValue true + */ + hoverable?: boolean; + /** + * This property is used by the HTML exporter as void elements don't have closing tags, eg. `
`, `
`, etc. Default: `false` + */ + void?: boolean; + /** + * Component default style, eg. `{ width: '100px', height: '100px', 'background-color': 'red' }` + * @defaultValue {} + */ + style?: any; + /** + * Component related styles, eg. `.my-component-class { color: red }` + * @defaultValue '' + */ + styles?: string; + /** + * Content of the component (not escaped) which will be appended before children rendering. Default: `''` + * @defaultValue '' + */ + content?: string; + /** + * Component's icon, this string will be inserted before the name (in Layers and badge), eg. it can be an HTML string ''. Default: `''` + * @defaultValue '' + */ + icon?: string; + /** + * Component's javascript. More about it [here](/modules/Components-js.html). Default: `''` + * @defaultValue '' + */ + script?: string | ((...params: any[]) => any); + ///** + // * You can specify javascript available only in export functions (eg. when you get the HTML). + //If this property is defined it will overwrite the `script` one (in export functions). Default: `''` + // * @defaultValue '' + // */ + //script-export?: string | ((...params: any[]) => any); + /** + * Component's traits. More about it [here](/modules/Traits.html). Default: `['id', 'title']` + * @defaultValue '' + */ + traits?: TraitOptions[] | String[] | Backbone.Collection; + /** + * Indicates an array of properties which will be inhereted by all NEW appended children. + For example if you create a component likes this: `{ removable: false, draggable: false, propagate: ['removable', 'draggable'] }` + and append some new component inside, the new added component will get the exact same properties indicated in the `propagate` array (and the `propagate` property itself). Default: `[]` + * @defaultValue [] + */ + propagate?: String[]; + /** + * Set an array of items to show up inside the toolbar when the component is selected (move, clone, delete). + Eg. `toolbar: [ { attributes: {class: 'fa fa-arrows'}, command: 'tlb-move' }, ... ]`. + By default, when `toolbar` property is falsy the editor will add automatically commands `core:component-exit` (select parent component, added if there is one), `tlb-move` (added if `draggable`) , `tlb-clone` (added if `copyable`), `tlb-delete` (added if `removable`). + */ + toolbar?: object[]; + ///** + // * Children components. Default: `null` + // */ + components?: Backbone.Collection; + [key: string]: any + } + + /** + * The Component object represents a single node of our template structure, so when you update its properties the changes are + * immediately reflected on the canvas and in the code to export (indeed, when you ask to export the code we just go through all + * the tree of nodes). + * An example on how to update properties: + * ```js + * component.set({ + * tagName: 'span', + * attributes: { ... }, + * removable: false, + * }); + * component.get('tagName'); + * // -> 'span' + * ``` + * + * [Component]: component.html + */ + interface Component extends Backbone.Model { + view?: ComponentView + + /** + * Hook method, called once the model is created + */ + init(): void; + + /** + * Hook method, called when the model has been updated (eg. updated some model's property) + * @param property - Property name, if triggered after some property update + * @param value - Property value, if triggered after some property update + * @param previous - Property previous value, if triggered after some property update + */ + updated(property: string, value: any, previous: any): void; + + /** + * Hook method, called once the model has been removed + */ + removed(): void; + + /** + * Check component's type + * @example + * component.is('image') + * // -> false + * @param type - Component type + */ + is(type: string): boolean; + + /** + * Return all the propeties + */ + props(): ComponentProperties; + + /** + * Get the index of the component in the parent collection. + */ + index(): number; + + /** + * Change the drag mode of the component. + * To get more about this feature read: https://github.com/artf/grapesjs/issues/1936 + * @param value - Drag mode, options: 'absolute' | 'translate' + */ + setDragMode(value: string): this; + + /** + * Find inner components by query string. + * **ATTENTION**: this method works only with already rendered component + * @example + * component.find('div > .class'); + * // -> [Component, Component, ...] + * @param query - Query string + * @returns Array of components + */ + find(query: string): Component[]; + + /** + * Find all inner components by component type. + * The advantage of this method over `find` is that you can use it + * also before rendering the component + * @example + * const allImages = component.findType('image'); + * console.log(allImages[0]) // prints the first found component + * @param type - Component type + */ + findType(type: string): Component[]; + + /** + * Find the closest parent component by query string. + * **ATTENTION**: this method works only with already rendered component + * @example + * component.closest('div.some-class'); + * // -> Component + * @param query - Query string + */ + closest(query: string): Component; + + /** + * Find the closest parent component by its type. + * The advantage of this method over `closest` is that you can use it + * also before rendering the component + * @example + * const Section = component.closestType('section'); + * console.log(Section); + * @param type - Component type + * @returns Found component, otherwise `undefined` + */ + closestType(type: string): Component; + + /** + * The method returns a Boolean value indicating whether the passed + * component is a descendant of a given component + * @param component - Component to check + */ + contains(component: Component): boolean; + + /** + * Replace a component with another one + * @example + * component.replaceWith('
Some new content
'); + * // -> Component + * @param el - Component or HTML string + * @returns New added component/s + */ + replaceWith(el: string | Component): Component | Component[]; + + /** + * Update attributes of the component + * @example + * component.setAttributes({ id: 'test', 'data-key': 'value' }); + * @param attrs - Key value attributes + * @param options - Options for the model update + */ + setAttributes(attrs: any, options: any): this; + + /** + * Add attributes to the component + * @example + * component.addAttributes({ 'data-key': 'value' }); + * @param attrs - Key value attributes + * @param options - Options for the model update + */ + addAttributes(attrs: any, options: any): this; + + /** + * Remove attributes from the component + * @example + * component.removeAttributes('some-attr'); + * component.removeAttributes(['some-attr1', 'some-attr2']); + * @param attrs - Array of attributes to remove + * @param options - Options for the model update + */ + removeAttributes(attrs: string | String[], options: any): this; + + /** + * Get the style of the component + */ + getStyle(): any; + + /** + * Set the style on the component + * @example + * component.setStyle({ color: 'red' }); + * @param prop - Key value style object + */ + setStyle(prop: any): any; + + /** + * Return all component's attributes + */ + getAttributes(): Record; + + /** + * Add classes + * @example + * model.addClass('class1'); + * model.addClass('class1 class2'); + * model.addClass(['class1', 'class2']); + * // -> [SelectorObject, ...] + * @param classes - Array or string of classes + * @returns Array of added selectors + */ + addClass(classes: String[] | string): any[]; + + /** + * Set classes (resets current collection) + * @example + * model.setClass('class1'); + * model.setClass('class1 class2'); + * model.setClass(['class1', 'class2']); + * // -> [SelectorObject, ...] + * @param classes - Array or string of classes + * @returns Array of added selectors + */ + setClass(classes: String[] | string): any[]; + + /** + * Remove classes + * @example + * model.removeClass('class1'); + * model.removeClass('class1 class2'); + * model.removeClass(['class1', 'class2']); + * // -> [SelectorObject, ...] + * @param classes - Array or string of classes + * @returns Array of removed selectors + */ + removeClass(classes: String[] | string): any[]; + + /** + * Returns component's classes as an array of strings + */ + getClasses(): any[]; + + /** + * Add new component children + * @example + * someComponent.get('components').length // -> 0 + * const videoComponent = someComponent.append('
')[0]; + * // This will add 2 components (`video` and `div`) to your `someComponent` + * someComponent.get('components').length // -> 2 + * // You can pass components directly + * otherComponent.append(otherComponent2); + * otherComponent.append([otherComponent3, otherComponent4]); + * // append at specific index (eg. at the beginning) + * someComponent.append(otherComponent, { at: 0 }); + * @param components - Component to add + * @param [opts = {}] - Options for the append action + * @returns Array of appended components + */ + append(components: Component | string, opts?: any): any[]; + + /** + * Set new collection if `components` are provided, otherwise the + * current collection is returned + * @example + * // Set new collection + * component.components('
'); + * // Get current collection + * const collection = component.components(); + * console.log(collection.length); + * // -> 2 + * @param [components] - Component Definitions or HTML string + * @param [opts = {}] - Options, same as in `Component.append()` + */ + components(components?: Component | string, opts?: any): Backbone.Collection; + + /** + * If exists, returns the child component at specific index. + * @example + * // Return first child + * component.getChildAt(0); + * // Return second child + * component.getChildAt(1); + * @param index - Index of the component to return + */ + getChildAt(index: number): any; + + /** + * If exists, returns the last child component. + * @example + * const lastChild = component.getLastChild(); + */ + getLastChild(): any; + + /** + * Remove all inner components + * * @return {this} + */ + empty(): void; + + /** + * Get the parent component, if exists + * @example + * component.parent(); + * // -> Component + */ + parent(): Component | null; + + /** + * Get traits. + * @example + * const traits = component.getTraits(); + * console.log(traits); + * // [Trait, Trait, Trait, ...] + */ + getTraits(): Trait[]; + + /** + * Replace current collection of traits with a new one. + * @example + * const traits = component.setTraits([{ type: 'checkbox', name: 'disabled'}, ...]); + * console.log(traits); + * // [Trait, ...] + * @param traits - Array of trait definitions + */ + setTraits(traits: object[]): Trait[]; + + /** + * Get the trait by id/name. + * @example + * const traitTitle = component.getTrait('title'); + * traitTitle && traitTitle.set('label', 'New label'); + * @param id - The `id` or `name` of the trait + * @returns Trait getModelToStyle + */ + getTrait(id: string): Trait | null; + + /** + * Update a trait. + * @example + * component.updateTrait('title', { + * type: 'select', + * options: [ 'Option 1', 'Option 2' ], + * }); + * @param id - The `id` or `name` of the trait + * @param props - Object with the props to update + */ + updateTrait(id: string, props: any): this; + + /** + * Get the trait position index by id/name. Useful in case you want to + * replace some trait, at runtime, with something else. + * @example + * const traitTitle = component.getTraitIndex('title'); + * console.log(traitTitle); // 1 + * @param id - The `id` or `name` of the trait + * @returns Index position of the current trait + */ + getTraitIndex(id: string): number; + + /** + * Remove trait/s by id/s. + * @example + * component.removeTrait('title'); + * component.removeTrait(['title', 'id']); + * @param id - The `id`/`name` of the trait (or an array) + * @returns Array of removed traits + */ + removeTrait(id: string | String[]): Trait[]; + + /** + * Add new trait/s. + * @example + * component.addTrait('title', { at: 1 }); // Add title trait (`at` option is the position index) + * component.addTrait({ + * type: 'checkbox', + * name: 'disabled', + * }); + * component.addTrait(['title', {...}, ...]); + * @param trait - Trait to add (or an array of traits) + * @param opts - Options for the add + * @returns Array of added traits + */ + addTrait(trait: string | any | (String | object)[], opts: Record): Trait[]; + + /** + * Get the name of the component + */ + getName(): string; + + /** + * Get the icon string + */ + getIcon(): string; + + /** + * Return HTML string of the component + * @example + * // Simple HTML return + * component.set({ tagName: 'span' }); + * component.setAttributes({ title: 'Hello' }); + * component.toHTML(); + * // -> + * + * // Custom attributes + * component.toHTML({ attributes: { 'data-test': 'Hello' } }); + * // -> + * + * // Custom dynamic attributes + * component.toHTML({ + * attributes(component, attributes) { + * if (component.get('tagName') == 'span') { + * attributes.title = 'Custom attribute'; + * } + * return attributes; + * }, + * }); + * // -> + * @param [opts = {}] - Options + * @param [opts.tag] - Custom tagName + * @param [opts.attributes = null] - You can pass an object of custom attributes to replace with the current ones or you can even pass a function to generate attributes dynamically. + * @param [opts.withProps] - Include component properties as `data-gjs-*` attributes. This allows you to have re-importable HTML. + * @param [opts.altQuoteAttr] - In case the attribute value contains a `"` char, instead of escaping it (`attr="value ""`), the attribute will be quoted using single quotes (`attr='value "'`). + * @returns HTML string + */ + toHTML(opts?: { + tag?: string; + attributes?: any | ((...params: any[]) => any); + withProps?: boolean; + altQuoteAttr?: boolean; + }): string; + + /** + * Get inner HTML of the component + * @param [opts = {}] - Same options of `toHTML` + * @returns HTML string + */ + getInnerHTML(opts?: any): string; + + /** + * Return an object containing only changed props + */ + getChangedProps(): void; + + /** + * Get block id + */ + getId(): string; + + /** + * Set new id on the component + */ + setId(id: string): this; + + /** + * Get the DOM element of the component. + * This works only if the component is already rendered + * @param frame - Specific frame from which taking the element + */ + getEl(frame?: Frame): HTMLElement; + + /** + * Get the View of the component. + * This works only if the component is already rendered + * @param frame - Get View of a specific frame + */ + getView(frame?: Frame): ComponentView; + + /** + * Execute callback function on itself and all inner components + * @example + * component.onAll(component => { + * // do something with component + * }) + * @param clb - Callback function, the model is passed as an argument + */ + onAll(clb: (...params: any[]) => any): this; + + /** + * Remove the component + */ + remove(): this; + + /** + * Move the component to another destination component + * @example + * // Move the selected component on top of the wrapper + * const dest = editor.getWrapper(); + * editor.getSelected().move(dest, { at: 0 }); + * @param component - Destination component (so the current one will be appended as a child) + * @param opts - Options for the append action + */ + move(component: Component, opts: any): this; + } + + /** + * 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) + */ + interface Panels { + /** + * Returns the collection of panels + * @returns Collection of panel + */ + getPanels(): Backbone.Collection; + /** + * Returns panels element + */ + getPanelsEl(): HTMLElement; + /** + * Add new panel to the collection + * @example + * var newPanel = panelManager.addPanel({ + * id: 'myNewPanel', + * visible : true, + * buttons : [...], + * }); + * @param panel - Object with right properties or an instance of Panel + * @returns Added panel. Useful in case passed argument was an Object + */ + addPanel(panel: any | Panel): Panel; + /** + * Remove a panel from the collection + * @example + * const newPanel = panelManager.removePanel({ + * id: 'myNewPanel', + * visible : true, + * buttons : [...], + * }); + * + * const newPanel = panelManager.removePanel('myNewPanel'); + * @param panel - Object with right properties or an instance of Panel or Painel id + * @returns Removed panel. Useful in case passed argument was an Object + */ + removePanel(panel: any | Panel | string): Panel; + /** + * Get panel by ID + * @example + * var myPanel = panelManager.getPanel('myNewPanel'); + * @param id - Id string + */ + getPanel(id: string): Panel | null; + /** + * Add button to the panel + * @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 which will be evaluated as a single .run command + * ... + * command: function(editor) { + * ... + * } + * @param panelId - Panel's ID + * @param button - Button object or instance of Button + * @returns Added button. Useful in case passed button was an Object + */ + addButton(panelId: string, button: ButtonOptions | Button): Button | null; + /** + * Remove button from the panel + * @example + * const removedButton = panelManager.addButton('myNewPanel',{ + * id: 'myNewButton', + * className: 'someClass', + * command: 'someCommand', + * attributes: { title: 'Some title'}, + * active: false, + * }); + * + * const removedButton = panelManager.removeButton('myNewPanel', 'myNewButton'); + * @param panelId - Panel's ID + * @param buttonId - Button's ID + * @returns Removed button. + */ + removeButton(panelId: string, buttonId: string): Button | null; + /** + * Get button from the panel + * @example + * var button = panelManager.getButton('myPanel','myButton'); + * @param panelId - Panel's ID + * @param id - Button's ID + */ + getButton(panelId: string, id: string): Button | null; + } + + /** + * With Style Manager you build categories (called sectors) of CSS properties which could be used to customize the style of components. + * 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/style_manager/config/config.js) + * ```js + * const editor = grapesjs.init({ + * styleManager: { + * // options + * } + * }) + * ``` + * + * Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance. + * + * ```js + * // Listen to events + * editor.on('style:sector:add', (sector) => { ... }); + * + * // Use the API + * const styleManager = editor.StyleManager; + * styleManager.addSector(...); + * ``` + * ## Available Events + * * `style:sector:add` - Sector added. The [Sector] is passed as an argument to the callback. + * * `style:sector:remove` - Sector removed. The [Sector] is passed as an argument to the callback. + * * `style:sector:update` - Sector updated. The [Sector] and the object containing changes are passed as arguments to the callback. + * * `style:property:add` - Property added. The [Property] is passed as an argument to the callback. + * * `style:property:remove` - Property removed. The [Property] is passed as an argument to the callback. + * * `style:property:update` - Property updated. The [Property] and the object containing changes are passed as arguments to the callback. + * * `style:target` - Target selection changed. The target (or `null` in case the target is deselected) is passed as an argument to the callback. + * + * + * ## Methods + * * [getConfig](#getconfig) + * * [addSector](#addsector) + * * [getSector](#getsector) + * * [getSectors](#getsectors) + * * [removeSector](#removesector) + * * [addProperty](#addproperty) + * * [getProperty](#getproperty) + * * [getProperties](#getproperties) + * * [removeProperty](#removeproperty) + * * [select](#select) + * * [getSelected](#getselected) + * * [getSelectedAll](#getselectedall) + * * [getSelectedParents](#getselectedparents) + * * [addStyleTargets](#addstyletargets) + * * [getBuiltIn](#getbuiltin) + * * [getBuiltInAll](#getbuiltinall) + * * [addBuiltIn](#addbuiltin) + * * [addType](#addtype) + * * [getType](#gettype) + * * [getTypes](#gettypes) + * + * [Sector]: sector.html + * [CssRule]: css_rule.html + * [Component]: component.html + * [Property]: property.html + */ + interface StyleManager { + /** + * Get configuration object + */ + getConfig(): StyleManagerConfig; + /** + * Add new sector. If the sector with the same id already exists, that one will be returned. + * @example + * const sector = styleManager.addSector('mySector',{ + * name: 'My sector', + * open: true, + * properties: [{ name: 'My property'}] + * }, { at: 0 }); + * // With `at: 0` we place the new sector at the beginning of the list + * @param id - Sector id + * @param sector - Sector definition. Check the [available properties](sector.html#properties) + * @param [options = {}] - Options + * @param [options.at] - Position index (by default, will be appended at the end). + */ + addSector(id: string, sector: any, options?: { + at?: number; + }): any; + /** + * Get sector by id. + * @example + * const sector = styleManager.getSector('mySector'); + * @param id - Sector id + */ + getSector(id: string): any; + /** + * Get all sectors. + * @example + * const sectors = styleManager.getSectors(); + * @param [opts = {}] - Options + * @param [opts.visible] - Returns only visible sectors + */ + getSectors(opts?: { + visible?: boolean; + }): any; + /** + * Remove sector by id. + * @example + * const removed = styleManager.removeSector('mySector'); + * @param id - Sector id + */ + removeSector(id: string): any; + /** + * Add new property to the sector. + * @example + * const property = styleManager.addProperty('mySector', { + * label: 'Minimum height', + * property: 'min-height', + * type: 'select', + * default: '100px', + * options: [ + * { id: '100px', label: '100' }, + * { id: '200px', label: '200' }, + * ], + * }, { at: 0 }); + * @param sectorId - Sector id. + * @param property - Property definition. Check the [base available properties](property.html#properties) + others based on the `type` of your property. + * @param [opts = {}] - Options + * @param [opts.at] - Position index (by default, will be appended at the end). + */ + addProperty(sectorId: string, property: any, opts?: { + at?: number; + }): any; + /** + * Get the property. + * @example + * const property = styleManager.getProperty('mySector', 'min-height'); + * @param sectorId - Sector id. + * @param id - Property id. + */ + getProperty(sectorId: string, id: string): any; + /** + * Get all properties of the sector. + * @example + * const properties = styleManager.getProperties('mySector'); + * @param sectorId - Sector id. + */ + getProperties(sectorId: string): any; + /** + * Remove the property. + * @example + * const property = styleManager.removeProperty('mySector', 'min-height'); + * @param sectorId - Sector id. + * @param id - Property id. + */ + removeProperty(sectorId: string, id: string): any; + /** + * Select new target. + * The target could be a Component, CSSRule, or a CSS selector string. + * @example + * // Select the first button in the current page + * const wrapperCmp = editor.Pages.getSelected().getMainComponent(); + * const btnCmp = wrapperCmp.find('button')[0]; + * btnCmp && styleManager.select(btnCmp); + * + * // Set as a target the CSS selector + * styleManager.select('.btn > span'); + */ + select(): any; + /** + * Get the last selected target. + * By default, the Style Manager shows styles of the last selected target. + */ + getSelected(): any; + /** + * Get the array of selected targets. + */ + getSelectedAll(): any; + /** + * Get parent rules of the last selected target. + */ + getSelectedParents(): any; + /** + * Update selected targets with a custom style. + * @example + * styleManager.addStyleTargets({ color: 'red' }); + * @param style - Style object + * @param [opts = {}] - Options + */ + addStyleTargets(style: any, opts?: any): void; + /** + * Return built-in property definition + * @example + * const widthPropDefinition = styleManager.getBuiltIn('width'); + * @param prop - Property name. + * @returns Property definition. + */ + getBuiltIn(prop: string): any | null; + /** + * Get all the available built-in property definitions. + */ + getBuiltInAll(): any; + /** + * Add built-in property definition. + * If the property exists already, it will extend it. + * @example + * const sector = styleManager.addBuiltIn('new-property', { + * type: 'select', + * default: 'value1', + * options: [{ id: 'value1', label: 'Some label' }, ...], + * }) + * @param prop - Property name. + * @param definition - Property definition. + * @returns Added property definition. + */ + addBuiltIn(prop: string, definition: any): any; + /** + * Add new property type + * @example + * styleManager.addType('my-custom-prop', { + * // Create UI + * create({ props, change }) { + * const el = document.createElement('div'); + * el.innerHTML = ''; + * const inputEl = el.querySelector('.my-input'); + * inputEl.addEventListener('change', event => change({ event })); + * inputEl.addEventListener('input', event => change({ event, partial: true })); + * return el; + * }, + * // Propagate UI changes up to the targets + * emit({ props, updateStyle }, { event, partial }) { + * const { value } = event.target; + * updateStyle(`${value}px`, { partial }); + * }, + * // Update UI (eg. when the target is changed) + * update({ value, el }) { + * el.querySelector('.my-input').value = parseInt(value, 10); + * }, + * // Clean the memory from side effects if necessary (eg. global event listeners, etc.) + * destroy() {} + * }) + * @param id - Type ID + * @param definition - Definition of the type. + */ + addType(id: string, definition: any): void; + /** + * Get type + * @param id - Type ID + * @returns Type definition + */ + getType(id: string): any; + /** + * Get all types + */ + getTypes(): any[]; + } + + interface SectorOptions { + /** + * Sector id, eg. `typography` + */ + id: string; + /** + * Sector name, eg. `Typography` + */ + name: string; + /** + * Indicates the open state. + * @defaultValue true + */ + open?: boolean; + /** + * Indicate an array of Property defintions. + * @defaultValue [] + */ + properties?: AnyProperty[]; + } + + interface Sector extends Backbone.Model { + /** + * Get sector id + */ + getId(): string; + + /** + * Get sector name + */ + getName(): string; + + /** + * Update sector name. + * @param value - New sector name + */ + setName(value: string): void; + + /** + * Check if the sector is open + */ + isOpen(): boolean; + + /** + * Update Sector open state + */ + setOpen(value: boolean): void; + + /** + * Check if the sector is visible + */ + isVisible(): boolean; + + /** + * Get sector properties. + * @param [opts = {}] - Options + * @param [opts.withValue = false] - Get only properties with value + * @param [opts.withParentValue = false] - Get only properties with parent value + */ + getProperties(opts?: { + withValue?: boolean; + withParentValue?: boolean; + }): AnyProperty[]; + } + + interface PropertyOptions { + + /** + * Property id, eg. `my-property-id`. + */ + id: string; + /** + * Related CSS property name, eg. `text-align`. + */ + property: string; + /** + * Defaul value of the property. + */ + default: string; + /** + * Label to use in UI, eg. `Text Align`. + */ + label: string; + /** + * Change callback. + \n + ```js + onChange: ({ property, from, to }) => { + console.log(`Changed property`, property.getName(), { from, to }); + } + ``` + */ + onChange?: (...params: any[]) => any; + } + + interface Property extends Backbone.Model { + /** + * Get property id + */ + getId(): string; + + /** + * Get the property type. + * The type of the property is defined on property creation and based on its value the proper Property class is assigned. + * The default type is `base`. + */ + getType(): string; + + /** + * Get name (the CSS property name). + */ + getName(): string; + + /** + * Get property label. + * @param {Object} [opts={}] Options + * @param {Boolean} [opts.locale=true] Use the locale string from i18n module + */ + getLabel(opts?: {locale?: boolean}): string; + + /** + * Get property value. + * @param [opts = {}] - Options + * @param [opts.noDefault = false] - Avoid returning the default value + */ + getValue(opts?: { + noDefault?: boolean; + }): string; + + /** + * Check if the property has value. + * @param [opts = {}] - Options + * @param [opts.noParent = false] - Ignore the value if it comes from the parent target. + */ + hasValue(opts?: { + noParent?: boolean; + }): boolean; + + /** + * Indicates if the current value is coming from a parent target (eg. another CSSRule). + */ + hasValueParent(): boolean; + + /** + * Get the CSS style object of the property. + * @param {Object} [opts={}] Options + * @param {Boolean} [opts.camelCase] Return property name in camelCase. + * @example + * // In case the property is `color` with a value of `red`. + * console.log(property.getStyle()); + * // { color: 'red' }; + */ + getStyle(opts?: {camelCase?: boolean}): any; + + /** + * Get the default value. + */ + getDefaultValue(): string; + + /** + * Update the value. + * The change is also propagated to the selected targets (eg. CSS rule). + * @param value - New value + * @param [opts = {}] - Options + * @param [opts.partial = false] - If `true` the update on targets won't be considered complete (not stored in UndoManager) + * @param [opts.noTarget = false] - If `true` the change won't be propagated to selected targets. + */ + upValue(value: string, opts?: { + partial?: boolean; + noTarget?: boolean; + }): void; + + /** + * Check if the sector is visible + */ + isVisible(): boolean; + + /** + * Clear the value. + * The change is also propagated to the selected targets (eg. the css property is cleared). + * @param [opts = {}] - Options + * @param [opts.noTarget = false] - If `true` the change won't be propagated to selected targets. + */ + clear(opts?: { + noTarget?: boolean; + }): void; + + /** + * Indicates if the current value comes directly from the selected target and so can be cleared. + */ + canClear(): boolean; + + /** + * If the current property is a sub-property, this will return the parent Property. + */ + getParent(): any; + + /** + * Indicates if the property is full-width in UI. + */ + isFull(): boolean; + } + + interface PropertyNumberOptions extends PropertyOptions { + /** + * Array of units, eg. `['px', '%']` + */ + units: String[]; + /** + * Minimum value. + */ + min: number; + /** + * Maximum value. + */ + max: number; + /** + * Step value. + */ + step: number; + } + + interface PropertyNumber extends Property { + /** + * Get property units. + */ + getUnits(): String[]; + + /** + * Get property unit value. + */ + getUnit(): string; + + /** + * Get min value. + */ + getMin(): number; + + /** + * Get max value. + */ + getMax(): number; + + /** + * Get step value. + */ + getStep(): number; + + /** + * Update property unit value. + * The change is also propagated to the selected targets. + * @param unit - New unit value + * @param [opts = {}] - Options + * @param [opts.noTarget = false] - If `true` the change won't be propagated to selected targets. + */ + upUnit(unit: string, opts?: { + noTarget?: boolean; + }): string; + } + + interface SelectOption { + id?: string + value?: string + label? : string + name?: string + } + + interface PropertySelectOptions extends PropertyOptions { + /** + * Array of option definitions. + \n + ```js + options: [ + { id: '100', label: 'Set 100' }, + { id: '200', label: 'Set 200' }, + ] + ``` + */ + options: SelectOption[]; + } + + interface PropertySelect extends Property { + /** + * Get available options. + * @returns Array of options + */ + getOptions(): SelectOption[]; + + /** + * Get current selected option or by id. + * @param [id] - Option id. + */ + getOption(id?: string): any | null; + + /** + * Update options. + * @param value - New array of options, eg. `[{ id: 'val-1', label: 'Value 1' }]` + */ + setOptions(value: SelectOption[]): void; + + /** + * Add new option. + * @param value - Option object, eg. `{ id: 'val-1', label: 'Value 1' }` + */ + addOption(value: SelectOption): void; + + /** + * Get the option id from the option object. + * @param option - Option object + * @returns Option id + */ + getOptionId(option: SelectOption): string; + + /** + * Get option label. + * @param id - Option id or the option object + * @param [opts = {}] - Options + * @param [opts.locale = true] - Use the locale string from i18n module + * @returns Option label + */ + getOptionLabel(id: string | any, opts?: { + locale?: boolean; + }): string; + } + + interface PropertyCompositeOptions extends PropertyOptions { + + /** + * Array of sub properties, eg. `[{ type: 'number', property: 'margin-top' }, ...]` + */ + properties: AnyProperty[]; + /** + * Indicate if the final CSS property is splitted (detached: `margin-top: X; margin-right: Y; ...`) or combined (not detached: `margin: X Y ...;`) + */ + detached?: boolean; + /** + * Value used to split property values, default `" "`. + * @defaultValue ' ' + */ + separator?: string | RegExp; + /** + * Value used to join property values, default `" "`. + * @defaultValue ' ' + */ + join?: string; + /** + * Custom logic for getting property values from the target style object. + \n + ```js + fromStyle: (style) => { + const margins = parseMarginShorthand(style.margin); + return { + 'margin-top': margins.top, + // ... + }; + } + ``` + */ + fromStyle?: (style : Record) => Record; + /** + * Custom logic for creating the CSS style object to apply on selected targets. + \n + ```js + toStyle: (values) => { + const top = values['margin-top'] || 0; + const right = values['margin-right'] || 0; + // ... + return { + margin: `${top} ${right} ...`, + }; + } + ``` + */ + toStyle?: (values : Record) => Record; + } + interface PropertyComposite extends Property { + /** + * Get properties. + */ + getProperties(): AnyProperty[]; + + /** + * Get property by id. + * @param id - Property id. + */ + getProperty(id: string): any; + + /** + * Get property at index. + */ + getPropertyAt(index: number): any; + + /** + * Check if the property is detached. + */ + isDetached(): boolean; + + /** + * Get current values of properties. + * @example + * // In case the property is `margin` with sub properties like `margin-top`, `margin-right`, etc. + * console.log(property.getValues()); + * // { 'margin-top': '10px', 'margin-right': '20px', ... }; + * @param [opts = {}] - Options + * @param [opts.byName = false] - Use property names as a key instead of the id. + */ + getValues(opts?: { + byName?: boolean; + }): any; + + /** + * Get property separator. + */ + getSeparator(): RegExp; + + /** + * Get the join value. + */ + getJoin(): string; + } + + type AnyProperty = Property | PropertyNumber | PropertySelect | PropertyComposite | PropertyStack; + + interface Layer extends Backbone.Model<{}> { + /** + * Get layer id. + */ + getId() : string + + /** + * Get layer index. + */ + getIndex() : number + + /** + * Get layer values. + * @param {Object} [opts={}] Options + * @param {Boolean} [opts.camelCase] Return property names in camelCase. + */ + getValues(opts?: {camelCase? : boolean}) : any + + /** + * Get layer label. + */ + getLabel() : string + + /** + * Check if the layer is selected. + */ + isSelected() : boolean + + /** + * Select the layer. + */ + select() : any + + /** + * Remove the layer. + */ + remove() : any + + /** + * Move layer to a new index. + * @param index New index + */ + move(index : number) : any + + /** + * Get style object for the preview. + * @param [opts={}] Options. Same of `PropertyStack.getStyleFromLayer` + * @returns Style object + */ + getStylePreview(opts: object) : any + + /** + * Check if the property has the preview enabled for this layer. + */ + hasPreview() : boolean + } + + interface PropertyStackOptions extends PropertyCompositeOptions { + /** + * Indicate if the layer should display a preview. + */ + preview?: boolean; + /** + * The separator used to split layer values. + * @defaultValue ', ' + */ + layerSeparator?: string | RegExp; + /** + * Value used to join layer values. + * @defaultValue ', ' + */ + layerJoin?: string; + /** + * Custom logic for creating layer labels. + \n + ```js + layerLabel: (layer) => { + const values = layer.getValues(); + return `A: ${values['prop-a']} B: ${values['prop-b']}`; + } + ``` + */ + layerLabel?: (...params: any[]) => any; + } + + interface PropertyStack extends PropertyComposite { + /** + * Get all available layers. + */ + getLayers(): Layer[]; + + /** + * Get layer by index. + * @example + * // Get the first layer + * const layerFirst = property.getLayer(0); + * // Get the last layer + * const layers = this.getLayers(); + * const layerLast = property.getLayer(layers.length - 1); + * @param [index = 0] - Layer index position. + */ + getLayer(index?: number): Layer | null; + + /** + * Get selected layer. + */ + getSelectedLayer(): Layer | null; + + /** + * Select layer. + * Without a selected layer any update made on inner properties has no effect. + * @example + * const layer = property.getLayer(0); + * property.selectLayer(layer); + * @param layer Layer to select + */ + selectLayer(layer: Layer): void; + + /** + * Select layer by index. + * @example + * property.selectLayerAt(1); + * @param index - Index of the layer to select. + */ + selectLayerAt(index: number): void; + + /** + * Move layer by index. + * @example + * const layer = property.getLayer(1); + * property.moveLayer(layer, 0); + * @param index - New layer index. + */ + moveLayer(layer: Layer, index: number): void; + + /** + * Add new layer to the stack. + * @example + * // Add new layer at the beginning of the stack with custom values + * property.addLayer({ 'sub-prop1': 'value1', 'sub-prop2': 'value2' }, { at: 0 }); + * @param [props = {}] - Custom property values to use in a new layer. + * @param [opts = {}] - Options + * @param [opts.at] - Position index (by default the layer will be appended at the end). + */ + addLayer(props?: any, opts?: { + at?: number; + }): Layer; + + /** + * Remove layer. + * @example + * const layer = property.getLayer(0); + * property.removeLayer(layer); + */ + removeLayer(layer: Layer): Layer; + + /** + * Remove layer by index. + * @example + * property.removeLayerAt(0); + * @param index - Index of the layer to remove + */ + removeLayerAt(index: number): Layer | null; + + /** + * Get the layer label. The label can be customized with the `layerLabel` property. + * @example + * const layer = this.getLayer(1); + * const label = this.getLayerLabel(layer); + */ + getLayerLabel(layer: Layer): string; + + /** + * Get style object from the layer. + * @param [opts = {}] - Options + * @param [opts.camelCase] - Return property names in camelCase. + * @param [opts.number] - Limit the result of the number types, eg. `number: { min: -3, max: 3 }` + * @returns Style object + */ + getStyleFromLayer(layer: Layer, opts?: { + camelCase?: boolean; + number?: any; + }): any; + + /** + * Get preview style object from the layer. + * If the property has `preview: false` the returned object will be empty. + * @param [opts = {}] - Options. Same of `getStyleFromLayer` + * @returns Style object + */ + getStylePreview(layer: Layer, opts?: any): any; + + /** + * Get layer separator. + */ + getLayerSeparator(): RegExp; + } + + /** + * 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/storage_manager/config/config.js) + * ```js + * const editor = grapesjs.init({ + * storageManager: { + * // options + * } + * }) + * ``` + * + * Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance. + * + * ```js + * // Listen to events + * editor.on('storage:start', () => { ... }); + * + * // Use the API + * const storageManager = editor.StorageManager; + * storageManager.add(...); + * ``` + * + * ## Available Events + * * `storage:start` - Before the storage request is started + * * `storage:start:store` - Before the store request. The object to store is passed as an argumnet (which you can edit) + * * `storage:start:load` - Before the load request. Items to load are passed as an argumnet (which you can edit) + * * `storage:load` - Triggered when something was loaded from the storage, loaded object passed as an argumnet + * * `storage:store` - Triggered when something is stored to the storage, stored object passed as an argumnet + * * `storage:end` - After the storage request is ended + * * `storage:end:store` - After the store request + * * `storage:end:load` - After the load request + * * `storage:error` - On any error on storage request, passes the error as an argument + * * `storage:error:store` - Error on store request, passes the error as an argument + * * `storage:error:load` - Error on load request, passes the error as an argument + * + * ## Methods + * * [getConfig](#getconfig) + * * [isAutosave](#isautosave) + * * [setAutosave](#setautosave) + * * [getStepsBeforeSave](#getstepsbeforesave) + * * [setStepsBeforeSave](#setstepsbeforesave) + * * [setStepsBeforeSave](#setstepsbeforesave) + * * [getStorages](#getstorages) + * * [getCurrent](#getcurrent) + * * [getCurrentStorage](#getcurrentstorage) + * * [setCurrent](#setcurrent) + * * [add](#add) + * * [get](#get) + * * [store](#store) + * * [load](#load) + */ + interface StorageManager { + /** + * Get configuration object + */ + getConfig(): StorageManagerConfig; + /** + * Checks if autosave is enabled + */ + isAutosave(): boolean; + /** + * Set autosave value + */ + setAutosave(v: boolean): this; + /** + * Returns number of steps required before trigger autosave + */ + getStepsBeforeSave(): number; + /** + * Set steps required before trigger autosave + */ + setStepsBeforeSave(v: number): this; + /** + * Add new storage + * @example + * storageManager.add('local2', { + * load: function(keys, clb, clbErr) { + * var res = {}; + * for (var i = 0, len = keys.length; i < len; i++){ + * var v = localStorage.getItem(keys[i]); + * if(v) res[keys[i]] = v; + * } + * clb(res); // might be called inside some async method + * // In case of errors... + * // clbErr('Went something wrong'); + * }, + * store: function(data, clb, clbErr) { + * for(var key in data) + * localStorage.setItem(key, data[key]); + * clb(); // might be called inside some async method + * } + * }); + * @param id - Storage ID + * @param storage - Storage wrapper + * @param storage.load - Load method + * @param storage.store - Store method + */ + add(id: string, storage: { + load: (...params: any[]) => any; + store: (...params: any[]) => any; + }): this; + /** + * Returns storage by id + * @param id - Storage ID + */ + get(id: string): any | null; + /** + * Returns all storages + */ + getStorages(): any[]; + /** + * Returns current storage type + */ + getCurrent(): string; + /** + * Set current storage type + * @param id - Storage ID + */ + setCurrent(id: string): this; + /** + * Store key-value resources in the current storage + * @example + * storageManager.store({item1: value1, item2: value2}); + * @param data - Data in key-value format, eg. {item1: value1, item2: value2} + * @param clb - Callback function + */ + store(data: any, clb: (...params: any[]) => any): any | null; + /** + * Load resource from the current storage by keys + * @example + * storageManager.load(['item1', 'item2'], res => { + * // res -> {item1: value1, item2: value2} + * }); + * storageManager.load('item1', res => { + * // res -> {item1: value1} + * }); + * @param keys - Keys to load + * @param clb - Callback function + */ + load(keys: string | string[], clb: (...params: any[]) => any): void; + /** + * Get current storage + */ + getCurrentStorage(): Storage; + } + + /** + * 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 + */ + interface Devices { + /** + * Add new 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 + * }); + * @param props - Device properties + */ + add(props: any): any; + /** + * Return device by ID + * @example + * const device = deviceManager.get('Tablet'); + * console.log(JSON.stringify(device)); + * // {name: 'Tablet', width: '900px'} + * @param id - ID of the device + */ + get(id: string): any; + /** + * Remove device + * @example + * const removed = deviceManager.remove('device-id'); + * // or by passing the Device + * const device = deviceManager.get('device-id'); + * deviceManager.remove(device); + */ + remove(): any; + /** + * Return all devices + * @example + * const devices = deviceManager.getDevices(); + * console.log(JSON.stringify(devices)); + * // [{name: 'Desktop', width: ''}, ...] + */ + getDevices(): any; + /** + * Change the selected device. This will update the frame in the canvas + * @example + * deviceManager.select('some-id'); + * // or by passing the page + * const device = deviceManager.get('some-id'); + * deviceManager.select(device); + */ + select(): void; + /** + * Get the selected device + * @example + * const selected = deviceManager.getSelected(); + */ + getSelected(): any; + } + + interface DeviceOptions { + /** + * Device type, eg. `Mobile` + * @defaultValue '' + */ + name?: string; + /** + * Width to set for the editor iframe, eg. '900px' + */ + width?: string; + /** + * Height to set for the editor iframe, eg. '600px' + * @defaultValue '' + */ + height?: string; + /** + * The width which will be used in media queries, If empty the width will be used + * @defaultValue '' + */ + widthMedia?: string; + /** + * Setup the order of media queries + */ + priority?: number; + } + + interface Device extends Backbone.Model { + getName() : string + getWidthMedia() : string + } + + /** + * Selectors in GrapesJS are used in CSS Composer inside Rules and in Components as classes. To illustrate this concept let's take + * a look at this code: + * + * ```css + * span > #send-btn.btn{ + * ... + * } + * ``` + * ```html + * + * + * + * ``` + * + * In this scenario we get: + * * span -> selector of type `tag` + * * send-btn -> selector of type `id` + * * btn -> selector of type `class` + * + * So, for example, being `btn` the same class entity it'll be easier to refactor and track things. + * + * 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/selector_manager/config/config.js) + * ```js + * const editor = grapesjs.init({ + * selectorManager: { + * // options + * } + * }) + * ``` + * + * Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance. + * + * ```js + * // Listen to events + * editor.on('selector:add', (selector) => { ... }); + * + * // Use the API + * const sm = editor.Selectors; + * sm.add(...); + * ``` + * + * ## Available Events + * * `selector:add` - Selector added. The [Selector] is passed as an argument to the callback. + * * `selector:remove` - Selector removed. The [Selector] is passed as an argument to the callback. + * * `selector:update` - Selector updated. The [Selector] and the object containing changes are passed as arguments to the callback. + * * `selector:state` - States changed. An object containing all the available data about the triggered event is passed as an argument to the callback. + * * `selector` - 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 + * * [getConfig](#getconfig) + * * [add](#add) + * * [get](#get) + * * [remove](#remove) + * * [getAll](#getall) + * * [setState](#setstate) + * * [getState](#getstate) + * * [getStates](#getstates) + * * [setStates](#setstates) + * * [getSelected](#getselected) + * * [addSelected](#addselected) + * * [removeSelected](#removeselected) + * * [getSelectedTargets](#getselectedtargets) + * * [setComponentFirst](#setcomponentfirst) + * * [getComponentFirst](#getcomponentfirst) + * + * [Selector]: selector.html + * [State]: state.html + * [Component]: component.html + * [CssRule]: css_rule.html + */ + interface SelectorManager { + /** + * Get configuration object + */ + getConfig(): SelectorManagerConfig; + /** + * Add a new selector to the collection if it does not already exist. + * You can pass selectors properties or string identifiers. + * @example + * const selector = selectorManager.add({ name: 'my-class', label: 'My class' }); + * console.log(selector.toString()) // `.my-class` + * // Same as + * const selector = selectorManager.add('.my-class'); + * console.log(selector.toString()) // `.my-class` + * @param props - Selector properties or string identifiers, eg. `{ name: 'my-class', label: 'My class' }`, `.my-cls` + * @param [opts] - Selector options + */ + add(props: any | string, opts?: SelectorOptions): any; + /** + * Get the selector by its name/type + * @example + * const selector = selectorManager.get('.my-class'); + * // Get Id + * const selectorId = selectorManager.get('#my-id'); + * @param name - Selector name or string identifier + */ + get(name: string): any; + /** + * Remove Selector. + * @example + * const removed = selectorManager.remove('.myclass'); + * // or by passing the Selector + * selectorManager.remove(selectorManager.get('.myclass')); + */ + remove(): any; + /** + * Change the selector state + * @example + * selectorManager.setState('hover'); + * @param value - State value + */ + setState(value: string): this; + /** + * Get the current selector state value + */ + getState(): string; + /** + * Get states + */ + getStates(): any; + /** + * Set a new collection of states + * @example + * const states = selectorManager.setStates([ + * { name: 'hover', label: 'Hover' }, + * { name: 'nth-of-type(2n)', label: 'Even/Odd' } + * ]); + * @param states - Array of new states + */ + setStates(states: object[]): any; + /** + * Get commonly selected selectors, based on all selected components. + * @example + * const selected = selectorManager.getSelected(); + * console.log(selected.map(s => s.toString())) + */ + getSelected(): any; + /** + * Add new selector to all selected components. + * @example + * selectorManager.addSelected('.new-class'); + * @param props - Selector properties or string identifiers, eg. `{ name: 'my-class', label: 'My class' }`, `.my-cls` + */ + addSelected(props: any | string): void; + /** + * Remove a common selector from all selected components. + * @example + * selectorManager.removeSelected('.myclass'); + */ + removeSelected(): void; + /** + * Get the array of currently selected targets. + * @example + * const targetsToStyle = selectorManager.getSelectedTargets(); + * console.log(targetsToStyle.map(target => target.getSelectorsString())) + */ + getSelectedTargets(): any; + /** + * Update component-first option. + * If the component-first is enabled, all the style changes will be applied on selected components (ID rules) instead + * of selectors (which would change styles on all components with those classes). + */ + setComponentFirst(value: boolean): void; + /** + * Get the value of component-first option. + */ + getComponentFirst(): boolean; + /** + * Get all selectors + */ + getAll(): any; + } + + interface SelectorOptions { + /** + * Selector name, eg. `my-class` + */ + name: string; + /** + * Selector label, eg. `My Class` + */ + label: string; + /** + * Type of the selector. 1 (class) | 2 (id) + * @defaultValue 1 + */ + type?: number; + /** + * If not active, it's not selectable by the Style Manager. + * @defaultValue true + */ + active?: boolean; + /** + * If true, it can't be seen by the Style Manager, but it will be rendered in the canvas and in export code. + */ + private?: boolean; + /** + * If true, it can't be removed from the attacched component. + */ + protected?: boolean; + } + + interface Selector extends Backbone.Model { + /** + * Get selector label. + * @example + * // Given such selector: { name: 'my-selector', label: 'My selector' } + * console.log(selector.getLabel()); + * // -> `My selector` + */ + getLabel(): string; + + /** + * Update selector label. + * @param {String} label New label + * @example + * // Given such selector: { name: 'my-selector', label: 'My selector' } + * selector.setLabel('New Label') + * console.log(selector.getLabel()); + * // -> `New Label` + */ + setLabel(label: string): void; + + /** + * Get selector active state. + */ + getActive(): boolean; + + /** + * Update selector active state. + * @param value - New active state + */ + setActive(value: boolean): void; + } + + interface StateOptions { + /** + * State name, eg. `hover`, `nth-of-type(2n)` + */ + name: string; + /** + * State label, eg. `Hover`, `Even/Odd` + */ + label: string; + } + + interface State extends Backbone.Model { + + /** + * Get state name + */ + getName(): string; + + /** + * Get state label. If label was not provided, the name will be returned. + */ + getLabel(): string; + } + + /** + * This module manages CSS rules in the canvas. + * 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/css_composer/config/config.js) + * ```js + * const editor = grapesjs.init({ + * cssComposer: { + * // 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 css = editor.Css; + * ``` + * + * * [addRules](#addrules) + * * [setRule](#setrule) + * * [getRule](#getrule) + * * [getRules](#getrules) + * * [remove](#remove) + * * [clear](#clear) + * + * [CssRule]: css_rule.html + */ + interface CssComposer { + /** + * Add CssRules via CSS string. + * @example + * const addedRules = css.addRules('.my-cls{ color: red } @media (max-width: 992px) { .my-cls{ color: darkred } }'); + * // Check rules + * console.log(addedRules.map(rule => rule.toCSS())); + * @param css - CSS string of rules to add. + */ + addRules(css: string): any; + /** + * Add/update the CssRule. + * @example + * // Simple class-based rule + * const rule = css.setRule('.class1.class2', { color: 'red' }); + * console.log(rule.toCSS()) // output: .class1.class2 { color: red } + * // With state and other mixed selector + * const rule = css.setRule('.class1.class2:hover, div#myid', { color: 'red' }); + * // output: .class1.class2:hover, div#myid { color: red } + * // With media + * const rule = css.setRule('.class1:hover', { color: 'red' }, { + * atRuleType: 'media', + * atRuleParams: '(min-width: 500px)', + * }); + * // output: @media (min-width: 500px) { .class1:hover { color: red } } + * @param selectors - Selector string, eg. `.myclass` + * @param style - Style properties and values + * @param [opts = {}] - Additional properties + * @param [opts.atRuleType = ''] - At-rule type, eg. `media` + * @param [opts.atRuleParams = ''] - At-rule parameters, eg. `(min-width: 500px)` + */ + setRule(selectors: string, style: any, opts?: { + atRuleType?: string; + atRuleParams?: string; + }): any; + /** + * Get the CssRule. + * @example + * const rule = css.getRule('.myclass1:hover'); + * const rule2 = css.getRule('.myclass1:hover, div#myid'); + * const rule3 = css.getRule('.myclass1', { + * atRuleType: 'media', + * atRuleParams: '(min-width: 500px)', + * }); + * @param selectors - Selector string, eg. `.myclass:hover` + * @param [opts = {}] - Additional properties + * @param [opts.atRuleType = ''] - At-rule type, eg. `media` + * @param [opts.atRuleParams = ''] - At-rule parameters, eg. '(min-width: 500px)' + */ + getRule(selectors: string, opts?: { + atRuleType?: string; + atRuleParams?: string; + }): any; + /** + * Get all rules or filtered by a matching selector. + * @example + * // Take all the component specific rules + * const id = someComponent.getId(); + * const rules = css.getRules(`#${id}`); + * console.log(rules.map(rule => rule.toCSS())) + * // All rules in the project + * console.log(css.getRules()) + * @param [selector = ''] - Selector, eg. `.myclass` + */ + getRules(selector?: string): any; + /** + * Remove rule, by CssRule or matching selector (eg. the selector will match also at-rules like `@media`) + * @example + * // Remove by CssRule + * const toRemove = css.getRules('.my-cls'); + * css.remove(toRemove); + * // Remove by selector + * css.remove('.my-cls-2'); + */ + remove(): any; + /** + * Remove all rules + */ + clear(): this; + } + + interface Styleable { + /** + * To trigger the style change event on models I have to + * pass a new object instance + * @param prop + */ + extendStyle(prop : object) : object + + /** + * Get style object + */ + getStyle(prop? : string) : object + + /** + * Set new style object + * @return {Object} Applied properties + */ + setStyle(prop : object | string, opts?: object) : object + + /** + * Add style property + * @example + * this.addStyle({color: 'red'}); + * this.addStyle('color', 'blue'); + */ + addStyle(prop : object | string, value?: string, opts?: object) : void + + /** + * Remove style property + */ + removeStyle(prop : string) : void + + /** + * Returns string of style properties + */ + styleToString(opts?: object) : string + } + + interface CssRuleOptions { + /** + * Array of selectors + */ + selectors: Selector[]; + /** + * Object containing style definitions + */ + style: any; + /** + * Additional string css selectors + * @defaultValue '' + */ + selectorsAdd?: string; + /** + * Type of at-rule, eg. `media`, 'font-face' + * @defaultValue '' + */ + atRuleType?: string; + /** + * At-rule value, eg. `(max-width: 1000px)` + * @defaultValue '' + */ + mediaText?: string; + /** + * This property is used only on at-rules, like 'page' or 'font-face', where the block containes only style declarations + */ + singleAtRule?: boolean; + /** + * State of the rule, eg: `hover`, `focused` + * @defaultValue '' + */ + state?: string; + /** + * If true, sets `!important` on all properties. You can also pass an array to specify properties on which use important + */ + important?: boolean | String[]; + /** + * Indicates if the rule is stylable from the editor + + [Device]: device.html + [State]: state.html + [Component]: component.html + * @defaultValue true + */ + stylable?: boolean; + } + interface CssRule extends Backbone.Model, Styleable { + /** + * Returns the at-rule statement when exists, eg. `@media (...)`, `@keyframes` + * @example + * const cssRule = editor.Css.setRule('.class1', { color: 'red' }, { + * atRuleType: 'media', + * atRuleParams: '(min-width: 500px)' + * }); + * cssRule.getAtRule(); // "@media (min-width: 500px)" + */ + getAtRule(): string; + + /** + * Return selectors of the rule as a string + * @example + * const cssRule = editor.Css.setRule('.class1:hover', { color: 'red' }); + * cssRule.selectorsToString(); // ".class1:hover" + * cssRule.selectorsToString({ skipState: true }); // ".class1" + * @param [opts] - Options + * @param [opts.skipState] - Skip state from the result + */ + selectorsToString(opts?: { + skipState?: boolean; + }): string; + + /** + * Get declaration block (without the at-rule statement) + * @example + * const cssRule = editor.Css.setRule('.class1', { color: 'red' }, { + * atRuleType: 'media', + * atRuleParams: '(min-width: 500px)' + * }); + * cssRule.getDeclaration() // ".class1{color:red;}" + * @param [opts = {}] - Options (same as in `selectorsToString`) + */ + getDeclaration(opts?: any): string; + + /** + * Get the Device the rule is related to. + * @example + * const device = rule.getDevice(); + * console.log(device?.getName()); + */ + getDevice(): Device | null; + + /** + * Get the State the rule is related to. + * @example + * const state = rule.getState(); + * console.log(state?.getLabel()); + */ + getState(): State | null; + + /** + * Returns the related Component (valid only for component-specific rules). + * @example + * const cmp = rule.getComponent(); + * console.log(cmp?.toHTML()); + */ + getComponent(): Component | null; + + /** + * Return the CSS string of the rule + * @example + * const cssRule = editor.Css.setRule('.class1', { color: 'red' }, { + * atRuleType: 'media', + * atRuleParams: '(min-width: 500px)' + * }); + * cssRule.toCSS() // "@media (min-width: 500px){.class1{color:red;}}" + * @param [opts = {}] - Options (same as in `getDeclaration`) + * @returns CSS string + */ + toCSS(opts?: any): string; + } + + /** + * 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) + */ + interface Modal { + /** + * Open the modal window + * @example + * modal.open({ + * title: 'My title', + * content: 'My content', + * attributes: { class: 'my-class' }, + * }); + * @param [opts = {}] - Options + * @param [opts.title] - Title to set for the modal + * @param [opts.content] - Content to set for the modal + * @param [opts.attributes] - Updates the modal wrapper with custom attributes + */ + open(opts?: { + title?: string | HTMLElement; + content?: string | HTMLElement; + attributes?: any; + }): this; + /** + * Close the modal window + * @example + * modal.close(); + */ + close(): this; + /** + * Execute callback when the modal will be closed. + * The callback will be called one only time + * @example + * modal.onceClose(() => { + * console.log('The modal is closed'); + * }); + * @param clb - Callback to call + */ + onceClose(clb: (...params: any[]) => any): this; + /** + * Execute callback when the modal will be opened. + * The callback will be called one only time + * @example + * modal.onceOpen(() => { + * console.log('The modal is opened'); + * }); + * @param clb - Callback to call + */ + onceOpen(clb: (...params: any[]) => any): this; + /** + * Checks if the modal window is open + * @example + * modal.isOpen(); // true | false + */ + isOpen(): boolean; + /** + * Set the title to the modal window + * @example + * // pass a string + * modal.setTitle('Some title'); + * // or an HTMLElement + * const el = document.createElement('div'); + * el.innerText = 'New title'; + * modal.setTitle(el); + * @param title - Title + */ + setTitle(title: string | HTMLElement): this; + /** + * Returns the title of the modal window + * @example + * modal.getTitle(); + */ + getTitle(): string | HTMLElement; + /** + * Set the content of the modal window + * @example + * // pass a string + * modal.setContent('Some content'); + * // or an HTMLElement + * const el = document.createElement('div'); + * el.innerText = 'New content'; + * modal.setContent(el); + * @param content - Content + */ + setContent(content: string | HTMLElement): this; + /** + * Get the content of the modal window + * @example + * modal.getContent(); + */ + getContent(): string | HTMLElement; + } + + /** + * This module allows to customize the built-in toolbar of the Rich Text Editor and use commands from the [HTML Editing APIs](https://developer.mozilla.org/en-US/docs/Web/API/Document/execCommand). + * It's highly recommended to keep this toolbar as small as possible, especially from styling commands (eg. 'fontSize') and leave this task to the Style Manager + * + * 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/rich_text_editor/config/config.js) + * ```js + * const editor = grapesjs.init({ + * richTextEditor: { + * // options + * } + * }) + * ``` + * + * Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance. + * + * ```js + * // Listen to events + * editor.on('rte:enable', () => { ... }); + * + * // Use the API + * const rte = editor.RichTextEditor; + * rte.add(...); + * ``` + * + * ## Available Events + * * `rte:enable` - RTE enabled. The view, on which RTE is enabled, is passed as an argument + * * `rte:disable` - RTE disabled. The view, on which RTE is disabled, is passed as an argument + * + * ## Methods + * * [add](#add) + * * [get](#get) + * * [getAll](#getall) + * * [remove](#remove) + * * [getToolbarEl](#gettoolbarel) + */ + interface RichTextEditor { + /** + * Add a new action to the built-in RTE toolbar + * @example + * rte.add('bold', { + * icon: 'B', + * attributes: {title: 'Bold'}, + * result: rte => rte.exec('bold') + * }); + * rte.add('link', { + * icon: document.getElementById('t'), + * attributes: {title: 'Link',} + * // Example on it's easy to wrap a selected content + * result: rte => rte.insertHTML(`${rte.selection()}`) + * }); + * // An example with fontSize + * rte.add('fontSize', { + * icon: ``, + * // Bind the 'result' on 'change' listener + * event: 'change', + * result: (rte, action) => rte.exec('fontSize', action.btn.firstChild.value), + * // Callback on any input change (mousedown, keydown, etc..) + * update: (rte, action) => { + * const value = rte.doc.queryCommandValue(action.name); + * if (value != 'false') { // value is a string + * action.btn.firstChild.value = value; + * } + * } + * }) + * // An example with state + * const isValidAnchor = (rte) => { + * // a utility function to help determine if the selected is a valid anchor node + * const anchor = rte.selection().anchorNode; + * const parentNode = anchor && anchor.parentNode; + * const nextSibling = anchor && anchor.nextSibling; + * return (parentNode && parentNode.nodeName == 'A') || (nextSibling && nextSibling.nodeName == 'A') + * } + * rte.add('toggleAnchor', { + * icon: ``, + * state: (rte, doc) => { + * if (rte && rte.selection()) { + * // `btnState` is a integer, -1 for disabled, 0 for inactive, 1 for active + * return isValidAnchor(rte) ? btnState.ACTIVE : btnState.INACTIVE; + * } else { + * return btnState.INACTIVE; + * } + * }, + * result: (rte, action) => { + * if (isValidAnchor(rte)) { + * rte.exec('unlink'); + * } else { + * rte.insertHTML(`${rte.selection()}`); + * } + * } + * }) + * @param name - Action name + * @param action - Action options + */ + add(name: string, action: any): void; + /** + * Get the action by its name + * @example + * const action = rte.get('bold'); + * // {name: 'bold', ...} + * @param name - Action name + */ + get(name: string): any; + /** + * Get all actions + */ + getAll(): any[]; + /** + * Remove the action from the toolbar + * @example + * const action = rte.remove('bold'); + * // {name: 'bold', ...} + * @returns Removed action + */ + remove(name: string): any; + /** + * Get the toolbar element + */ + getToolbarEl(): HTMLElement; + } + + /** + * You can customize the initial state of the module from the editor initialization + * ```js + * const editor = grapesjs.init({ + * keymaps: { + * // Object of keymaps + * defaults: { + * 'your-namespace:keymap-name' { + * keys: '⌘+z, ctrl+z', + * handler: 'some-command-id' + * }, + * ... + * } + * } + * }) + * ``` + * + * Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance. + * + * ```js + * // Listen to events + * editor.on('keymap:add', () => { ... }); + * + * // Use the API + * const keymaps = editor.Keymaps; + * keymaps.add(...); + * ``` + * + * ## Available Events + * * `keymap:add` - New keymap added. The new keyamp object is passed as an argument + * * `keymap:remove` - Keymap removed. The removed keyamp object is passed as an argument + * * `keymap:emit` - Some keymap emitted, in arguments you get keymapId, shortcutUsed, Event + * * `keymap:emit:{keymapId}` - `keymapId` emitted, in arguments you get keymapId, shortcutUsed, Event + * + * ## Methods + * * [getConfig](#getconfig) + * * [add](#add) + * * [get](#get) + * * [getAll](#getAll) + * * [remove](#remove) + * * [removeAll](#removeall) + */ + interface Keymaps { + /** + * Get module configurations + * @returns Configuration object + */ + getConfig(): any; + /** + * Add new keymap + * @example + * // 'ns' is just a custom namespace + * keymaps.add('ns:my-keymap', '⌘+j, ⌘+u, ctrl+j, alt+u', editor => { + * console.log('do stuff'); + * }); + * // or + * keymaps.add('ns:my-keymap', '⌘+s, ctrl+s', 'some-gjs-command'); + * + * // listen to events + * editor.on('keymap:emit', (id, shortcut, e) => { + * // ... + * }) + * @param id - Keymap id + * @param keys - Keymap keys, eg. `ctrl+a`, `⌘+z, ctrl+z` + * @param handler - Keymap handler, might be a function + * @param [opts = {}] - Options + * @returns Added keymap + * or just a command id as a string + */ + add(id: string, keys: string, handler: ((...params: any[]) => any) | string, opts?: any): any; + /** + * Get the keymap by id + * @example + * keymaps.get('ns:my-keymap'); + * // -> {keys, handler}; + * @param id - Keymap id + * @returns Keymap object + */ + get(id: string): any; + /** + * Get all keymaps + * @example + * keymaps.getAll(); + * // -> {id1: {}, id2: {}}; + */ + getAll(): any; + /** + * Remove the keymap by id + * @example + * keymaps.remove('ns:my-keymap'); + * // -> {keys, handler}; + * @param id - Keymap id + * @returns Removed keymap + */ + remove(id: string): any; + /** + * Remove all binded keymaps + */ + removeAll(): Keymaps; + } + + /** + * This module allows to manage the stack of changes applied in canvas. + * Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance + * + * ```js + * const um = editor.UndoManager; + * ``` + * + * * [getConfig](#getconfig) + * * [add](#add) + * * [remove](#remove) + * * [removeAll](#removeall) + * * [start](#start) + * * [stop](#stop) + * * [undo](#undo) + * * [undoAll](#undoall) + * * [redo](#redo) + * * [redoAll](#redoall) + * * [hasUndo](#hasundo) + * * [hasRedo](#hasredo) + * * [getStack](#getstack) + * * [clear](#clear) + */ + interface UndoManager { + /** + * Get module configurations + * @example + * const config = um.getConfig(); + * // { ... } + * @returns Configuration object + */ + getConfig(): any; + /** + * Add an entity (Model/Collection) to track + * Note: New Components and CSSRules will be added automatically + * @example + * um.add(someModelOrCollection); + * @param entity - Entity to track + */ + add(entity: Backbone.GenericModel | Backbone.Collection): UndoManager; + /** + * Remove and stop tracking the entity (Model/Collection) + * @example + * um.remove(someModelOrCollection); + * @param entity - Entity to remove + */ + remove(entity: Backbone.GenericModel | Backbone.Collection): UndoManager; + /** + * Remove all entities + * @example + * um.removeAll(); + */ + removeAll(): UndoManager; + /** + * Start/resume tracking changes + * @example + * um.start(); + */ + start(): UndoManager; + /** + * Stop tracking changes + * @example + * um.stop(); + */ + stop(): UndoManager; + /** + * Undo last change + * @example + * um.undo(); + */ + undo(): UndoManager; + /** + * Undo all changes + * @example + * um.undoAll(); + */ + undoAll(): UndoManager; + /** + * Redo last change + * @example + * um.redo(); + */ + redo(): UndoManager; + /** + * Redo all changes + * @example + * um.redoAll(); + */ + redoAll(): UndoManager; + /** + * Checks if exists an available undo + * @example + * um.hasUndo(); + */ + hasUndo(): boolean; + /** + * Checks if exists an available redo + * @example + * um.hasRedo(); + */ + hasRedo(): boolean; + /** + * Check if the entity (Model/Collection) to tracked + * Note: New Components and CSSRules will be added automatically + * @param entity - Entity to track + */ + isRegistered(entity: Backbone.GenericModel | Backbone.Collection): boolean; + /** + * Get stack of changes + * @example + * const stack = um.getStack(); + * stack.each(item => ...); + */ + getStack(): Backbone.Collection; + /** + * Get grouped undo manager stack. + * The difference between `getStack` is when you do multiple operations at a time, + * like appending multiple components: + * `editor.getWrapper().append(`
C1
C2
`);` + * `getStack` will return a collection length of 2. + * `getStackGroup` instead will group them as a single operation (the first + * inserted component will be returned in the list) by returning an array length of 1. + */ + getStackGroup(): any[]; + /** + * Clear the stack + * @example + * um.clear(); + */ + clear(): UndoManager; + } + + /** + * 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/canvas/config/config.js) + * ```js + * const editor = grapesjs.init({ + * canvas: { + * // options + * } + * }) + * ``` + * + * Once the editor is instantiated you can use its API and listen to its events. Before using these methods, you should get the module from the instance. + * + * ```js + * // Listen to events + * editor.on('canvas:drop', () => { ... }); + * + * // Use the API + * const canvas = editor.Canvas; + * canvas.setCoords(...); + * ``` + * ## Available Events + * * `canvas:dragenter` - When something is dragged inside the canvas, `DataTransfer` instance passed as an argument + * * `canvas:dragover` - When something is dragging on canvas, `DataTransfer` instance passed as an argument + * * `canvas:drop` - Something is dropped in canvas, `DataTransfer` instance and the dropped model are passed as arguments + * * `canvas:dragend` - When a drag operation is ended, `DataTransfer` instance passed as an argument + * * `canvas:dragdata` - On any dataTransfer parse, `DataTransfer` instance and the `result` are passed as arguments. + * By changing `result.content` you're able to customize what is dropped + * + * ## Methods + * * [getConfig](#getconfig) + * * [getElement](#getelement) + * * [getFrameEl](#getframeel) + * * [getWindow](#getwindow) + * * [getDocument](#getdocument) + * * [getBody](#getbody) + * * [setCustomBadgeLabel](#setcustombadgelabel) + * * [hasFocus](#hasfocus) + * * [scrollTo](#scrollto) + * * [setZoom](#setzoom) + * * [getZoom](#getzoom) + * * [getCoords](#getcoords) + * * [setCoords](#setcoords) + * + * [Component]: component.html + * [Frame]: frame.html + */ + interface Canvas { + /** + * Get the configuration object + * @example + * console.log(canvas.getConfig()) + * @returns Configuration object + */ + getConfig(): CanvasConfig; + /** + * Get the canvas element + */ + getElement(): HTMLElement; + /** + * Get the main frame element of the canvas + */ + getFrameEl(): HTMLIFrameElement; + /** + * Get the main frame window instance + */ + getWindow(): Window; + /** + * Get the main frame document element + */ + getDocument(): HTMLDocument; + /** + * Get the main frame body element + */ + getBody(): HTMLBodyElement; + /** + * Set custom badge naming strategy + * @example + * canvas.setCustomBadgeLabel(function(component){ + * return component.getName(); + * }); + */ + setCustomBadgeLabel(f: (...params: any[]) => any): void; + /** + * Get canvas rectangular data + */ + getRect(): any; + /** + * Check if the canvas is focused + */ + hasFocus(): boolean; + /** + * Scroll canvas to the element if it's not visible. The scrolling is + * executed via `scrollIntoView` API and options of this method are + * passed to it. For instance, you can scroll smoothly by using + * `{ behavior: 'smooth' }`. + * @example + * const selected = editor.getSelected(); + * // Scroll smoothly (this behavior can be polyfilled) + * canvas.scrollTo(selected, { behavior: 'smooth' }); + * // Force the scroll, even if the element is alredy visible + * canvas.scrollTo(selected, { force: true }); + * @param [opts = {}] - Options, same as options for `scrollIntoView` + * @param [opts.force = false] - Force the scroll, even if the element is already visible + */ + scrollTo(el: HTMLElement | Component, opts?: { + force?: boolean; + }): void; + /** + * Set canvas zoom value + * @example + * canvas.setZoom(50); // set zoom to 50% + * @param value - The zoom value, from 0 to 100 + */ + setZoom(value: number): this; + /** + * Get canvas zoom value + * @example + * canvas.setZoom(50); // set zoom to 50% + * const zoom = canvas.getZoom(); // 50 + */ + getZoom(): number; + /** + * Set canvas position coordinates + * @example + * canvas.setCoords(100, 100); + * @param x - Horizontal position + * @param y - Vertical position + */ + setCoords(x: number, y: number): this; + /** + * Get canvas position coordinates + * @example + * canvas.setCoords(100, 100); + * const coords = canvas.getCoords(); + * // { x: 100, y: 100 } + * @returns Object containing coordinates + */ + getCoords(): any; + /** + * Add new frame to the canvas + * @example + * canvas.addFrame({ + * name: 'Mobile home page', + * x: 100, // Position in canvas + * y: 100, + * width: 500, // Frame dimensions + * height: 600, + * // device: 'DEVICE-ID', + * components: [ + * '

Title frame

', + * '

Paragraph frame

', + * ], + * styles: ` + * .testh { color: red; } + * .testp { color: blue; } + * `, + * }); + * @param props - Frame properties + */ + addFrame(props: any): any; + } + + interface FrameOptions { + /** + * Wrapper component definition. You can also pass an HTML string as components of the default wrapper component. + */ + component: any | string; + /** + * Width of the frame. By default, the canvas width will be taken. + * @defaultValue '' + */ + width?: string; + /** + * Height of the frame. By default, the canvas height will be taken. + * @defaultValue '' + */ + height?: string; + /** + * Horizontal position of the frame in the canvas. + */ + x?: number; + /** + * Vertical position of the frame in the canvas. + */ + y?: number; + } + + interface Frame extends Backbone.Model { + + } + + /** + * 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/i18n/config.js) + * ```js + * const editor = grapesjs.init({ + * i18n: { + * locale: 'en', + * localeFallback: 'en', + * messages: { + * it: { hello: 'Ciao', ... }, + * ... + * } + * } + * }) + * ``` + * + * Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance + * + * ```js + * const i18n = editor.I18n; + * ``` + * + * ### Events + * * `i18n:add` - New set of messages is added + * * `i18n:update` - The set of messages is updated + * * `i18n:locale` - Locale changed + */ + interface I18n { + /** + * Get module configurations + * @returns Configuration object + */ + getConfig(): any; + /** + * Update current locale + * @example + * i18n.setLocale('it'); + * @param locale - Locale value + */ + setLocale(locale: string): this; + /** + * Get current locale + * @returns Current locale value + */ + getLocale(): string; + /** + * Get all messages + * @example + * i18n.getMessages(); + * // -> { en: { hello: '...' }, ... } + * i18n.getMessages('en'); + * // -> { hello: '...' } + * @param [lang] - Specify the language of messages to return + * @param [opts] - Options + * @param [opts.debug] - Show warnings in case of missing language + */ + getMessages(lang?: string, opts?: { + debug?: boolean; + }): any; + /** + * Set new set of messages + * @example + * i18n.getMessages(); + * // -> { en: { msg1: 'Msg 1', msg2: 'Msg 2', } } + * i18n.setMessages({ en: { msg2: 'Msg 2 up', msg3: 'Msg 3', } }); + * // Set replaced + * i18n.getMessages(); + * // -> { en: { msg2: 'Msg 2 up', msg3: 'Msg 3', } } + * @param msg - Set of messages + */ + setMessages(msg: any): this; + /** + * Update messages + * @example + * i18n.getMessages(); + * // -> { en: { msg1: 'Msg 1', msg2: 'Msg 2', } } + * i18n.addMessages({ en: { msg2: 'Msg 2 up', msg3: 'Msg 3', } }); + * // Set updated + * i18n.getMessages(); + * // -> { en: { msg1: 'Msg 1', msg2: 'Msg 2 up', msg3: 'Msg 3', } } + * @param msg - Set of messages to add + */ + addMessages(msg: any): this; + /** + * Translate the locale message + * @example + * obj.setMessages({ + * en: { msg: 'Msg', msg2: 'Msg {test}'}, + * it: { msg2: 'Msg {test} it'}, + * }); + * obj.t('msg'); + * // -> outputs `Msg` + * obj.t('msg2', { params: { test: 'hello' } }); // use params + * // -> outputs `Msg hello` + * obj.t('msg2', { l: 'it', params: { test: 'hello' } }); // custom local + * // -> outputs `Msg hello it` + * @param key - Label to translate + * @param [opts] - Options for the translation + * @param [opts.params] - Params for the translation + * @param [opts.debug] - Show warnings in case of missing resources + */ + t(key: string, opts?: { + params?: any; + debug?: boolean; + }): string; + } + + /** + * You can customize the initial state of the module from the editor initialization + * ```js + * const editor = grapesjs.init({ + * .... + * pageManager: { + * pages: [ + * { + * id: 'page-id', + * styles: `.my-class { color: red }`, // or a JSON of styles + * component: '
My element
', // or a JSON of components + * } + * ] + * }, + * }) + * ``` + * + * Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance + * + * ```js + * const pageManager = editor.Pages; + * ``` + * + * ## Available Events + * * `page:add` - Added new page. The page is passed as an argument to the callback + * * `page:remove` - Page removed. The page is passed as an argument to the callback + * * `page:select` - New page selected. The newly selected page and the previous one, are passed as arguments to the callback + * * `page:update` - Page updated. The updated page and the object containing changes are passed as arguments to the callback + * * `page` - 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) + * * [getAll](#getall) + * * [getAllWrappers](#getallwrappers) + * * [getMain](#getmain) + * * [remove](#remove) + * * [select](#select) + * * [getSelected](#getselected) + * + * [Page]: page.html + * [Component]: component.html + */ + interface Pages { + /** + * Add new page + * @example + * const newPage = pageManager.add({ + * id: 'new-page-id', // without an explicit ID, a random one will be created + * styles: `.my-class { color: red }`, // or a JSON of styles + * component: '
My element
', // or a JSON of components + * }); + * @param props - Page properties + * @param [opts] - Options + */ + add(props: any, opts?: any): any; + /** + * Remove page + * @example + * const removedPage = pageManager.remove('page-id'); + * // or by passing the page + * const somePage = pageManager.get('page-id'); + * pageManager.remove(somePage); + */ + remove(): any; + /** + * Get page by id + * @example + * const somePage = pageManager.get('page-id'); + * @param id - Page id + */ + get(id: string): any; + /** + * Get main page (the first one available) + * @example + * const mainPage = pageManager.getMain(); + */ + getMain(): any; + /** + * Get all pages + * @example + * const arrayOfPages = pageManager.getAll(); + */ + getAll(): any; + /** + * Get wrapper components (aka body) from all pages and frames. + * @example + * const wrappers = pageManager.getAllWrappers(); + * // Get all `image` components from the project + * const allImages = wrappers.map(wrp => wrp.findType('image')).flat(); + */ + getAllWrappers(): any; + /** + * Change the selected page. This will switch the page rendered in canvas + * @example + * pageManager.select('page-id'); + * // or by passing the page + * const somePage = pageManager.get('page-id'); + * pageManager.select(somePage); + */ + select(): this; + /** + * Get the selected page + * @example + * const selectedPage = pageManager.getSelected(); + */ + getSelected(): any; + } + + interface PageOptions { + frames : Frame[] + } + + interface Page extends Backbone.Model { + /** + * Get page id + */ + getId(): string; + + /** + * Get page name + */ + getName(): string; + + /** + * Update page name + * @param value - New page name + */ + setName(value: string): void; + + /** + * Get all frames + * @example + * const arrayOfFrames = page.getAllFrames(); + */ + getAllFrames(): Frame[]; + + /** + * Get the first frame of the page (identified always as the main one) + * @example + * const mainFrame = page.getMainFrame(); + */ + getMainFrame(): Frame; + + /** + * Get the root component (usually is the `wrapper` component) from the main frame + * @example + * const rootComponent = page.getMainComponent(); + * console.log(rootComponent.toHTML()); + */ + getMainComponent(): Component; + } + + /** + * 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/parser/config/config.js) + * ```js + * const editor = grapesjs.init({ + * parser: { + * // 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 { Parser } = editor; + * ``` + * ## Available Events + * * `parse:html` - On HTML parse, an object containing the input and the output of the parser is passed as an argument + * * `parse:css` - On CSS parse, an object containing the input and the output of the parser is passed as an argument + * + * ## Methods + * * [getConfig](#getconfig) + * * [parseHtml](#parsehtml) + * * [parseCss](#parsecss) + */ + interface Parser { + /** + * Get the configuration object + * @example + * console.log(Parser.getConfig()) + * @returns Configuration object + */ + getConfig(): any; + /** + * Parse HTML string and return the object containing the Component Definition + * @example + * const resHtml = Parser.parseHtml(`
Hi
`, { + * htmlType: 'text/html', // default + * }); + * // By using the `text/html`, this will fix automatically all the HTML syntax issues + * // Indeed the final representation, in this case, will be `
Hi
` + * const resXml = Parser.parseHtml(`
Hi
`, { + * htmlType: 'application/xml', + * }); + * // This will preserve the original format as, from the XML point of view, is a valid format + * @param input - HTML string to parse + * @param [options] - Options + * @param [options.htmlType] - [HTML mime type](https://developer.mozilla.org/en-US/docs/Web/API/DOMParser/parseFromString#Argument02) to parse + * @param [options.allowScripts = false] - Allow `