Browse Source

Add `addStyles` option to `editor.Css.setRule`. Closes #5173

pull/5196/head
Artur Arseniev 3 years ago
parent
commit
763865d903
  1. 27
      src/css_composer/index.ts
  2. 2
      src/domain_abstract/model/StyleableModel.ts
  3. 16
      test/specs/css_composer/index.ts

27
src/css_composer/index.ts

@ -40,10 +40,22 @@ import EditorModel from '../editor/model/Editor';
import Component from '../dom_components/model/Component'; import Component from '../dom_components/model/Component';
import { ObjectAny } from '../common'; import { ObjectAny } from '../common';
type RuleOptions = { interface RuleOptions {
/**
* At-rule type, eg. `media`
*/
atRuleType?: string; atRuleType?: string;
/**
* At-rule parameters, eg. `(min-width: 500px)`
*/
atRuleParams?: string; atRuleParams?: string;
}; }
interface SetRuleOptions extends RuleOptions {
/**
* If the rule exists already, merge passed styles instead of replacing them.
*/
addStyles?: boolean;
}
type CssRuleStyle = Required<CssRuleProperties>['style']; type CssRuleStyle = Required<CssRuleProperties>['style'];
@ -260,6 +272,7 @@ export default class CssComposer extends ItemManagerModule<CssComposerConfig & {
* @param {Object} [opts={}] Additional properties * @param {Object} [opts={}] Additional properties
* @param {String} [opts.atRuleType=''] At-rule type, eg. `media` * @param {String} [opts.atRuleType=''] At-rule type, eg. `media`
* @param {String} [opts.atRuleParams=''] At-rule parameters, eg. `(min-width: 500px)` * @param {String} [opts.atRuleParams=''] At-rule parameters, eg. `(min-width: 500px)`
* @param {Boolean} [opts.addStyles=false] If the rule exists already, merge passed styles instead of replacing them.
* @returns {[CssRule]} The new/updated CssRule * @returns {[CssRule]} The new/updated CssRule
* @example * @example
* // Simple class-based rule * // Simple class-based rule
@ -275,7 +288,7 @@ export default class CssComposer extends ItemManagerModule<CssComposerConfig & {
* }); * });
* // output: @media (min-width: 500px) { .class1:hover { color: red } } * // output: @media (min-width: 500px) { .class1:hover { color: red } }
*/ */
setRule(selectors: any, style: CssRuleProperties['style'] = {}, opts: RuleOptions = {}) { setRule(selectors: any, style: CssRuleProperties['style'] = {}, opts: SetRuleOptions = {}) {
const { atRuleType, atRuleParams } = opts; const { atRuleType, atRuleParams } = opts;
const node = this.em.Parser.parserCss.checkNode({ const node = this.em.Parser.parserCss.checkNode({
selectors, selectors,
@ -288,7 +301,13 @@ export default class CssComposer extends ItemManagerModule<CssComposerConfig & {
selectorsAdd, selectorsAdd,
atRule: atRuleType, atRule: atRuleType,
}); });
rule.setStyle(style, opts);
if (opts.addStyles) {
rule.addStyle(style, opts);
} else {
rule.setStyle(style, opts);
}
return rule; return rule;
} }

2
src/domain_abstract/model/StyleableModel.ts

@ -82,7 +82,7 @@ export default class StyleableModel<T extends ObjectHash = any> extends Model<T>
* this.addStyle({color: 'red'}); * this.addStyle({color: 'red'});
* this.addStyle('color', 'blue'); * this.addStyle('color', 'blue');
*/ */
addStyle(prop: string | ObjectAny, value = '', opts = {}) { addStyle(prop: string | ObjectAny, value: any = '', opts: ObjectAny = {}) {
if (typeof prop == 'string') { if (typeof prop == 'string') {
prop = { prop = {
[prop]: value, [prop]: value,

16
test/specs/css_composer/index.ts

@ -216,7 +216,7 @@ describe('Css Composer', () => {
describe('setRule/getRule', () => { describe('setRule/getRule', () => {
test('Create a simple class-based rule', () => { test('Create a simple class-based rule', () => {
const selector = '.test'; const selector = '.test';
const result = obj.setRule(selector, { color: 'red' }); obj.setRule(selector, { color: 'red' });
expect(obj.getAll().length).toEqual(1); expect(obj.getAll().length).toEqual(1);
const rule = obj.getRule(selector)!; const rule = obj.getRule(selector)!;
expect(rule.selectorsToString()).toEqual(selector); expect(rule.selectorsToString()).toEqual(selector);
@ -225,7 +225,7 @@ describe('Css Composer', () => {
test('Avoid creating multiple rules with the same selector', () => { test('Avoid creating multiple rules with the same selector', () => {
const selector = '.test'; const selector = '.test';
obj.setRule(selector, { color: 'red' }); obj.setRule(selector, { color: 'red', background: 'red' });
obj.setRule(selector, { color: 'blue' }); obj.setRule(selector, { color: 'blue' });
expect(obj.getAll().length).toEqual(1); expect(obj.getAll().length).toEqual(1);
const rule = obj.getRule(selector)!; const rule = obj.getRule(selector)!;
@ -233,9 +233,17 @@ describe('Css Composer', () => {
expect(rule.styleToString()).toEqual('color:blue;'); expect(rule.styleToString()).toEqual('color:blue;');
}); });
test('Update rule with addStyles option', () => {
const selector = '.test';
obj.setRule(selector, { color: 'red', background: 'red' });
obj.setRule(selector, { color: 'blue' }, { addStyles: true });
const rule = obj.getRule(selector)!;
expect(rule.styleToString()).toEqual('color:blue;background:red;');
});
test('Create a class-based rule', () => { test('Create a class-based rule', () => {
const selector = '.test.test2'; const selector = '.test.test2';
const result = obj.setRule(selector, { color: 'red' }); obj.setRule(selector, { color: 'red' });
expect(obj.getAll().length).toEqual(1); expect(obj.getAll().length).toEqual(1);
const rule = obj.getRule(selector)!; const rule = obj.getRule(selector)!;
expect(rule.selectorsToString()).toEqual(selector); expect(rule.selectorsToString()).toEqual(selector);
@ -244,7 +252,7 @@ describe('Css Composer', () => {
test('Create a class-based rule with a state', () => { test('Create a class-based rule with a state', () => {
const selector = '.test.test2:hover'; const selector = '.test.test2:hover';
const result = obj.setRule(selector, { color: 'red' }); obj.setRule(selector, { color: 'red' });
expect(obj.getAll().length).toEqual(1); expect(obj.getAll().length).toEqual(1);
const rule = obj.getRule(selector)!; const rule = obj.getRule(selector)!;
expect(rule.selectorsToString()).toEqual(selector); expect(rule.selectorsToString()).toEqual(selector);

Loading…
Cancel
Save