From 322f3b5c69897945c6985bee8f03417addda65d5 Mon Sep 17 00:00:00 2001 From: Artur Arseniev Date: Tue, 10 Jan 2023 17:56:33 +0400 Subject: [PATCH] Move PropertyView to TS --- src/style_manager/model/Property.ts | 8 +- src/style_manager/model/PropertyComposite.ts | 3 +- src/style_manager/model/PropertyStack.ts | 3 +- src/style_manager/view/PropertyFileView.js | 2 +- src/style_manager/view/PropertySliderView.js | 2 +- src/style_manager/view/PropertyStackView.js | 2 +- .../view/{PropertyView.js => PropertyView.ts} | 135 +++++++++++------- 7 files changed, 95 insertions(+), 60 deletions(-) rename src/style_manager/view/{PropertyView.js => PropertyView.ts} (78%) diff --git a/src/style_manager/model/Property.ts b/src/style_manager/model/Property.ts index 2f4be7a52..d55118c78 100644 --- a/src/style_manager/model/Property.ts +++ b/src/style_manager/model/Property.ts @@ -21,6 +21,7 @@ export interface PropertyProps { status?: string; visible?: boolean; fixedValues?: string[]; + className?: string; onChange?: (data: { property: Property; from: PartialPropertyProps; @@ -68,6 +69,8 @@ export interface PropertyProps { __p?: any; } +export type StyleProps = Record; + export type OptionsUpdate = { partial?: boolean; noTarget?: boolean; @@ -96,6 +99,7 @@ type PartialPropertyProps = Partial; */ export default class Property = PropertyProps> extends Model { em!: EditorModel; + parent?: Property; static getDefaults() { return result(this.prototype, 'defaults'); @@ -168,7 +172,7 @@ export default class Property = PropertyProps> ext applyStyle && this.__upTargetsStyle({ [name]: value }, opts); } - __upTargetsStyle(style: Record, opts: any) { + __upTargetsStyle(style: StyleProps, opts: any) { const sm = this.em?.get('StyleManager'); sm?.addStyleTargets({ ...style, __p: !!opts.avoidStore }, opts); } @@ -313,9 +317,9 @@ export default class Property = PropertyProps> ext * @param {Object} [opts={}] Options * @param {Boolean} [opts.noTarget=false] If `true` the change won't be propagated to selected targets. */ - // @ts-ignore clear(opts = {}) { this._up(this.__getClearProps(), { ...opts, __clear: true }); + return this; } /** diff --git a/src/style_manager/model/PropertyComposite.ts b/src/style_manager/model/PropertyComposite.ts index 48454d808..93f2c8ebf 100644 --- a/src/style_manager/model/PropertyComposite.ts +++ b/src/style_manager/model/PropertyComposite.ts @@ -365,7 +365,8 @@ export default class PropertyComposite = PropertyC clear() { this.getProperties().map(p => p.clear({ __clearIn: !this.isDetached() })); - return Property.prototype.clear.call(this); + Property.prototype.clear.call(this); + return this; } hasValue(opts: Parameters[0]) { diff --git a/src/style_manager/model/PropertyStack.ts b/src/style_manager/model/PropertyStack.ts index 6edc322ca..06ddb0af2 100644 --- a/src/style_manager/model/PropertyStack.ts +++ b/src/style_manager/model/PropertyStack.ts @@ -540,7 +540,8 @@ export default class PropertyStack extends PropertyComposite clear(opts = {}) { this.__getLayers().reset(); this.__upTargetsStyleProps(opts); - return PropertyBase.prototype.clear.call(this); + PropertyBase.prototype.clear.call(this); + return this; } __canClearProp() { diff --git a/src/style_manager/view/PropertyFileView.js b/src/style_manager/view/PropertyFileView.js index 470e5ae5f..049b04938 100644 --- a/src/style_manager/view/PropertyFileView.js +++ b/src/style_manager/view/PropertyFileView.js @@ -4,7 +4,7 @@ import PropertyView from './PropertyView'; export default class PropertyFileView extends PropertyView { events() { return { - ...PropertyView.prototype.events, + ...PropertyView.prototype.events(), 'click [data-clear-asset]': 'clear', 'click [data-open-assets]': 'openAssetManager', }; diff --git a/src/style_manager/view/PropertySliderView.js b/src/style_manager/view/PropertySliderView.js index ee5752463..4ec87d702 100644 --- a/src/style_manager/view/PropertySliderView.js +++ b/src/style_manager/view/PropertySliderView.js @@ -3,7 +3,7 @@ import Property from './PropertyNumberView'; export default class PropertySliderView extends Property { events() { return { - ...Property.prototype.events, + ...Property.prototype.events(), 'change [type=range]': 'inputValueChanged', 'input [type=range]': 'inputValueChangedSoft', change: '', diff --git a/src/style_manager/view/PropertyStackView.js b/src/style_manager/view/PropertyStackView.js index 724386148..3b7b3e08a 100644 --- a/src/style_manager/view/PropertyStackView.js +++ b/src/style_manager/view/PropertyStackView.js @@ -5,7 +5,7 @@ import LayersView from './LayersView'; export default class PropertyStackView extends PropertyCompositeView { events() { return { - ...PropertyCompositeView.prototype.events, + ...PropertyCompositeView.prototype.events(), 'click [data-add-layer]': 'addLayer', change: '', }; diff --git a/src/style_manager/view/PropertyView.js b/src/style_manager/view/PropertyView.ts similarity index 78% rename from src/style_manager/view/PropertyView.js rename to src/style_manager/view/PropertyView.ts index 50dbe8a5c..bbef2341b 100644 --- a/src/style_manager/view/PropertyView.js +++ b/src/style_manager/view/PropertyView.ts @@ -1,11 +1,70 @@ import { bindAll, isUndefined, debounce } from 'underscore'; import { View } from '../../common'; +import EditorModel from '../../editor/model/Editor'; import { isObject } from '../../utils/mixins'; +import Property from '../model/Property'; +import { StyleProps } from '../model/PropertyComposite'; const clearProp = 'data-clear-style'; -export default class Property extends View { - template() { +export default class PropertyView extends View { + em: EditorModel; + pfx: string; + ppfx: string; + config: any; + parent?: PropertyView; + __destroyFn!: Function; + create?: Function; + destroy?: Function; + update?: Function; + onRender?: Function; + emit?: Function; + unset?: Function; + clearEl?: HTMLElement; + createdEl?: HTMLElement; + input?: HTMLInputElement; + $input?: any; + + constructor(o = {}) { + super(o); + bindAll(this, '__change', '__updateStyle'); + // @ts-ignore + const config = o.config || {}; + const { em } = config; + this.config = config; + this.em = em; + this.pfx = config.stylePrefix || ''; + this.ppfx = config.pStylePrefix || ''; + this.__destroyFn = this.destroy ? this.destroy.bind(this) : () => {}; + const { model } = this; + // @ts-ignore + model.view = this; + + // Put a sligh delay on debounce in order to execute the update + // post styleManager.__upProps trigger. + this.onValueChange = debounce(this.onValueChange.bind(this), 10); + this.updateStatus = debounce(this.updateStatus.bind(this), 0); + + this.listenTo(model, 'destroy remove', this.remove); + this.listenTo(model, 'change:visible', this.updateVisibility); + this.listenTo(model, 'change:name change:className change:full', this.render); + this.listenTo(model, 'change:value', this.onValueChange); + this.listenTo(model, 'change:parentTarget', this.updateStatus); + this.listenTo(em, 'change:device', this.onValueChange); + + // @ts-ignore + const init = this.init && this.init.bind(this); + init && init(); + } + + events() { + return { + change: 'inputValueChanged', + [`click [${clearProp}]`]: 'clear', + }; + } + + template(model: any) { const { pfx, ppfx } = this; return `
@@ -13,7 +72,7 @@ export default class Property extends View { `; } - templateLabel(model) { + templateLabel(model: Property) { const { pfx, em } = this; const { parent } = model; const { icon = '', info = '' } = model.attributes; @@ -28,7 +87,7 @@ export default class Property extends View { `; } - templateInput(model) { + templateInput(model: Property) { return `
@@ -36,38 +95,12 @@ export default class Property extends View { `; } - initialize(o = {}) { - bindAll(this, '__change', '__updateStyle'); - const config = o.config || {}; - const { em } = config; - this.config = config; - this.em = em; - this.pfx = config.stylePrefix || ''; - this.ppfx = config.pStylePrefix || ''; - this.__destroyFn = this.destroy ? this.destroy.bind(this) : () => {}; - const { model } = this; - model.view = this; - - // Put a sligh delay on debounce in order to execute the update - // post styleManager.__upProps trigger. - this.onValueChange = debounce(this.onValueChange.bind(this), 10); - this.updateStatus = debounce(this.updateStatus.bind(this)); - - this.listenTo(model, 'destroy remove', this.remove); - this.listenTo(model, 'change:visible', this.updateVisibility); - this.listenTo(model, 'change:name change:className change:full', this.render); - this.listenTo(model, 'change:value', this.onValueChange); - this.listenTo(model, 'change:parentTarget', this.updateStatus); - this.listenTo(em, 'change:device', this.onValueChange); - - const init = this.init && this.init.bind(this); - init && init(); - } - remove() { - View.prototype.remove.apply(this, arguments); + View.prototype.remove.apply(this, arguments as any); + // @ts-ignore ['em', 'input', '$input', 'view'].forEach(i => (this[i] = null)); this.__destroyFn(this._getClbOpts()); + return this; } /** @@ -81,7 +114,7 @@ export default class Property extends View { const computedCls = `${ppfx}color-warn`; const labelEl = this.$el.children(`.${pfx}label`); const clearStyleEl = this.getClearEl(); - const clearStyle = clearStyleEl ? clearStyleEl.style : {}; + const clearStyle = clearStyleEl ? clearStyleEl.style : ({} as CSSStyleDeclaration); labelEl.removeClass(`${updatedCls} ${computedCls}`); clearStyle.display = 'none'; @@ -98,7 +131,7 @@ export default class Property extends View { /** * Clear the property from the target */ - clear(ev) { + clear(ev: Event) { ev && ev.stopPropagation(); this.model.clear(); } @@ -109,7 +142,7 @@ export default class Property extends View { */ getClearEl() { if (!this.clearEl) { - this.clearEl = this.el.querySelector(`[${clearProp}]`); + this.clearEl = this.el.querySelector(`[${clearProp}]`)!; } return this.clearEl; @@ -119,14 +152,14 @@ export default class Property extends View { * Triggers when the value of element input/s is changed, so have to update * the value of the model which will propogate those changes to the target */ - inputValueChanged(ev) { + inputValueChanged(ev: any) { ev && ev.stopPropagation(); // Skip the default update in case a custom emit method is defined if (this.emit) return; this.model.upValue(ev.target.value); } - onValueChange(m, val, opt = {}) { + onValueChange(m: any, val: any, opt: any = {}) { this.setValue(this.model.getFullValue(undefined, { skipImportant: true })); this.updateStatus(); } @@ -136,21 +169,21 @@ export default class Property extends View { * Usually the value is a result of `model.getFullValue()` * @param {String} value The value from the model * */ - setValue(value) { + setValue(value: string) { const { model } = this; const result = isUndefined(value) || value === '' ? model.getDefaultValue() : value; if (this.update) return this.__update(result); this.__setValueInput(result); } - __setValueInput(value) { + __setValueInput(value: string) { const input = this.getInputEl(); input && (input.value = value); } getInputEl() { if (!this.input) { - this.input = this.el.querySelector('input'); + this.input = this.el.querySelector('input')!; } return this.input; @@ -161,9 +194,9 @@ export default class Property extends View { } clearCached() { - this.clearEl = null; - this.input = null; - this.$input = null; + delete this.clearEl; + delete this.input; + delete this.$input; } __unset() { @@ -171,7 +204,7 @@ export default class Property extends View { unset && unset(this._getClbOpts()); } - __update(value) { + __update(value: string) { const update = this.update && this.update.bind(this); update && update({ @@ -180,17 +213,17 @@ export default class Property extends View { }); } - __change(...args) { + __change(...args: any) { const emit = this.emit && this.emit.bind(this); emit && emit(this._getClbOpts(), ...args); } - __updateStyle(value, { complete, partial, ...opts } = {}) { + __updateStyle(value: string | StyleProps, { complete, partial, ...opts }: any = {}) { const { model } = this; const final = complete !== false && partial !== true; if (isObject(value)) { - model.__upTargetsStyle(value, { avoidStore: !final }); + model.__upTargetsStyle(value as StyleProps, { avoidStore: !final }); } else { model.upValue(value, { partial: !final }); } @@ -231,10 +264,6 @@ export default class Property extends View { const onRender = this.onRender && this.onRender.bind(this); onRender && onRender(); this.setValue(model.getValue()); + return this; } } - -Property.prototype.events = { - change: 'inputValueChanged', - [`click [${clearProp}]`]: 'clear', -};