Browse Source

Add new API for extending Style Manager properties

pull/2992/head
Artur Arseniev 6 years ago
parent
commit
260b210801
  1. 5
      src/domain_abstract/model/TypeableCollection.js
  2. 9
      src/style_manager/index.js
  3. 2
      src/style_manager/model/Properties.js
  4. 79
      src/style_manager/view/PropertyView.js
  5. 3
      src/utils/mixins.js

5
src/domain_abstract/model/TypeableCollection.js

@ -124,6 +124,11 @@ export default {
? view
: ViewInst.extend(view || {});
// New API
if (this.extendViewApi && !definition.model && !definition.view) {
view = view.extend(definition);
}
if (type) {
type.model = model;
type.view = view;

9
src/style_manager/index.js

@ -204,7 +204,7 @@ export default () => {
/**
* Get property by its CSS name and sector id
* @param {string} sectorId Sector id
* @param {string} name CSS property name, eg. 'min-height'
* @param {string} name CSS property name (or id), eg. 'min-height'
* @return {Property|null}
* @example
* var property = styleManager.getProperty('mySector','min-height');
@ -214,8 +214,11 @@ export default () => {
let prop = null;
if (sector) {
prop = sector.get('properties').where({ property: name });
prop = prop.length == 1 ? prop[0] : prop;
prop = sector
.get('properties')
.filter(
prop => prop.get('property') === name || prop.get('id') === name
)[0];
}
return prop;

2
src/style_manager/model/Properties.js

@ -18,6 +18,8 @@ import PropertyIntegerView from './../view/PropertyIntegerView';
import PropertyView from './../view/PropertyView';
export default Backbone.Collection.extend(TypeableCollection).extend({
extendViewApi: 1,
types: [
{
id: 'stack',

79
src/style_manager/view/PropertyView.js

@ -1,20 +1,16 @@
import Backbone from 'backbone';
import { bindAll, isArray, isUndefined, debounce } from 'underscore';
import { camelCase } from 'utils/mixins';
import { camelCase, isObject } from 'utils/mixins';
import { includes, each } from 'underscore';
const clearProp = 'data-clear-style';
export default Backbone.View.extend({
template(model) {
const pfx = this.pfx;
template() {
const { pfx, ppfx } = this;
return `
<div class="${pfx}label">
${this.templateLabel(model)}
</div>
<div class="${this.ppfx}fields">
${this.templateInput(model)}
</div>
<div class="${pfx}label" data-sm-label></div>
<div class="${ppfx}fields" data-sm-fields></div>
`;
},
@ -46,7 +42,7 @@ export default Backbone.View.extend({
},
initialize(o = {}) {
bindAll(this, 'targetUpdated');
bindAll(this, 'targetUpdated', '__change', '__updateStyle');
this.config = o.config || {};
const em = this.config.em;
this.em = em;
@ -63,6 +59,7 @@ export default Backbone.View.extend({
const pfx = this.pfx;
this.inputHolderId = '#' + pfx + 'input-holder';
this.sector = model.collection && model.collection.sector;
this.__destroyFn = this.destroy ? this.destroy.bind(this) : () => {};
model.view = this;
if (!model.get('value')) {
@ -100,6 +97,11 @@ export default Backbone.View.extend({
init && init();
},
remove() {
Backbone.View.prototype.remove.apply(this, arguments);
this.__destroyFn(this._getClbOpts());
},
/**
* Triggers when the status changes. The status indicates if the value of
* the proprerty is changed or inherited
@ -191,6 +193,7 @@ export default Backbone.View.extend({
*/
inputValueChanged(ev) {
ev && ev.stopPropagation();
if (this.emit) return;
this.model.setValueFromInput(this.getInputValue());
this.elementUpdated();
},
@ -588,6 +591,7 @@ export default Backbone.View.extend({
setValue(value) {
const model = this.model;
let val = isUndefined(value) ? model.getDefaultValue() : value;
if (this.update) return this.__update(val);
const input = this.getInputEl();
input && (input.value = val);
},
@ -625,16 +629,63 @@ export default Backbone.View.extend({
this.$input = null;
},
__update(value) {
const update = this.update && this.update.bind(this);
update &&
update({
...this._getClbOpts(),
value
});
},
__change(...args) {
const emit = this.emit && this.emit.bind(this);
emit && emit(this._getClbOpts(), ...args);
},
__updateStyle(value, { complete, ...opts } = {}) {
const final = complete !== false;
if (isObject(value)) {
this.getTargets().forEach(target =>
target.addStyle(value, { avoidStore: !final })
);
} else {
this.model.setValueFromInput(value, complete, opts);
}
final && this.elementUpdated();
},
_getClbOpts() {
const { model, el } = this;
return {
el,
props: model.attributes,
setProps: (...args) => model.set(...args),
change: this.__change,
updateStyle: this.__updateStyle,
targets: this.getTargets()
};
},
render() {
this.clearCached();
const pfx = this.pfx;
const model = this.model;
const el = this.el;
const { pfx, model, el, $el } = this;
const property = model.get('property');
const full = model.get('full');
const cls = model.get('className') || '';
const className = `${pfx}property`;
el.innerHTML = this.template(model);
this.createdEl && this.__destroyFn(this._getClbOpts());
$el.empty().append(this.template(model));
$el.find('[data-sm-label]').append(this.templateLabel(model));
const create = this.create && this.create.bind(this);
this.createdEl = create && create(this._getClbOpts());
$el
.find('[data-sm-fields]')
.append(this.createdEl || this.templateInput(model));
el.className = `${className} ${pfx}${model.get(
'type'
)} ${className}__${property} ${cls}`.trim();

3
src/utils/mixins.js

@ -210,6 +210,8 @@ const getPointerEvent = ev =>
const getKeyCode = ev => ev.which || ev.keyCode;
const getKeyChar = ev => String.fromCharCode(getKeyCode(ev));
const isEscKey = ev => getKeyCode(ev) === 27;
const isObject = val =>
val !== null && !Array.isArray(val) && typeof val === 'object';
const capitalize = str => str && str.charAt(0).toUpperCase() + str.substring(1);
const isComponent = obj => obj && obj.toHTML;
@ -242,6 +244,7 @@ export {
getViewEl,
setViewEl,
appendStyles,
isObject,
isComponent,
isRule
};

Loading…
Cancel
Save