Browse Source

Update state rule

up-style-manager
Artur Arseniev 5 years ago
parent
commit
3cadb40327
  1. 34
      src/css_composer/index.js
  2. 9
      src/domain_abstract/model/Styleable.js
  3. 89
      src/editor/model/Editor.js
  4. 51
      src/selector_manager/index.js
  5. 27
      src/style_manager/index.js
  6. 30
      src/undo_manager/index.js

34
src/css_composer/index.js

@ -225,14 +225,10 @@ export default () => {
if (isString(selectors)) {
const sm = em.get('SelectorManager');
const singleSel = selectors.split(',')[0].trim();
const node = em
.get('Parser')
.parserCss.checkNode({ selectors: singleSel })[0];
const node = em.get('Parser').parserCss.checkNode({ selectors: singleSel })[0];
slc = sm.get(node.selectors);
}
return (
rules.find(rule => rule.compare(slc, state, width, ruleProps)) || null
);
return rules.find(rule => rule.compare(slc, state, width, ruleProps)) || null;
},
getAll() {
@ -279,9 +275,7 @@ export default () => {
isObject(props) && model.set(props, opts);
if (updateStyle) {
let styleUpdate = opts.extend
? { ...model.get('style'), ...style }
: style;
let styleUpdate = opts.extend ? { ...model.get('style'), ...style } : style;
model.set('style', styleUpdate, opts);
}
@ -330,14 +324,14 @@ export default () => {
const { atRuleType, atRuleParams } = opts;
const node = em.get('Parser').parserCss.checkNode({
selectors,
style
style,
})[0];
const { state, selectorsAdd } = node;
const sm = em.get('SelectorManager');
const selector = sm.add(node.selectors);
const rule = this.add(selector, state, atRuleParams, {
selectorsAdd,
atRule: atRuleType
atRule: atRuleType,
});
rule.setStyle(style, opts);
return rule;
@ -368,7 +362,7 @@ export default () => {
selector &&
this.get(selector, state, atRuleParams, {
selectorsAdd,
atRule: atRuleType
atRule: atRuleType,
})
);
},
@ -388,12 +382,8 @@ export default () => {
getRules(selector) {
const rules = this.getAll();
if (!selector) return [...rules.models];
const sels = isString(selector)
? selector.split(',').map(s => s.trim())
: selector;
const result = rules.filter(
r => sels.indexOf(r.getSelectors().getFullString()) >= 0
);
const sels = isString(selector) ? selector.split(',').map(s => s.trim()) : selector;
const result = rules.filter(r => sels.indexOf(r.getSelectors().getFullString()) >= 0);
return result;
},
@ -492,9 +482,9 @@ export default () => {
* // Remove by selector
* css.remove('.my-cls-2');
*/
remove(rule) {
remove(rule, opts) {
const toRemove = isString(rule) ? this.getRules(rule) : rule;
const result = this.getAll().remove(toRemove);
const result = this.getAll().remove(toRemove, opts);
return isArray(result) ? result : [result];
},
@ -531,7 +521,7 @@ export default () => {
rulesView && rulesView.remove();
rulesView = new CssRulesView({
collection: rules,
config: c
config: c,
});
return rulesView.render().el;
},
@ -542,6 +532,6 @@ export default () => {
rulesView && rulesView.remove();
[em, rules, rulesView].forEach(i => (i = null));
c = {};
}
},
};
};

9
src/domain_abstract/model/Styleable.js

@ -44,6 +44,7 @@ export default {
const diff = shallowDiff(propOrig, propNew);
keys(diff).forEach(pr => {
const em = this.em;
if (opts.noEvent) return;
this.trigger(`change:style:${pr}`);
if (em) {
em.trigger(`styleable:change`, this, pr, opts);
@ -65,7 +66,7 @@ export default {
addStyle(prop, value = '', opts = {}) {
if (typeof prop == 'string') {
prop = {
prop: value
prop: value,
};
} else {
opts = value || {};
@ -110,9 +111,7 @@ export default {
},
getSelectorsString(opts) {
return this.selectorsToString
? this.selectorsToString(opts)
: this.getSelectors().getFullString();
return this.selectorsToString ? this.selectorsToString(opts) : this.getSelectors().getFullString();
},
_validate(attr, opts) {
@ -133,5 +132,5 @@ export default {
}
return true;
}
},
};

89
src/editor/model/Editor.js

@ -1,12 +1,4 @@
import {
isUndefined,
isFunction,
isArray,
contains,
toArray,
keys,
bindAll
} from 'underscore';
import { isUndefined, isFunction, isArray, contains, toArray, keys, bindAll } from 'underscore';
import Backbone from 'backbone';
import $ from 'utils/cash-dom';
import Extender from 'utils/extender';
@ -37,7 +29,7 @@ const deps = [
require('navigator'),
require('canvas'),
require('commands'),
require('block_manager')
require('block_manager'),
];
let timedInterval;
@ -45,14 +37,14 @@ let updateItr;
Extender({
Backbone: Backbone,
$: Backbone.$
$: Backbone.$,
});
const logs = {
debug: console.log,
info: console.info,
warning: console.warn,
error: console.error
error: console.error,
};
export default Backbone.Model.extend({
@ -69,7 +61,7 @@ export default Backbone.Model.extend({
modules: [],
toLoad: [],
opened: {},
device: ''
device: '',
};
},
@ -103,26 +95,18 @@ export default Backbone.Model.extend({
toLog.forEach(e => this.listenLog(e));
// Deprecations
[{ from: 'change:selectedComponent', to: 'component:toggled' }].forEach(
event => {
const eventFrom = event.from;
const eventTo = event.to;
this.listenTo(this, eventFrom, (...args) => {
this.trigger(eventTo, ...args);
this.logWarning(
`The event '${eventFrom}' is deprecated, replace it with '${eventTo}'`
);
});
}
);
[{ from: 'change:selectedComponent', to: 'component:toggled' }].forEach(event => {
const eventFrom = event.from;
const eventTo = event.to;
this.listenTo(this, eventFrom, (...args) => {
this.trigger(eventTo, ...args);
this.logWarning(`The event '${eventFrom}' is deprecated, replace it with '${eventTo}'`);
});
});
},
_checkReady() {
if (
this.get('readyLoad') &&
this.get('readyCanvas') &&
!this.get('ready')
) {
if (this.get('readyLoad') && this.get('readyCanvas') && !this.get('ready')) {
this.set('ready', true);
}
},
@ -206,9 +190,7 @@ export default Backbone.Model.extend({
const Module = moduleName.default || moduleName;
const Mod = new Module();
const name = Mod.name.charAt(0).toLowerCase() + Mod.name.slice(1);
const cfgParent = !isUndefined(config[name])
? config[name]
: config[Mod.name];
const cfgParent = !isUndefined(config[name]) ? config[name] : config[Mod.name];
const cfg = cfgParent === true ? {} : cfgParent || {};
const sm = this.get('StorageManager');
cfg.pStylePrefix = config.pStylePrefix || '';
@ -262,7 +244,7 @@ export default Backbone.Model.extend({
* */
handleUpdates(model, val, opt = {}) {
// Component has been added temporarily - do not update storage or record changes
if (opt.temporary || opt.noCount || opt.avoidStore || !this.get('ready')) {
if (this.__skip || opt.temporary || opt.noCount || opt.avoidStore || !this.get('ready')) {
return;
}
@ -538,7 +520,7 @@ export default Backbone.Model.extend({
exportWrapper,
wrapperIsBody,
...optsHtml,
...opts
...opts,
})
: '';
html += js ? `<script>${js}</script>` : '';
@ -555,9 +537,7 @@ export default Backbone.Model.extend({
const config = this.config;
const { optsCss, wrapperIsBody } = config;
const avoidProt = opts.avoidProtected;
const keepUnusedStyles = !isUndefined(opts.keepUnusedStyles)
? opts.keepUnusedStyles
: config.keepUnusedStyles;
const keepUnusedStyles = !isUndefined(opts.keepUnusedStyles) ? opts.keepUnusedStyles : config.keepUnusedStyles;
const cssc = this.get('CssComposer');
const wrp = opts.component || this.get('DomComponents').getComponent();
const protCss = !avoidProt ? config.protectedCss : '';
@ -568,7 +548,7 @@ export default Backbone.Model.extend({
wrapperIsBody,
keepUnusedStyles,
...optsCss,
...opts
...opts,
});
return wrp ? (opts.json ? css : protCss + css) : '';
},
@ -580,11 +560,7 @@ export default Backbone.Model.extend({
*/
getJs(opts = {}) {
var wrp = opts.component || this.get('DomComponents').getWrapper();
return wrp
? this.get('CodeManager')
.getCode(wrp, 'js')
.trim()
: '';
return wrp ? this.get('CodeManager').getCode(wrp, 'js').trim() : '';
},
/**
@ -810,14 +786,9 @@ export default Backbone.Model.extend({
this.stopListening();
this.clear({ silent: true });
this.destroyed = 1;
['config', 'view', '_previousAttributes', '_events', '_listeners'].forEach(
i => (this[i] = {})
);
['config', 'view', '_previousAttributes', '_events', '_listeners'].forEach(i => (this[i] = {}));
editors.splice(editors.indexOf(editor), 1);
hasWin() &&
$(config.el)
.empty()
.attr(this.attrsOrig);
hasWin() && $(config.el).empty().attr(this.attrsOrig);
},
getEditing() {
@ -874,10 +845,22 @@ export default Backbone.Model.extend({
chooseText: 'Ok',
cancelText: '⨯',
...opts,
...colorPicker
...colorPicker,
});
},
/**
* Execute actions without triggering the storage and undo manager.
* @param {Function} clb
* @private
*/
skip(clb) {
this.__skip = true;
const um = this.get('UndoManager');
um ? um.skip(clb) : clb();
this.__skip = false;
},
/**
* Set/get data from the HTMLElement
* @param {HTMLElement} el
@ -898,5 +881,5 @@ export default Backbone.Model.extend({
} else {
el[varName][name] = value;
}
}
},
});

51
src/selector_manager/index.js

@ -111,7 +111,7 @@ export default () => {
remove: evRemove,
removeBefore: evRemoveBefore,
state: evState,
custom: evCustom
custom: evCustom,
},
/**
@ -138,12 +138,10 @@ export default () => {
this.model = new Model({ cFirst: config.componentFirst, _undo: true });
this.__initListen({
collections: [this.states, this.selected],
propagate: [{ entity: this.states, event: this.events.state }]
propagate: [{ entity: this.states, event: this.events.state }],
});
em.on('change:state', (m, value) => em.trigger('selector:state', value));
this.model.on('change:cFirst', (m, value) =>
em.trigger('selector:type', value)
);
em.on('change:state', (m, value) => em.trigger(evState, value));
this.model.on('change:cFirst', (m, value) => em.trigger('selector:type', value));
const listenTo =
'component:toggled component:update:classes change:device styleManager:update selector:state selector:type';
this.model.listenTo(em, listenTo, () => this.__update());
@ -151,7 +149,7 @@ export default () => {
return this;
},
__update: debounce(function() {
__update: debounce(function () {
this.__trgCustom();
}),
@ -164,7 +162,7 @@ export default () => {
return {
states: this.getStates(),
selected: this.getSelected(),
container
container,
};
},
@ -188,11 +186,7 @@ export default () => {
const res = toSelect
.filter(i => i)
.map(sel =>
isComponent(sel)
? sel
: isRule(sel) && !sel.get('selectorsAdd')
? sel
: sel.getSelectorsString()
isComponent(sel) ? sel : isRule(sel) && !sel.get('selectorsAdd') ? sel : sel.getSelectorsString()
);
selTags && selTags.componentChanged({ targets: res });
return this;
@ -221,9 +215,7 @@ export default () => {
const cname = props.name;
const config = this.getConfig();
const all = this.getAll();
const selector = cname
? this.get(cname, props.type)
: all.where(props)[0];
const selector = cname ? this.get(cname, props.type) : all.where(props)[0];
if (!selector) {
return all.add(props, { ...cOpts, config });
@ -301,12 +293,8 @@ export default () => {
// Keep support for arrays but avoid it in docs
if (isArray(name)) {
const result = [];
const selectors = name
.map(item => this.getSelector(item))
.filter(item => item);
selectors.forEach(
item => result.indexOf(item) < 0 && result.push(item)
);
const selectors = name.map(item => this.getSelector(item)).filter(item => item);
selectors.forEach(item => result.indexOf(item) < 0 && result.push(item));
return result;
} else {
return this.getSelector(name, type) || null;
@ -402,9 +390,7 @@ export default () => {
*/
removeSelected(selector) {
this.em.getSelectedAll().forEach(trg => {
!selector.get('protected') &&
trg &&
trg.getSelectors().remove(selector);
!selector.get('protected') && trg && trg.getSelectors().remove(selector);
});
},
@ -471,7 +457,7 @@ export default () => {
el,
collection: this.selected,
module: this,
config
config,
});
return this.selectorTags.render().el;
@ -495,21 +481,16 @@ export default () => {
},
__getCommonSelectors(components, opts = {}) {
const selectors = components
.map(cmp => cmp.getSelectors && cmp.getSelectors().getValid(opts))
.filter(Boolean);
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);
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]);
}
return args.slice(1).reduce((acc, item) => this.__common(acc, item), args[0]);
},
};
};

27
src/style_manager/index.js

@ -339,7 +339,23 @@ export default () => {
targets = targets.map(t => this.getModelToStyle(t));
const lastTarget = targets.slice().reverse()[0];
const lastTargetParents = this.getParentRules(lastTarget, em.getState());
this.model.set({ targets, lastTarget, lastTargetParents });
let stateTarget = this.__getStateTarget();
em.skip(() => {
if (em.getState() && lastTarget?.getState?.()) {
const style = lastTarget.getStyle();
if (!stateTarget) {
stateTarget = cssc.getAll().add({ selectors: 'gjs-selected', style, important: true });
} else {
stateTarget.setStyle(style);
}
} else if (stateTarget) {
cssc.remove(stateTarget);
stateTarget = null;
}
});
this.model.set({ targets, lastTarget, lastTargetParents, stateTarget });
this.__upProps(opts);
return targets;
@ -370,6 +386,10 @@ export default () => {
return this.model.get('lastTargetParents') || [];
},
__getStateTarget() {
return this.model.get('stateTarget') || null;
},
/**
* Update selected targets with a custom style.
* @param {Object} style Style object
@ -379,6 +399,11 @@ export default () => {
*/
addStyleTargets(style, opts) {
this.getSelectedAll().map(t => t.addStyle(style, opts));
// Update state rule
const target = this.getSelected();
const targetState = this.__getStateTarget();
target && targetState?.setStyle(target.getStyle(), opts);
},
/**

30
src/undo_manager/index.js

@ -34,7 +34,7 @@ export default () => {
let beforeCache;
const configDef = {
maximumStackLength: 500,
trackSelection: 1
trackSelection: 1,
};
const hasSkip = opts => opts.avoidStore || opts.noUndo;
const getChanged = obj => Object.keys(obj.changedAttributes());
@ -59,13 +59,11 @@ export default () => {
if (hasUndo) {
const undoExc = object.get('_undoexc');
if (isArray(undoExc)) {
if (getChanged(object).some(chn => undoExc.indexOf(chn) >= 0))
return false;
if (getChanged(object).some(chn => undoExc.indexOf(chn) >= 0)) return false;
}
if (isBoolean(hasUndo)) return true;
if (isArray(hasUndo)) {
if (getChanged(object).some(chn => hasUndo.indexOf(chn) >= 0))
return true;
if (getChanged(object).some(chn => hasUndo.indexOf(chn) >= 0)) return true;
}
}
return false;
@ -84,7 +82,7 @@ export default () => {
const result = {
object,
before: beforeCache,
after
after,
};
beforeCache = null;
// Skip undo in case of empty changes
@ -92,7 +90,7 @@ export default () => {
return result;
}
}
},
});
um.changeUndoType('add', {
on: (model, collection, options = {}) => {
@ -101,9 +99,9 @@ export default () => {
object: collection,
before: undefined,
after: model,
options: { ...options, fromUndo }
options: { ...options, fromUndo },
};
}
},
});
um.changeUndoType('remove', {
on: (model, collection, options = {}) => {
@ -112,9 +110,9 @@ export default () => {
object: collection,
before: model,
after: undefined,
options: { ...options, fromUndo }
options: { ...options, fromUndo },
};
}
},
});
um.on('undo redo', () => {
@ -309,6 +307,12 @@ export default () => {
return result;
},
skip(clb) {
this.stop();
clb();
this.start();
},
__getStackRead() {
const result = {};
const createItem = item => {
@ -317,7 +321,7 @@ export default () => {
type,
after,
before,
object
object,
};
};
this.getStack().forEach(item => {
@ -352,6 +356,6 @@ export default () => {
this.clear().removeAll();
[em, um, config, beforeCache].forEach(i => (i = {}));
this.em = {};
}
},
};
};

Loading…
Cancel
Save