Browse Source

Refactor SelectorManager

pull/3874/head
Artur Arseniev 5 years ago
parent
commit
abcc9c6027
  1. 2
      src/selector_manager/config/config.js
  2. 110
      src/selector_manager/index.js
  3. 9
      src/selector_manager/view/ClassTagView.js
  4. 41
      src/selector_manager/view/ClassTagsView.js
  5. 5
      src/style_manager/index.js

2
src/selector_manager/config/config.js

@ -9,7 +9,7 @@ export default {
// Default selectors // Default selectors
selectors: [], selectors: [],
// States // Default states
states: [{ name: 'hover' }, { name: 'active' }, { name: 'nth-of-type(2n)' }], states: [{ name: 'hover' }, { name: 'active' }, { name: 'nth-of-type(2n)' }],
// Custom selector name escaping strategy, eg. // Custom selector name escaping strategy, eg.

110
src/selector_manager/index.js

@ -61,7 +61,7 @@
* @module SelectorManager * @module SelectorManager
*/ */
import { isString, isElement, isObject, isArray } from 'underscore'; import { isString, debounce, isObject, isArray, isEmpty } from 'underscore';
import { isComponent, isRule } from 'utils/mixins'; import { isComponent, isRule } from 'utils/mixins';
import { Model } from 'common'; import { Model } from 'common';
import Module from 'common/module'; import Module from 'common/module';
@ -119,13 +119,37 @@ export default () => {
// Global selectors container // Global selectors container
this.all = new Selectors(config.selectors); this.all = new Selectors(config.selectors);
this.selected = new Selectors([], { em, config });
this.model = new Model({ _undo: true }); this.model = new Model({ _undo: true });
this.__initListen(); this.__initListen();
em.on('change:state', (m, value) => em.trigger('selector:state', value)); em.on('change:state', (m, value) => em.trigger('selector:state', value));
const listenTo =
'component:toggled component:update:classes styleManager:update change:state';
this.model.listenTo(em, listenTo, () => this.__update());
return this; return this;
}, },
__update: debounce(function() {
this.__trgCustom();
}),
__trgCustom() {
this.em.trigger(this.events.custom, this.__customData());
},
__customData() {
const common = this.__getCommon();
return {
sm: this,
common,
states: this.getStates(),
selected: this.getSelected(),
add: prop => this.__addToCommon(prop), // add selector to common selection
remove: '' // remove selector from selection
};
},
// postLoad() { // postLoad() {
// this.__postLoad(); // this.__postLoad();
// const { em, model } = this; // const { em, model } = this;
@ -136,6 +160,7 @@ export default () => {
postRender() { postRender() {
this.__appendTo(); this.__appendTo();
this.__trgCustom();
}, },
select(value, opts = {}) { select(value, opts = {}) {
@ -155,6 +180,10 @@ export default () => {
return this; return this;
}, },
getSelected() {
return this.em.get('StyleManager').getTargets();
},
addSelector(name, opts = {}, cOpts = {}) { addSelector(name, opts = {}, cOpts = {}) {
let props = { ...opts }; let props = { ...opts };
@ -296,13 +325,22 @@ export default () => {
}, },
/** /**
* Get the current selector state * Get the current selector state value
* @returns {String} * @returns {String}
*/ */
getState() { getState() {
return this.em.getState(); return this.em.getState();
}, },
/**
* Get states
* @returns {Array<State>}
* @private
*/
getStates() {
return this.config.states;
},
/** /**
* Get all selectors * Get all selectors
* @name getAll * @name getAll
@ -331,9 +369,11 @@ export default () => {
const { em, selectorTags } = this; const { em, selectorTags } = this;
const config = this.getConfig(); const config = this.getConfig();
const el = selectorTags && selectorTags.el; const el = selectorTags && selectorTags.el;
this.selected.reset(selectors);
this.selectorTags = new ClassTagsView({ this.selectorTags = new ClassTagsView({
el, el,
collection: new Selectors(selectors || [], { em, config }), collection: this.selected,
module: this,
config config
}); });
@ -341,13 +381,75 @@ export default () => {
}, },
destroy() { destroy() {
const { selectorTags } = this; const { selectorTags, model } = this;
const all = this.getAll(); const all = this.getAll();
model.stopListening();
all.stopListening(); all.stopListening();
all.reset(); all.reset();
selectorTags && selectorTags.remove(); selectorTags && selectorTags.remove();
this.em = {}; this.em = {};
this.selectorTags = {}; this.selectorTags = {};
},
// __toSync(common = []) {
// const cmpFirst = this.getConfig().componentFirst;
// const cmp = this.em.getSelected();
// let result = null;
// if (cmp && cmpFirst && common.length) {
// const style = cmp.getStyle();
// result = !isEmpty(style) ? style : null;
// }
// return result;
// },
/**
* Get common selectors from the current selection.
* @return {Array<Selector>}
* @private
*/
__getCommon() {
return this.__getCommonSelectors(this.em.getSelectedAll());
},
__getCommonSelectors(components, opts = {}) {
const selectors = components
.map(cmp => cmp.getSelectors && cmp.getSelectors().getValid(opts))
.filter(Boolean);
return this.__common(...selectors);
},
__common(...args) {
if (!args.length) return [];
if (args.length === 1) return args[0];
if (args.length === 2)
return args[0].filter(item => args[1].indexOf(item) >= 0);
return args
.slice(1)
.reduce((acc, item) => this.__common(acc, item), args[0]);
},
getSelected() {
return [...this.selected.models];
},
addSelected(props) {
const added = this.add(props);
// TODO: target should be the one from StyleManager
this.em.getSelectedAll().forEach(target => {
target.getSelectors().add(added);
});
// TODO: update selected collection
},
removeSelected(selector) {
this.em.getSelectedAll().forEach(trg => {
!selector.get('protected') &&
trg &&
trg.getSelectors().remove(selector);
});
} }
}; };
}; };

9
src/selector_manager/view/ClassTagView.js

@ -23,9 +23,10 @@ export default Backbone.View.extend({
'focusout [data-tag-name]': 'endEditTag' 'focusout [data-tag-name]': 'endEditTag'
}, },
initialize(o) { initialize(o = {}) {
const config = o.config || {}; const config = o.config || {};
this.config = config; this.config = config;
this.module = o.module;
this.coll = o.coll || null; this.coll = o.coll || null;
this.pfx = config.stylePrefix || ''; this.pfx = config.stylePrefix || '';
this.ppfx = config.pStylePrefix || ''; this.ppfx = config.pStylePrefix || '';
@ -97,11 +98,7 @@ export default Backbone.View.extend({
* @private * @private
*/ */
removeTag() { removeTag() {
const { em, model } = this; this.module.removeSelected(this.model);
const targets = em && em.getSelectedAll();
targets.forEach(sel => {
!model.get('protected') && sel && sel.getSelectors().remove(model);
});
}, },
/** /**

41
src/selector_manager/view/ClassTagsView.js

@ -66,6 +66,7 @@ export default Backbone.View.extend({
const { em } = this.config; const { em } = this.config;
const coll = this.collection; const coll = this.collection;
this.target = this.config.em; this.target = this.config.em;
this.module = o.module;
this.em = em; this.em = em;
const toList = 'component:toggled component:update:classes'; const toList = 'component:toggled component:update:classes';
const toListCls = 'component:update:classes change:state'; const toListCls = 'component:update:classes change:state';
@ -212,27 +213,17 @@ export default Backbone.View.extend({
this.collection.reset(selectors); this.collection.reset(selectors);
this.updateStateVis(trgs); this.updateStateVis(trgs);
this.module.__trgCustom();
return selectors; return selectors;
}, },
getCommonSelectors({ targets, opts = {} } = {}) { getCommonSelectors({ targets, opts = {} } = {}) {
const trgs = targets || this.getTargets(); const trgs = targets || this.getTargets();
const selectors = trgs return this.module.__getCommonSelectors(trgs, opts);
.map(tr => tr.getSelectors && tr.getSelectors().getValid(opts))
.filter(i => i);
return this._commonSelectors(...selectors);
}, },
_commonSelectors(...args) { _commonSelectors(...args) {
if (!args.length) return []; return this.module.__common(...args);
if (args.length === 1) return args[0];
if (args.length === 2)
return args[0].filter(item => args[1].indexOf(item) >= 0);
return args
.slice(1)
.reduce((acc, item) => this._commonSelectors(acc, item), args[0]);
}, },
checkSync: debounce(function() { checkSync: debounce(function() {
@ -332,23 +323,12 @@ export default Backbone.View.extend({
* @param {Object} e * @param {Object} e
* @private * @private
*/ */
addNewTag(label) { addNewTag(value) {
const { em } = this; const label = value.trim();
if (!label) return;
if (!label.trim()) return; this.module.addSelected({ label });
if (em) {
const sm = em.get('SelectorManager');
const model = sm.add({ label });
this.getTargets().forEach(target => {
target.getSelectors().add(model);
this.collection.add(model);
this.updateStateVis();
});
}
this.endNewTag(); this.endNewTag();
// this.updateStateVis(); // Check if required
}, },
/** /**
@ -364,7 +344,8 @@ export default Backbone.View.extend({
const rendered = new ClassTagView({ const rendered = new ClassTagView({
model, model,
config: this.config, config: this.config,
coll: this.collection coll: this.collection,
module: this.module
}).render().el; }).render().el;
fragment ? fragment.appendChild(rendered) : classes.append(rendered); fragment ? fragment.appendChild(rendered) : classes.append(rendered);

5
src/style_manager/index.js

@ -416,6 +416,11 @@ export default () => {
return SectView.setTarget(target, opts); return SectView.setTarget(target, opts);
}, },
getTargets() {
const { propTarget } = SectView || {};
return (propTarget && propTarget.targets) || [];
},
getEmitter() { getEmitter() {
return SectView.propTarget; return SectView.propTarget;
}, },

Loading…
Cancel
Save