From be118f8088baea88641b2c8fb6a8494c9d5f549d Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Sun, 3 Oct 2021 16:49:20 +0200 Subject: [PATCH] Add remove method to CssComposer API --- docs/api/canvas.md | 4 +- docs/api/css_composer.md | 201 +++++++++++++------------------------- src/css_composer/index.js | 116 +++++++++++++--------- 3 files changed, 137 insertions(+), 184 deletions(-) diff --git a/docs/api/canvas.md b/docs/api/canvas.md index d3356d320..6945c35fd 100644 --- a/docs/api/canvas.md +++ b/docs/api/canvas.md @@ -34,6 +34,8 @@ const canvas = editor.Canvas; [Component]: component.html +[Frame]: frame.html + ## getConfig Get the configuration object @@ -218,7 +220,7 @@ canvas.addFrame({ }); ``` -Returns **Frame** +Returns **[Frame]** [1]: https://github.com/artf/grapesjs/blob/master/src/canvas/config/config.js diff --git a/docs/api/css_composer.md b/docs/api/css_composer.md index a119e74fe..09946d123 100644 --- a/docs/api/css_composer.md +++ b/docs/api/css_composer.md @@ -16,206 +16,137 @@ const editor = grapesjs.init({ Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance ```js -const cssComposer = editor.CssComposer; +const css = editor.Css; ``` -* [load][2] -* [store][3] -* [add][4] -* [get][5] -* [getAll][6] -* [clear][7] -* [setRule][8] -* [getRule][9] +* [setRule][2] +* [getRule][3] +* [getRules][4] +* [remove][5] +* [clear][6] -## load - -Load data from the passed object, if the object is empty will try to fetch them -autonomously from the storage manager. -The fetched data will be added to the collection - -### Parameters - -* `data` **[Object][10]** Object of data to load - -Returns **[Object][10]** Loaded rules - -## store - -Store data to the selected storage - -### Parameters - -* `noStore` **[Boolean][11]** If true, won't store - -Returns **[Object][10]** Data to store - -## add - -Add new rule to the collection, if not yet exists with the same selectors - -### Parameters - -* `selectors` **[Array][12]\** Array of selectors -* `state` **[String][13]** Css rule state -* `width` **[String][13]** For which device this style is oriented -* `opts` **[Object][10]** Options for the add of new rule (optional, default `{}`) -* `addOpts` (optional, default `{}`) -* `props` **[Object][10]** Other props for the rule - -### Examples - -```javascript -var sm = editor.SelectorManager; -var sel1 = sm.add('myClass1'); -var sel2 = sm.add('myClass2'); -var rule = cssComposer.add([sel1, sel2], 'hover'); -rule.set('style', { - width: '100px', - color: '#fff', -}); -``` - -Returns **Model** - -## get - -Get the rule - -### Parameters - -* `selectors` **([String][13] | [Array][12]\)** Array of selectors or selector string, eg `.myClass1.myClass2` -* `state` **[String][13]** Css rule state, eg. 'hover' -* `width` **[String][13]** Media rule value, eg. '(max-width: 992px)' -* `ruleProps` **[Object][10]** Other rule props - -### Examples - -```javascript -const sm = editor.SelectorManager; -const sel1 = sm.add('myClass1'); -const sel2 = sm.add('myClass2'); -const rule = cssComposer.get([sel1, sel2], 'hover', '(max-width: 992px)'); -// Update the style -rule.set('style', { - width: '300px', - color: '#000', -}); -``` - -Returns **(Model | null)** - -## getAll - -Get the collection of rules - -Returns **Collection** - -## clear - -Remove all rules - -### Parameters - -* `opts` (optional, default `{}`) - -Returns **this** +[CssRule]: css_rule.html ## setRule -Add/update the CSS rule with a generic selector +Add/update the CssRule. ### Parameters -* `selectors` **[string][13]** Selector, eg. '.myclass' -* `style` **[Object][10]** Style properties and values -* `opts` **[Object][10]** Additional properties (optional, default `{}`) +* `selectors` **[string][7]** Selector, eg. `.myclass` +* `style` **[Object][8]** Style properties and values +* `opts` **[Object][8]** Additional properties (optional, default `{}`) - * `opts.atRuleType` **[String][13]** At-rule type, eg. 'media' (optional, default `''`) - * `opts.atRuleParams` **[String][13]** At-rule parameters, eg. '(min-width: 500px)' (optional, default `''`) + * `opts.atRuleType` **[String][7]** At-rule type, eg. 'media' (optional, default `''`) + * `opts.atRuleParams` **[String][7]** At-rule parameters, eg. `(min-width: 500px)` (optional, default `''`) ### Examples ```javascript // Simple class-based rule -const rule = cc.setRule('.class1.class2', { color: 'red' }); +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 = cc.setRule('.class1.class2:hover, div#myid', { color: 'red' }); +const rule = css.setRule('.class1.class2:hover, div#myid', { color: 'red' }); // output: .class1.class2:hover, div#myid { color: red } // With media -const rule = cc.setRule('.class1:hover', { color: 'red' }, { +const rule = css.setRule('.class1:hover', { color: 'red' }, { atRuleType: 'media', atRuleParams: '(min-width: 500px)', }); // output: @media (min-width: 500px) { .class1:hover { color: red } } ``` -Returns **CssRule** The new/updated rule +Returns **[CssRule]** The new/updated CssRule ## getRule -Get the CSS rule by a generic selector +Get the CssRule. ### Parameters -* `selectors` **[string][13]** Selector, eg. '.myclass:hover' -* `opts` (optional, default `{}`) +* `selectors` **[String][7]** Selector string, eg. `.myclass:hover` +* `opts` **[Object][8]** Additional properties (optional, default `{}`) + + * `opts.atRuleType` **[String][7]** At-rule type, eg. 'media' (optional, default `''`) + * `opts.atRuleParams` **[String][7]** At-rule parameters, eg. '(min-width: 500px)' (optional, default `''`) ### Examples ```javascript -const rule = cc.getRule('.myclass1:hover'); -const rule2 = cc.getRule('.myclass1:hover, div#myid'); -const rule3 = cc.getRule('.myclass1', { +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)', }); ``` -Returns **CssRule** +Returns **[CssRule]** ## getRules -Find rules, in different states (eg. like `:hover`) and media queries, matching the selector. +Get all rules or filtered by a matching selector. ### Parameters -* `selector` **[string][13]** Selector, eg. '.myclass' +* `selector` **[String][7]** Selector, eg. '.myclass' (optional, default `''`) ### Examples ```javascript // Common scenario, take all the component specific rules const id = someComponent.getId(); -const rules = cc.getRules(`#${id}`); +const rules = css.getRules(`#${id}`); console.log(rules.map(rule => rule.toCSS())) ``` -Returns **[Array][12]\** +Returns **[Array][9]<[CssRule]>** -[1]: https://github.com/artf/grapesjs/blob/master/src/css_composer/config/config.js +## remove + +Remove rule, by CssRule or matching selector (eg. the selector will match also at-rules like `@media`) -[2]: #load +### Parameters + +* `rule` **([String][7] | [CssRule] | [Array][9]<[CssRule]>)** CssRule or matching selector. -[3]: #store +### Examples -[4]: #add +```javascript +// Remove by CssRule +const toRemove = css.getRules('.my-cls'); +css.remove(toRemove); +// Remove by selector +css.remove('.my-cls-2'); +``` -[5]: #get +Returns **[Array][9]<[CssRule]>** Removed rules + +## clear + +Remove all rules + +### Parameters + +* `opts` (optional, default `{}`) + +Returns **this** + +[1]: https://github.com/artf/grapesjs/blob/master/src/css_composer/config/config.js -[6]: #getall +[2]: #setrule -[7]: #clear +[3]: #getrule -[8]: #setrule +[4]: #getrules -[9]: #getrule +[5]: #remove -[10]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object +[6]: #clear -[11]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean +[7]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String -[12]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array +[8]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object -[13]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String +[9]: https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array diff --git a/src/css_composer/index.js b/src/css_composer/index.js index 9db98b2c1..c8086c908 100644 --- a/src/css_composer/index.js +++ b/src/css_composer/index.js @@ -12,17 +12,16 @@ * Once the editor is instantiated you can use its API. Before using these methods you should get the module from the instance * * ```js - * const cssComposer = editor.CssComposer; + * const css = editor.Css; * ``` * - * * [load](#load) - * * [store](#store) - * * [add](#add) - * * [get](#get) - * * [getAll](#getall) - * * [clear](#clear) * * [setRule](#setrule) * * [getRule](#getrule) + * * [getRules](#getrules) + * * [remove](#remove) + * * [clear](#clear) + * + * [CssRule]: css_rule.html * * @module CssComposer */ @@ -114,6 +113,7 @@ export default () => { * The fetched data will be added to the collection * @param {Object} data Object of data to load * @return {Object} Loaded rules + * @private */ load(data) { var d = data || ''; @@ -145,6 +145,7 @@ export default () => { * Store data to the selected storage * @param {Boolean} noStore If true, won't store * @return {Object} Data to store + * @private */ store(noStore) { if (!c.stm) return; @@ -165,6 +166,7 @@ export default () => { * @param {Object} props Other props for the rule * @param {Object} opts Options for the add of new rule * @return {Model} + * @private * @example * var sm = editor.SelectorManager; * var sel1 = sm.add('myClass1'); @@ -205,6 +207,7 @@ export default () => { * @param {String} width Media rule value, eg. '(max-width: 992px)' * @param {Object} ruleProps Other rule props * @return {Model|null} + * @private * @example * const sm = editor.SelectorManager; * const sel1 = sm.add('myClass1'); @@ -231,23 +234,10 @@ export default () => { ); }, - /** - * Get the collection of rules - * @return {Collection} - * */ getAll() { return rules; }, - /** - * Remove all rules - * @return {this} - */ - clear(opts = {}) { - this.getAll().reset(null, opts); - return this; - }, - /** * Add a raw collection of rule objects * This method overrides styles, in case, of already defined rule @@ -301,22 +291,22 @@ export default () => { }, /** - * Add/update the CSS rule with a generic selector - * @param {string} selectors Selector, eg. '.myclass' + * Add/update the CssRule. + * @param {String} selectors Selector string, eg. `.myclass` * @param {Object} style Style properties and values * @param {Object} [opts={}] Additional properties - * @param {String} [opts.atRuleType=''] At-rule type, eg. 'media' - * @param {String} [opts.atRuleParams=''] At-rule parameters, eg. '(min-width: 500px)' - * @return {CssRule} The new/updated rule + * @param {String} [opts.atRuleType=''] At-rule type, eg. `media` + * @param {String} [opts.atRuleParams=''] At-rule parameters, eg. `(min-width: 500px)` + * @returns {[CssRule]} The new/updated CssRule * @example * // Simple class-based rule - * const rule = cc.setRule('.class1.class2', { color: 'red' }); + * 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 = cc.setRule('.class1.class2:hover, div#myid', { color: 'red' }); + * const rule = css.setRule('.class1.class2:hover, div#myid', { color: 'red' }); * // output: .class1.class2:hover, div#myid { color: red } * // With media - * const rule = cc.setRule('.class1:hover', { color: 'red' }, { + * const rule = css.setRule('.class1:hover', { color: 'red' }, { * atRuleType: 'media', * atRuleParams: '(min-width: 500px)', * }); @@ -340,15 +330,16 @@ export default () => { }, /** - * Get the CSS rule by a generic selector - * @param {string} selectors Selector, eg. '.myclass:hover' - * @param {String} [opts.atRuleType=''] At-rule type, eg. 'media' + * Get the CssRule. + * @param {String} selectors Selector string, eg. `.myclass:hover` + * @param {Object} [opts={}] Additional properties + * @param {String} [opts.atRuleType=''] At-rule type, eg. `media` * @param {String} [opts.atRuleParams=''] At-rule parameters, eg. '(min-width: 500px)' - * @return {CssRule} + * @returns {[CssRule]} * @example - * const rule = cc.getRule('.myclass1:hover'); - * const rule2 = cc.getRule('.myclass1:hover, div#myid'); - * const rule3 = cc.getRule('.myclass1', { + * 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)', * }); @@ -369,17 +360,20 @@ export default () => { }, /** - * Find rules, in different states (eg. like `:hover`) and media queries, matching the selector. - * @param {string} selector Selector, eg. '.myclass' - * @returns {Array} + * Get all rules or filtered by a matching selector. + * @param {String} [selector=''] Selector, eg. `.myclass` + * @returns {Array<[CssRule]>} * @example - * // Common scenario, take all the component specific rules + * // Take all the component specific rules * const id = someComponent.getId(); - * const rules = cc.getRules(`#${id}`); + * const rules = css.getRules(`#${id}`); * console.log(rules.map(rule => rule.toCSS())) + * // All rules in the project + * console.log(css.getRules()) */ getRules(selector) { const rules = this.getAll(); + if (!selector) return [...rules.models]; const result = rules.filter( r => r.getSelectors().getFullString() === selector ); @@ -394,8 +388,8 @@ export default () => { * @return {CssRule} The new/updated rule * @private * @example - * const rule = cc.setIdRule('myid', { color: 'red' }); - * const ruleHover = cc.setIdRule('myid', { color: 'blue' }, { state: 'hover' }); + * const rule = css.setIdRule('myid', { color: 'red' }); + * const ruleHover = css.setIdRule('myid', { color: 'blue' }, { state: 'hover' }); * // This will add current CSS: * // #myid { color: red } * // #myid:hover { color: blue } @@ -418,8 +412,8 @@ export default () => { * @return {CssRule} * @private * @example - * const rule = cc.getIdRule('myid'); - * const ruleHover = cc.setIdRule('myid', { state: 'hover' }); + * const rule = css.getIdRule('myid'); + * const ruleHover = css.setIdRule('myid', { state: 'hover' }); */ getIdRule(name, opts = {}) { const { mediaText } = opts; @@ -437,8 +431,8 @@ export default () => { * @return {CssRule} The new/updated rule * @private * @example - * const rule = cc.setClassRule('myclass', { color: 'red' }); - * const ruleHover = cc.setClassRule('myclass', { color: 'blue' }, { state: 'hover' }); + * const rule = css.setClassRule('myclass', { color: 'red' }); + * const ruleHover = css.setClassRule('myclass', { color: 'blue' }, { state: 'hover' }); * // This will add current CSS: * // .myclass { color: red } * // .myclass:hover { color: blue } @@ -460,8 +454,8 @@ export default () => { * @return {CssRule} * @private * @example - * const rule = cc.getClassRule('myclass'); - * const ruleHover = cc.getClassRule('myclass', { state: 'hover' }); + * const rule = css.getClassRule('myclass'); + * const ruleHover = css.getClassRule('myclass', { state: 'hover' }); */ getClassRule(name, opts = {}) { const state = opts.state || ''; @@ -470,6 +464,32 @@ export default () => { return selector && this.get(selector, state, media); }, + /** + * Remove rule, by CssRule or matching selector (eg. the selector will match also at-rules like `@media`) + * @param {String|[CssRule]|Array<[CssRule]>} rule CssRule or matching selector. + * @return {Array<[CssRule]>} Removed rules + * @example + * // Remove by CssRule + * const toRemove = css.getRules('.my-cls'); + * css.remove(toRemove); + * // Remove by selector + * css.remove('.my-cls-2'); + */ + remove(rule) { + const toRemove = isString(rule) ? this.getRules(rule) : rule; + const result = this.getAll().remove(toRemove); + return isArray(result) ? result : [result]; + }, + + /** + * Remove all rules + * @return {this} + */ + clear(opts = {}) { + this.getAll().reset(null, opts); + return this; + }, + getComponentRules(cmp, opts = {}) { let { state, mediaText, current } = opts; if (current) {