UNPKG

mframejs

Version:
360 lines 18.2 kB
import * as tslib_1 from "tslib"; import { customAttribute } from '../decorator/exported'; import { BindingEngine } from '../binding/exported'; import { Cache, connectBehavior } from '../utils/exported'; export class PropertyChangeHandler { constructor(node) { this.node = node; this.firstRun = true; this.name = 'valueAttribute'; } call(newValue, oldValue) { if (oldValue !== newValue || this.firstRun) { this.value = newValue; switch (true) { case this.node.type === 'textarea': case (this.node.type !== 'checkbox' && this.node.type !== 'radio' && this.node.type !== 'select-multiple' && this.node.type !== 'select-one'): this.node.value = newValue || ''; break; case this.node.type === 'checkbox': const modelBind = this.node.hasAttribute('model.bind') ? this.node.getAttributeNode('model.bind') : null; if (modelBind && modelBind.getContent) { const x = modelBind.getContent(); if (x) { if (Array.isArray(newValue)) { if (newValue.indexOf(x.value) !== -1) { this.node.checked = true; } else { this.node.checked = false; } } else { if (newValue === x.value) { this.node.checked = true; } else { this.node.checked = false; } } } } else { if (Array.isArray(newValue)) { console.warn('error: value is array, this should not happen'); } else { this.node.checked = newValue || false; } } break; case this.node.type === 'radio': if (this.node) { const modelBind = this.node.hasAttribute('model.bind') ? this.node.getAttributeNode('model.bind') : null; if (modelBind && modelBind.getContent) { const x = modelBind.getContent(); if (x) { if (newValue === x.value) { this.node.checked = true; } } } } break; case this.node.type === 'select-one': const optionsSingle = this.node.options; let index = null; for (let i = 0; i < optionsSingle.length; i++) { const modelBind = optionsSingle[i].hasAttribute('model.bind') ? optionsSingle[i].getAttributeNode('model.bind') : null; if (modelBind && modelBind.getContent) { const x = modelBind.getContent(); if (x) { if (Array.isArray(newValue)) { if (newValue[0] === x.value) { index = i; } } else { if (newValue === x.value) { index = i; } } } } } this.node.selectedIndex = index; break; case this.node.type === 'select-multiple': const optionsMany = this.node.options; for (let i = 0; i < optionsMany.length; i++) { const modelBind = optionsMany[i].hasAttribute('model.bind') ? optionsMany[i].getAttributeNode('model.bind') : null; if (modelBind && modelBind.getContent) { const x = modelBind.getContent(); if (x) { if (Array.isArray(newValue)) { if (newValue.indexOf(x.value) !== -1) { optionsMany[i].selected = true; } else { optionsMany[i].selected = false; } if (newValue.length === 0 && x.value === null) { optionsMany[i].selected = true; } } else { if (newValue === x.value) { optionsMany[i].selected = true; } else { optionsMany[i].selected = false; } } } } } break; } this.firstRun = false; } } } let ValueAttribute = class ValueAttribute { constructor() { this.valueConverters = []; this.eventHandlerBinded = this.eventHandler.bind(this); } attached() { if (this.$element.type === 'select-multiple') { this.propertyChangeHandler.call(this.propertyChangeHandler.value, 'somethign % its not'); } } created() { this.expressionValue = this.$attribute.value; this.attributeName = this.expressionValue.split('|')[0].trim().split('&')[0].trim(); this.trigger = null; this.name = this.$attribute.name; this.propertyChangeHandler = new PropertyChangeHandler(this.$element); switch (true) { case (this.$element.tagName === 'INPUT' && this.$element.type !== 'checkbox' && this.$element.type !== 'radio' && this.$element.type !== 'select-multiple' && this.$element.type !== 'select-one') || this.$element.tagName === 'TEXTAREA': BindingEngine.subscribeClassProperty(this.$bindingContext, this.expressionValue, this.propertyChangeHandler); connectBehavior(this.expressionValue, this); if (!this.trigger) { this.$element.addEventListener('input', this.eventHandlerBinded, false); } else { this.trigger.forEach((trigger) => { this.$element.addEventListener(trigger, this.eventHandlerBinded, false); }); } break; case this.$element.tagName === 'INPUT' && this.$element.type === 'checkbox': BindingEngine.subscribeClassProperty(this.$bindingContext, this.expressionValue, this.propertyChangeHandler); connectBehavior(this.expressionValue, this); if (!this.trigger) { this.$element.addEventListener('click', this.eventHandlerBinded, false); } else { this.trigger.forEach((trigger) => { this.$element.addEventListener(trigger, this.eventHandlerBinded, false); }); } break; case this.$element.tagName === 'INPUT' && this.$element.type === 'radio': BindingEngine.subscribeClassProperty(this.$bindingContext, this.expressionValue, this.propertyChangeHandler); connectBehavior(this.expressionValue, this); if (!this.trigger) { this.$element.addEventListener('click', this.eventHandlerBinded, false); } else { this.trigger.forEach((trigger) => { this.$element.addEventListener(trigger, this.eventHandlerBinded, false); }); } break; case this.$element.tagName === 'SELECT': BindingEngine.subscribeClassProperty(this.$bindingContext, this.expressionValue, this.propertyChangeHandler); connectBehavior(this.expressionValue, this); if (!this.trigger) { this.$element.addEventListener('change', this.eventHandlerBinded, false); } else { this.trigger.forEach((trigger) => { this.$element.addEventListener(trigger, this.eventHandlerBinded, false); }); } break; default: } } runValueConverter(value) { const x = Cache.expressionMap.get(this.expressionValue); return BindingEngine.valueConvert(x.ast, this.$bindingContext, value); } detached() { switch (true) { case (this.$element.tagName === 'INPUT' && this.$element.type !== 'checkbox' && this.$element.type !== 'radio' && this.$element.type !== 'select-multiple' && this.$element.type !== 'select-one') || this.$element.tagName === 'TEXTAREA': if (!this.trigger) { this.$element.removeEventListener('input', this.eventHandlerBinded); } else { this.trigger.forEach((trigger) => { this.$element.removeEventListener(trigger, this.eventHandlerBinded); }); } break; case this.$element.tagName === 'INPUT' && this.$element.type === 'checkbox': if (!this.trigger) { this.$element.removeEventListener('click', this.eventHandlerBinded); } else { this.trigger.forEach((trigger) => { this.$element.removeEventListener(trigger, this.eventHandlerBinded); }); } break; case this.$element.tagName === 'INPUT' && this.$element.type === 'radio': if (!this.trigger) { this.$element.removeEventListener('click', this.eventHandlerBinded); } else { this.trigger.forEach((trigger) => { this.$element.removeEventListener(trigger, this.eventHandlerBinded); }); } break; case this.$element.tagName === 'SELECT': if (!this.trigger) { this.$element.removeEventListener('change', this.eventHandlerBinded); } else { this.trigger.forEach((trigger) => { this.$element.removeEventListener(trigger, this.eventHandlerBinded); }); } break; default: this.$attribute.$bindingContext = null; break; } if (this.propertyChangeHandler.caller) { BindingEngine.unSubscribeClassProperty(this.$bindingContext, this.propertyChangeHandler); } } eventHandler() { switch (true) { case (this.$element.tagName === 'INPUT' && this.$element.type !== 'checkbox' && this.$element.type !== 'radio' && this.$element.type !== 'select-multiple' && this.$element.type !== 'select-one') || this.$element.tagName === 'TEXTAREA': let value = this.$element.value; if (this.$element.type === 'number') { value = this.$element.valueAsNumber; } if (this.$element.type === 'date') { value = this.$element.valueAsDate; } BindingEngine.setValue(this.$bindingContext, this.attributeName, this.runValueConverter(value)); break; case this.$element.tagName === 'INPUT' && this.$element.type === 'checkbox': const modelBindCheckbox = this.$element.hasAttribute('model.bind') ? this.$element.getAttributeNode('model.bind') : null; if (modelBindCheckbox) { const value = modelBindCheckbox.getContent().value; let propertyType = BindingEngine.evaluateExpression(this.$attribute.nodeValue, this.$bindingContext); const isArray = Array.isArray(propertyType); const selected = this.$element.checked; if (isArray) { if (selected) { const ii = propertyType.indexOf(value); if (ii === -1) { propertyType = [...propertyType, this.runValueConverter(value)]; BindingEngine.setValue(this.$bindingContext, this.attributeName, propertyType); } } else { const ii = propertyType.indexOf(value); if (ii !== -1) { propertyType.splice(ii, 1); if (!propertyType.__array_observer__class) { propertyType = [...propertyType]; } BindingEngine.setValue(this.$bindingContext, this.attributeName, propertyType); } else { this.$element.checked = false; } } } else { BindingEngine.setValue(this.$bindingContext, this.attributeName, this.runValueConverter(value) || false); } } else { BindingEngine.setValue(this.$bindingContext, this.attributeName, this.$element.checked || false); } break; case this.$element.tagName === 'INPUT' && this.$element.type === 'radio': const modelBindRadio = this.$element.hasAttribute('model.bind') ? this.$element.getAttributeNode('model.bind') : null; if (modelBindRadio) { const value = BindingEngine.evaluateExpression(modelBindRadio.nodeValue, modelBindRadio.getContent().$bindingContext); BindingEngine.setValue(this.$bindingContext, this.attributeName, this.runValueConverter(value)); } else { BindingEngine.setValue(this.$bindingContext, this.attributeName, this.runValueConverter(this.$element.checked)); } break; case this.$element.tagName === 'SELECT': const propertyType = BindingEngine.evaluateExpression(this.$attribute.nodeValue, this.$bindingContext); const isArray = Array.isArray(propertyType); const length = this.$element.selectedOptions.length; let finalValue = null; if (length > 1) { const values = []; for (let i = 0; i < length; i++) { const x = this.$element.selectedOptions[i]; const modelBind = x.hasAttribute('model.bind') ? x.getAttributeNode('model.bind') : null; const value = BindingEngine.evaluateExpression(modelBind.nodeValue, modelBind.getContent().$bindingContext); values.push(this.runValueConverter(value)); } finalValue = values; } else { if (length === 0) { finalValue = null; } else { const x = this.$element.selectedOptions[0]; const modelBind = x.hasAttribute('model.bind') ? x.getAttributeNode('model.bind') : null; const value = BindingEngine.evaluateExpression(modelBind.nodeValue, modelBind.getContent().$bindingContext); finalValue = value; } } if (isArray) { BindingEngine.setValue(this.$bindingContext, this.attributeName, Array.isArray(finalValue) ? finalValue : finalValue === null ? [] : [finalValue]); } else { BindingEngine.setValue(this.$bindingContext, this.attributeName, Array.isArray(finalValue) ? finalValue.map(a => a) : finalValue); } break; } } }; ValueAttribute = tslib_1.__decorate([ customAttribute('value.bind'), customAttribute('checked.bind'), tslib_1.__metadata("design:paramtypes", []) ], ValueAttribute); export { ValueAttribute }; //# sourceMappingURL=valueAttribute.js.map