diff --git a/src/common/index.ts b/src/common/index.ts index 63ccacb2ac..e6115798e2 100644 --- a/src/common/index.ts +++ b/src/common/index.ts @@ -5,7 +5,7 @@ interface NOOP {} export type Debounced = Function & { cancel(): void }; -export type SetOptions = Backbone.ModelSetOptions & { avoidStore?: boolean }; +export type SetOptions = Backbone.ModelSetOptions & { avoidStore?: boolean; inline?: boolean }; export type AddOptions = Backbone.AddOptions & { temporary?: boolean }; diff --git a/src/dom_components/model/Component.ts b/src/dom_components/model/Component.ts index ca9861334d..7bb39fc0e8 100644 --- a/src/dom_components/model/Component.ts +++ b/src/dom_components/model/Component.ts @@ -540,7 +540,7 @@ export default class Component extends StyleableModel { // Handle style const style = attrs.style; - style && this.setStyle(style); + style && this.setStyle(style, opts); delete attrs.style; const attrPrev = { ...this.previous('attributes') }; @@ -613,6 +613,10 @@ export default class Component extends StyleableModel { if (rule) { return rule.getStyle(prop); } + + // Return empty style if not rule have been found. We cannot return inline style with the next return + // because else on load inline style is set a #id or .class style + return {}; } return super.getStyle.call(this, prop); @@ -671,9 +675,9 @@ export default class Component extends StyleableModel { // Add style if (!opts.noStyle) { - const style = this.get('style'); + const style = this.getStyle({ inline: true }); if (isObject(style) && !isEmptyObj(style)) { - attributes.style = this.styleToString({ inline: 1 }); + attributes.style = this.styleToString({ inline: true }); } } @@ -1572,7 +1576,7 @@ export default class Component extends StyleableModel { const tag = customTag || model.get('tagName'); const sTag = model.get('void'); const customAttr = opts.attributes; - let attributes = this.getAttrToHTML(); + let attributes = this.getAttrToHTML(opts); delete opts.tag; // Get custom attributes if requested @@ -1643,10 +1647,10 @@ export default class Component extends StyleableModel { * @return {Object} * @private */ - getAttrToHTML() { + getAttrToHTML(opts?: ToHTMLOptions) { const attrs = this.getAttributes(); - if (avoidInline(this.em)) { + if (avoidInline(this.em) && opts?.keepInlineStyle !== true) { delete attrs.style; } diff --git a/src/dom_components/model/types.ts b/src/dom_components/model/types.ts index e782f76e59..36c0bbb07d 100644 --- a/src/dom_components/model/types.ts +++ b/src/dom_components/model/types.ts @@ -280,6 +280,11 @@ export type ToHTMLOptions = { */ altQuoteAttr?: boolean; + /** + * Keep inline style set intentionally by users with `setStyle({}, { inline: true })` + */ + keepInlineStyle?: boolean; + /** * 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. diff --git a/src/editor/config/config.ts b/src/editor/config/config.ts index da717a880a..a95d84c830 100644 --- a/src/editor/config/config.ts +++ b/src/editor/config/config.ts @@ -7,6 +7,7 @@ import { DeviceManagerConfig } from '../../device_manager/config/config'; import { I18nConfig } from '../../i18n/config'; import { ModalConfig } from '../../modal_dialog/config/config'; import { LayerManagerConfig } from '../../navigator/config/config'; +import { KeymapsConfig } from '../../keymaps/config'; import { PageManagerConfig } from '../../pages/types'; import { PanelsConfig } from '../../panels/config/config'; import { ParserConfig } from '../../parser/config/config'; @@ -356,6 +357,11 @@ export interface EditorConfig { */ commands?: CommandsConfig; + /** + * Configurations for keymaps + */ + keymaps?: KeymapsConfig; + /** * Configurations for Css Composer. */ diff --git a/test/specs/dom_components/model/Component.ts b/test/specs/dom_components/model/Component.ts index 51b4b19e8f..ccc610e81f 100644 --- a/test/specs/dom_components/model/Component.ts +++ b/test/specs/dom_components/model/Component.ts @@ -19,7 +19,9 @@ let em: Editor; describe('Component', () => { beforeEach(() => { - em = new Editor({ avoidDefaults: true }); + // FIXME: avoidInlineStyle is deprecated and when running in dev or prod, `avoidInlineStyle` is set to true + // The following tests ran with `avoidInlineStyle` to false (this is why I add the parameter here) + em = new Editor({ avoidDefaults: true, avoidInlineStyle: true }); dcomp = em.Components; em.Pages.onLoad(); compOpts = { @@ -278,10 +280,10 @@ describe('Component', () => { class: 'class1 class2', style: 'color: white; background: #fff', }); + // Style is not in attributes because it has not been set as inline expect(obj.getAttributes()).toEqual({ id: 'test', class: 'class1 class2', - style: 'color:white;background:#fff;', 'data-test': 'value', }); expect(obj.classes.length).toEqual(2); @@ -291,13 +293,25 @@ describe('Component', () => { }); }); - test('set inline style with multiple values of the same key', () => { + test('set style with multiple values of the same key', () => { obj.setAttributes({ style: CSS_BG_STR }); expect(obj.getStyle()).toEqual(CSS_BG_OBJ); }); - test('get proper style from inline style with multiple values of the same key', () => { - obj.setAttributes({ style: CSS_BG_STR }); + test('set style on id and inline style', () => { + obj.setStyle({ color: 'red' }); // Should be set on id + obj.setStyle({ display: 'flex' }, { inline: true }); // Should be set as inline + + expect(obj.getStyle()).toEqual({ + color: 'red', + }); + expect(obj.getStyle({ inline: true })).toEqual({ + display: 'flex', + }); + }); + + test('get proper style from style with multiple values of the same key', () => { + obj.setAttributes({ style: CSS_BG_STR }, { inline: true }); expect(obj.getAttributes()).toEqual({ style: CSS_BG_STR.split('\n').join(''), });