diff --git a/src/editor/config/config.ts b/src/editor/config/config.ts index 2d612fad4..51a4f76d6 100644 --- a/src/editor/config/config.ts +++ b/src/editor/config/config.ts @@ -1,151 +1,462 @@ -export default { - // Style prefix - stylePrefix: 'gjs-', +import { AssetManagerConfig } from '../../asset_manager/config/config'; +import { BlockManagerConfig } from '../../block_manager/config/config'; +import { CanvasConfig } from '../../canvas/config/config'; +import { CodeManagerConfig } from '../../code_manager/config/config'; +import { CssComposerConfig } from '../../css_composer/config/config'; +import { DeviceManagerConfig } from '../../device_manager/config/config'; +import { I18nConfig } from '../../i18n/config'; +import { ParserConfig } from '../../parser/config/config'; +import { RichTextEditorConfig } from '../../rich_text_editor/config/config'; +import { UndoManagerConfig } from '../../undo_manager/config'; + +type AnyObject = Record; + +export interface EditorConfig { + /** + * Style class name prefix. + * @default 'gjs-' + */ + stylePrefix?: string; + + /** + * Selector which indicates where render the editor. + */ + container?: string | HTMLElement; + + /** + * If true, auto-render the content + * @default true + */ + autorender?: boolean; + + /** + * Array of plugins to execute on start. + * @default [] + */ + plugins?: (string | Plugin)[]; + + /** + * Custom options for plugins + * @default {} + */ + pluginsOpts?: Record; + + /** + * Init headless editor. + * @default false + */ + headless?: boolean; + + /** + * Initial project data (JSON containing your components/styles/etc) to load. + */ + projectData?: AnyObject; /** * HTML string or object of components * @deprecated Rely on `projectData` option + * @default '' */ - components: '', + components?: string; /** * CSS string or object of rules * @deprecated Rely on `projectData` option + * @default '' */ - style: '', + style?: string; /** - * If true, will fetch HTML and CSS from selected container + * If true, will fetch HTML and CSS from the selected container. * @deprecated + * @default false */ - fromElement: false, + fromElement?: boolean; /** - * Initial project data + * Show an alert before unload the page with unsaved changes + * @default true */ - projectData: null, + noticeOnUnload?: boolean; - // Show an alert before unload the page with unsaved changes - noticeOnUnload: true, - - // Show paddings and margins - showOffsets: false, + /** + * Show paddings and margins. + * @default false + */ + showOffsets?: boolean; - // Show paddings and margins on selected component - showOffsetsSelected: false, + /** + * Show paddings and margins on selected component + * @default false + */ + 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: true, + /** + * 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. + * @default true + */ + forceClass?: boolean; - // Height for the editor container - height: '900px', + /** + * Height for the editor container + * @default '900px' + */ + height?: string; - // Width for the editor container - width: '100%', + /** + * Width for the editor container + * @default '100%' + */ + 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: ['warning', 'error'], + /** + * 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. + * @default ['warning', 'error'] + */ + 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. * @deprecated in favor of `config.canvas.frameStyle` + * @default '' */ - baseCss: '', + baseCss?: string; - // CSS that could only be seen (for instance, inside the code viewer) - protectedCss: '* { box-sizing: border-box; } body {margin: 0;}', + /** + * CSS that could only be seen (for instance, inside the code viewer) + * @default '* { box-sizing: border-box; } body {margin: 0;}' + */ + 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: '', + /** + * CSS for the iframe which containing the canvas, useful if you need to customize + * something inside (eg. the style of the selected component). + * @default '' + */ + canvasCss?: string; - // Default command - defaultCommand: 'select-comp', + /** + * Default command + * @default 'select-comp' + */ + defaultCommand?: string; - // Show a toolbar when the component is selected - showToolbar: true, + /** + * Show a toolbar when the component is selected + * @default true + */ + 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: true, + /** + * If true render a select of available devices + * @default true + */ + showDevices?: boolean; - // When enabled, on device change media rules won't be created - devicePreviewMode: false, + /** + * When enabled, on device change media rules won't be created + * @default false + */ + devicePreviewMode?: boolean; - // THe condition to use for media queries, eg. 'max-width' - // Comes handy for mobile-first cases - mediaCondition: 'max-width', + /** + * The condition to use for media queries, eg. 'max-width'. + * Comes handy for mobile-first cases. + * @default 'max-width' + */ + mediaCondition?: string; - // Starting tag for variable inside scripts in Components - tagVarStart: '{[ ', + /** + * Starting tag for variable inside scripts in Components + * @deprecated Rely on 'script-props' https://grapesjs.com/docs/modules/Components-js.html#passing-properties-to-scripts + * @default '{[ ' + */ + tagVarStart?: string; - // Ending tag for variable inside scripts in Components - tagVarEnd: ' ]}', + /** + * Ending tag for variable inside scripts in Components + * @deprecated Rely on 'script-props' https://grapesjs.com/docs/modules/Components-js.html#passing-properties-to-scripts + * @default ' ]}' + */ + tagVarEnd?: string; - // When false, removes empty text nodes when parsed, unless they contain a space - keepEmptyTextNodes: false, + /** + * When false, removes empty text nodes when parsed, unless they contain a space. + * @default false + */ + keepEmptyTextNodes?: boolean; - // Return JS of components inside HTML from 'editor.getHtml()' - jsInHtml: true, + /** + * Return JS of components inside HTML from 'editor.getHtml()'. + * @default true + */ + jsInHtml?: boolean; - // Enable native HTML5 drag and drop - nativeDnD: true, + /** + * Enable native HTML5 drag and drop. + * @default true + */ + nativeDnD?: boolean; - // Enable multiple selection - multipleSelection: true, + /** + * Enable multiple component selection. + * @default true + */ + multipleSelection?: boolean; - // Pass default available options wherever `editor.getHtml()` is called - optsHtml: {}, + // TODO + /** + * Pass default available options wherever `editor.getHtml()` is called. + * @default {} + */ + optsHtml?: Record; + /** + * Pass default available options wherever `editor.getCss()` is called + * @default {} + */ + optsCss?: Record; - // Pass default available options wherever `editor.getCss()` is called - optsCss: {}, + /** + * 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; - // 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: true, + /** + * 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). + * @default true + */ + avoidDefaults?: 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: true, + /** + * (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. + * @default false + */ + clearStyles?: 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: false, + /** + * 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?: 'translate' | 'absolute'; - // 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: 0, - - // 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: [], + /** + * 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')], + * @default [] + * */ + listenToEl?: HTMLElement[]; - // Import asynchronously CSS to use as icons - cssIcons: 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css', + /** + * Import asynchronously CSS to use as icons. + * @default 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css' + * */ + cssIcons?: string; + + /** + * Experimental: don't use. + * Editor icons + */ + icons?: AnyObject; + + /** + * Configurations for I18n. + */ + i18n?: I18nConfig; + + /** + * Configurations for Undo Manager + */ + undoManager?: UndoManagerConfig | boolean; + + /** + * Configurations for Asset Manager. + */ + assetManager?: AssetManagerConfig | boolean; + + /** + * Configurations for Canvas. + */ + canvas?: CanvasConfig | boolean; + + // TODO + /** + * Configurations for Layers. + */ + layers?: AnyObject | boolean; + + // TODO + /** + * Configurations for Storage Manager. + */ + storageManager?: AnyObject | boolean; + + /** + * Configurations for Rich Text Editor. + */ + richTextEditor?: RichTextEditorConfig; + + // TODO + /** + * Configurations for DomComponents + */ + domComponents?: AnyObject; + + // TODO + /** + * Configurations for Modal Dialog. + */ + modal?: AnyObject | boolean; + + /** + * Configurations for Code Manager. + */ + codeManager?: CodeManagerConfig; + + // TODO + /** + * Configurations for Panels. + */ + panels?: AnyObject; + + // TODO + /** + * Configurations for Commands. + */ + commands?: AnyObject; + + /** + * Configurations for Css Composer. + */ + cssComposer?: CssComposerConfig; + + // TODO + /** + * Configurations for Selector Manager. + */ + selectorManager?: AnyObject; + + /** + * Configurations for Device Manager. + */ + deviceManager?: DeviceManagerConfig; + + // TODO + /** + * Configurations for Style Manager. + */ + styleManager?: AnyObject; + + // TODO + /** + * Configurations for Block Manager. + */ + blockManager?: BlockManagerConfig | boolean; + + // TODO + /** + * Configurations for Trait Manager. + */ + traitManager?: AnyObject; + + // TODO + /** + * Configurations for Page Manager. + */ + pageManager?: AnyObject; + + // TODO + /** + * Configurations for Layer Manager. + */ + layerManager?: AnyObject; + + /** + * Configurations for Parser module. + */ + parser?: ParserConfig; + + /** Texts **/ + textViewCode?: string; + + /** + * Keep unused styles within the editor. + * @default false + */ + keepUnusedStyles?: boolean; + + /** + * Experimental: don't use. + * Avoid default UI styles. + */ + customUI?: boolean; + el?: HTMLElement; + multiFrames?: boolean; +} - // Experimental: don't use. +const config: EditorConfig = { + stylePrefix: 'gjs-', + components: '', + style: '', + fromElement: false, + projectData: undefined, + noticeOnUnload: true, + showOffsets: false, + showOffsetsSelected: false, + forceClass: true, + height: '900px', + width: '100%', + log: ['warning', 'error'], + baseCss: '', + protectedCss: '* { box-sizing: border-box; } body {margin: 0;}', + canvasCss: '', + defaultCommand: 'select-comp', + showToolbar: true, + showDevices: true, + devicePreviewMode: false, + mediaCondition: 'max-width', + tagVarStart: '{[ ', + tagVarEnd: ' ]}', + keepEmptyTextNodes: false, + jsInHtml: true, + nativeDnD: true, + multipleSelection: true, + optsHtml: {}, + optsCss: {}, + avoidInlineStyle: true, + avoidDefaults: true, + clearStyles: false, + listenToEl: [], + cssIcons: 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css', icons: { close: '', @@ -163,74 +474,28 @@ export default { eyeOff: '', }, - - // Dom element - el: '', - - // Configurations for I18n i18n: {}, - - // Configurations for Undo Manager undoManager: {}, - - //Configurations for Asset Manager assetManager: {}, - - //Configurations for Canvas canvas: {}, - - //Configurations for Layers layers: {}, - - //Configurations for Storage Manager storageManager: {}, - - //Configurations for Rich Text Editor richTextEditor: {}, - - //Configurations for DomComponents domComponents: {}, - - //Configurations for Modal Dialog modal: {}, - - //Configurations for Code Manager codeManager: {}, - - //Configurations for Panels panels: {}, - - //Configurations for Commands commands: {}, - - //Configurations for Css Composer cssComposer: {}, - - //Configurations for Selector Manager selectorManager: {}, - - //Configurations for Device Manager deviceManager: {}, - - //Configurations for Style Manager styleManager: {}, - - // Configurations for Block Manager blockManager: {}, - - // Configurations for Trait Manager traitManager: {}, - - // Texts textViewCode: 'Code', - - // Keep unused styles within the editor keepUnusedStyles: false, - - // TODO multiFrames: false, - - // Experimental: don't use. - // Avoid default UI styles customUI: false, }; + +export default config; diff --git a/src/utils/mixins.ts b/src/utils/mixins.ts index 9f3398df1..169f2cc20 100644 --- a/src/utils/mixins.ts +++ b/src/utils/mixins.ts @@ -1,4 +1,5 @@ import { keys, isUndefined, isElement, isArray } from 'underscore'; +import EditorModel from '../editor/model/Editor'; export const isDef = (value: any) => typeof value !== 'undefined'; @@ -13,8 +14,7 @@ const elProt = hasWin() ? window.Element.prototype : {}; // @ts-ignore const matches = elProt.matches || elProt.webkitMatchesSelector || elProt.mozMatchesSelector || elProt.msMatchesSelector; -// @ts-ignore -export const getUiClass = (em, defCls) => { +export const getUiClass = (em: EditorModel, defCls: string) => { const { stylePrefix, customUI } = em.getConfig(); return [customUI && `${stylePrefix}cui`, defCls].filter(i => i).join(' '); };