UNPKG

pragma-views2

Version:

106 lines (87 loc) 3.8 kB
import {BehaviourBase} from "./behaviour-base.js"; import {addTriggers, removeTriggers, getObjOnPath, createFunctionForExpression, removeFunctionForExpression } from "../binding/observers.js"; import {domCaseMap} from "../binding/document-casemap.js"; import {setValueOnPath} from "../objectpath-helper.js"; import {inflateAttribute} from "../template-inflator.js"; import {postProcessPropertyChange} from "./behaviour-postprocess.js"; export class PropertyBehaviour extends BehaviourBase { static create(attr, bindingContext, property) { if (attr.nodeValue.indexOf("#") != -1) { return inflateAttribute(attr, bindingContext); } const result = new PropertyBehaviour(); result._attribute = attr; result._context = bindingContext; result._attrName = property; result._expression = attr.nodeValue; result.connectedCallback(attr.ownerElement); return result; } connectedCallback(element) { super.connectedCallback(element); this.initChangeEvent(); this.initBindings(); } disconnectedCallback(element) { super.disconnectedCallback(); removeFunctionForExpression(this._expression, this); removeTriggers(this._context, this._expression, this.fn); this.fn = null; this.changeHandler = null; this._pathStack = null; this._context = null; this._expression = null; this._attrName = null; this._attribute = null; } initChangeEvent() { const validListeners = ["INPUT", "TEXTAREA", "SELECT"]; if (validListeners.indexOf(this._element.nodeName) != -1) { this._pathStack = this._expression.split("."); this._fieldName = this._pathStack[this._pathStack.length - 1]; this.changeHandler = this.change.bind(this); this.registerEvent(this._element, "change", this.changeHandler); } } notifyPropertyChanged(name, value) { setValueOnPath(this._context, this._expression, value); } initBindings() { const resultFn = createFunctionForExpression(this._expression, this); const attrName = domCaseMap.has(this._attrName) ? domCaseMap.get(this._attrName) : this._attrName; if (attrName == "innerHTML") { this.fn = () => requestAnimationFrame(() => this._element ? this._element.innerHTML = resultFn(this._context) : null); } else { this.fn = () => { const property = this.createPropertyName(attrName); const oldValue = this._element[property]; const result = resultFn(this._context); Reflect.set(this._element, property, result); const changedName = `${property}Changed`; if (this._element[changedName] != undefined) { this._element[changedName].call(this._element, result, oldValue); } postProcessPropertyChange(this._element, property, result); } } addTriggers(this._context, this._expression, this.fn); this.fn(); } createPropertyName(name) { if (name.indexOf("-") == -1) { return name; } const stack = name.split("-"); let result = stack[0]; for (let i = 1; i < stack.length; i++) { const s = stack[i]; result += s.charAt(0).toUpperCase() + s.slice(1) } return result; } change(event) { const value = event.target.value; const obj = getObjOnPath(this._context, this._pathStack); obj[this._fieldName] = value; } }