diff --git a/src/domain_abstract/model/Styleable.js b/src/domain_abstract/model/Styleable.js index 7bea455e4..5b81414b5 100644 --- a/src/domain_abstract/model/Styleable.js +++ b/src/domain_abstract/model/Styleable.js @@ -105,5 +105,11 @@ export default { getSelectors() { return this.get('selectors') || this.get('classes'); + }, + + getSelectorsString() { + return this.selectorsToString + ? this.selectorsToString() + : this.getSelectors().getFullString(); } }; diff --git a/src/selector_manager/index.js b/src/selector_manager/index.js index d9ec66ddd..97b574367 100644 --- a/src/selector_manager/index.js +++ b/src/selector_manager/index.js @@ -57,7 +57,7 @@ const isClass = str => isString(str) && str[0] == '.'; export default config => { var c = config || {}; - var selectors, selectorTags; + var selectors; return { Selector, @@ -98,7 +98,7 @@ export default config => { c.stylePrefix = ppfx + c.stylePrefix; } - selectorTags = new ClassTagsView({ + this.selectorTags = new ClassTagsView({ collection: new Selectors([], { em, config: c }), config: c }); @@ -129,6 +129,14 @@ export default config => { } }, + select(value, opts = {}) { + const targets = Array.isArray(value) ? value : [value]; + const toSelect = this.em.get('StyleManager').setTarget(targets, opts); + const res = toSelect.map(sel => sel.getSelectorsString()); + this.selectorTags.componentChanged({ targets: res }); + return this; + }, + /** * Change the selector state * @param {String} value State value @@ -289,12 +297,12 @@ export default config => { */ render(selectors) { if (selectors) { - var view = new ClassTagsView({ + this.selectorTags = new ClassTagsView({ collection: new Selectors(selectors), config: c }); - return view.render().el; - } else return selectorTags.render().el; + return this.selectorTags.render().el; + } else return this.selectorTags.render().el; } }; }; diff --git a/src/selector_manager/view/ClassTagsView.js b/src/selector_manager/view/ClassTagsView.js index 1e367f01c..f07f8adae 100644 --- a/src/selector_manager/view/ClassTagsView.js +++ b/src/selector_manager/view/ClassTagsView.js @@ -1,4 +1,4 @@ -import { isEmpty, debounce } from 'underscore'; +import { isEmpty, isArray, isString, debounce } from 'underscore'; import Backbone from 'backbone'; import ClassTagView from './ClassTagView'; @@ -92,6 +92,7 @@ export default Backbone.View.extend({ const selectors = this.getCommonSelectors({ opts }); const state = em.get('state'); const mediaText = em.getCurrentMedia(); + const ruleComponents = []; const rule = cssC.get(selectors, state, mediaText) || cssC.add(selectors, state, mediaText); @@ -104,6 +105,7 @@ export default Backbone.View.extend({ }); style = ruleComponent.getStyle(); ruleComponent.setStyle({}); + ruleComponents.push(ruleComponent); }); style && rule.addStyle(style); @@ -113,7 +115,7 @@ export default Backbone.View.extend({ selectors, mediaText, rule, - ruleComponent, + ruleComponents, state }); }, @@ -206,14 +208,13 @@ export default Backbone.View.extend({ * @param {Object} e * @private */ - componentChanged: debounce(function() { - const { em } = this; - const target = this.getTarget(); + componentChanged: debounce(function({ targets } = {}) { + const target = targets || this.getTarget(); let validSelectors = []; if (target) { this.checkStates(); - validSelectors = this.getCommonSelectors(); + validSelectors = this.getCommonSelectors({ targets }); this.checkSync({ validSelectors }); } @@ -223,7 +224,9 @@ export default Backbone.View.extend({ getCommonSelectors({ targets, opts = {} } = {}) { const trgs = targets || this.getTargets(); - const selectors = trgs.map(tr => tr.getSelectors().getValid(opts)); + const selectors = trgs + .map(tr => tr.getSelectors && tr.getSelectors().getValid(opts)) + .filter(i => i); return this._commonSelectors(...selectors); }, @@ -269,7 +272,7 @@ export default Backbone.View.extend({ updateStateVis(target) { const em = this.em; const avoidInline = em && em.getConfig('avoidInlineStyle'); - const display = this.collection.length || avoidInline ? 'block' : 'none'; + const display = this.collection.length || avoidInline ? '' : 'none'; this.getStatesC().css('display', display); this.updateSelector(target); }, @@ -279,34 +282,37 @@ export default Backbone.View.extend({ * @return {this} * @private */ - updateSelector(target) { - const cmpFrst = this.config.componentFirst; - const selected = target || this.getTarget(); - if (!selected || !selected.get) return; - const result = cmpFrst - ? this.getTargets() - .map(trg => this.__getName(trg)) - .join(', ') - : this.__getName(selected); + updateSelector(targets) { const elSel = this.el.querySelector('[data-selected]'); - elSel && (elSel.innerHTML = result); + const result = []; + let trgs = targets || this.getTargets(); + trgs = isArray(trgs) ? trgs : [trgs]; + + trgs.forEach(target => result.push(this.__getName(target))); + elSel && (elSel.innerHTML = result.join(', ')); this.checkStates(); }, __getName(target) { const { pfx, config, em } = this; const { selectedName, componentFirst } = config; - const coll = this.collection; - const selectors = target.getSelectors().getStyleable(); - const state = em.get('state'); - const idRes = target.getId - ? `${target.getName()}#${target.getId()}` - : ''; - let result = coll.getFullString(selectors); - result = result || target.get('selectorsAdd') || idRes; - result = componentFirst ? idRes : result; - result += state ? `:${state}` : ''; - result = selectedName ? selectedName({ result, state, target }) : result; + let result; + + if (isString(target)) { + result = `${target}`; + } else { + if (!target || !target.get) return; + const selectors = target.getSelectors().getStyleable(); + const state = em.get('state'); + const idRes = target.getId + ? `${target.getName()}#${target.getId()}` + : ''; + result = this.collection.getFullString(selectors); + result = result || target.get('selectorsAdd') || idRes; + result = componentFirst ? idRes : result; + result += state ? `:${state}` : ''; + result = selectedName ? selectedName({ result, state, target }) : result; + } return result && `${result}`; }, diff --git a/src/style_manager/view/SectorsView.js b/src/style_manager/view/SectorsView.js index 76cbfafdd..9b0115a20 100644 --- a/src/style_manager/view/SectorsView.js +++ b/src/style_manager/view/SectorsView.js @@ -1,5 +1,5 @@ import Backbone from 'backbone'; -import { extend, isString } from 'underscore'; +import { extend, isString, isArray } from 'underscore'; import { isTaggableNode } from 'utils/mixins'; import { appendAtIndex } from 'utils/dom'; import SectorView from './SectorView'; @@ -108,40 +108,47 @@ export default Backbone.View.extend({ /** * Select different target for the Style Manager. * It could be a Component, CSSRule, or a string of any CSS selector - * @param {Component|CSSRule|String} target - * @return {Styleable} A Component or CSSRule + * @param {Component|CSSRule|String|Array} target + * @return {Array} Array of Components/CSSRules */ setTarget(target, opts = {}) { const em = this.target; + const trgs = isArray(target) ? target : [target]; const { targetIsClass, stylable } = opts; - let model = target; + const models = []; - if (isString(target)) { - let rule; - const rules = em.get('CssComposer').getAll(); + trgs.forEach(target => { + let model = target; - if (targetIsClass) { - rule = rules.filter( - rule => rule.get('selectors').getFullString() === target - )[0]; - } + if (isString(target)) { + let rule; + const rules = em.get('CssComposer').getAll(); - if (!rule) { - rule = rules.filter(rule => rule.get('selectorsAdd') === target)[0]; - } + if (targetIsClass) { + rule = rules.filter( + rule => rule.get('selectors').getFullString() === target + )[0]; + } + + if (!rule) { + rule = rules.filter(rule => rule.get('selectorsAdd') === target)[0]; + } + + if (!rule) { + rule = rules.add({ selectors: [], selectorsAdd: target }); + } - if (!rule) { - rule = rules.add({ selectors: [], selectorsAdd: target }); + stylable && rule.set({ stylable }); + model = rule; } - stylable && rule.set({ stylable }); - model = rule; - } + models.push(model); + }); const pt = this.propTarget; - pt.model = model; - pt.trigger('styleManager:update', model); - return model; + pt.targets = models; + pt.trigger('update'); + return models; }, /**