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
selectors: [],
// States
// Default states
states: [{ name: 'hover' }, { name: 'active' }, { name: 'nth-of-type(2n)' }],
// Custom selector name escaping strategy, eg.

110
src/selector_manager/index.js

@ -61,7 +61,7 @@
* @module SelectorManager
*/
import { isString, isElement, isObject, isArray } from 'underscore';
import { isString, debounce, isObject, isArray, isEmpty } from 'underscore';
import { isComponent, isRule } from 'utils/mixins';
import { Model } from 'common';
import Module from 'common/module';
@ -119,13 +119,37 @@ export default () => {
// Global selectors container
this.all = new Selectors(config.selectors);
this.selected = new Selectors([], { em, config });
this.model = new Model({ _undo: true });
this.__initListen();
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;
},
__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() {
// this.__postLoad();
// const { em, model } = this;
@ -136,6 +160,7 @@ export default () => {
postRender() {
this.__appendTo();
this.__trgCustom();
},
select(value, opts = {}) {
@ -155,6 +180,10 @@ export default () => {
return this;
},
getSelected() {
return this.em.get('StyleManager').getTargets();
},
addSelector(name, opts = {}, cOpts = {}) {
let props = { ...opts };
@ -296,13 +325,22 @@ export default () => {
},
/**
* Get the current selector state
* Get the current selector state value
* @returns {String}
*/
getState() {
return this.em.getState();
},
/**
* Get states
* @returns {Array<State>}
* @private
*/
getStates() {
return this.config.states;
},
/**
* Get all selectors
* @name getAll
@ -331,9 +369,11 @@ export default () => {
const { em, selectorTags } = this;
const config = this.getConfig();
const el = selectorTags && selectorTags.el;
this.selected.reset(selectors);
this.selectorTags = new ClassTagsView({
el,
collection: new Selectors(selectors || [], { em, config }),
collection: this.selected,
module: this,
config
});
@ -341,13 +381,75 @@ export default () => {
},
destroy() {
const { selectorTags } = this;
const { selectorTags, model } = this;
const all = this.getAll();
model.stopListening();
all.stopListening();
all.reset();
selectorTags && selectorTags.remove();
this.em = {};
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'
},
initialize(o) {
initialize(o = {}) {
const config = o.config || {};
this.config = config;
this.module = o.module;
this.coll = o.coll || null;
this.pfx = config.stylePrefix || '';
this.ppfx = config.pStylePrefix || '';
@ -97,11 +98,7 @@ export default Backbone.View.extend({
* @private
*/
removeTag() {
const { em, model } = this;
const targets = em && em.getSelectedAll();
targets.forEach(sel => {
!model.get('protected') && sel && sel.getSelectors().remove(model);
});
this.module.removeSelected(this.model);
},
/**

41
src/selector_manager/view/ClassTagsView.js

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

5
src/style_manager/index.js

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

Loading…
Cancel
Save