mframejs
Version:
simple framework
360 lines • 18.2 kB
JavaScript
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