data-tier
Version:
Tiny and fast two way (MV-VM) data binding framework for browser environments.
1 lines • 2.94 kB
JavaScript
import{extractViewParams as o,getRandomKey as r,TARGET_TYPES as h}from"./utils.min.js";class e{constructor(e){this.dti=e,this.views={},this.scopes={},this.unscoped=[]}obtainTieViews(e){let t=this.views[e];return t||(t={_pathsCache:[]},this.views[e]=t),t}deleteTieViews(e){delete this.views[e]}addView(e,t){this._handleView(e,t,!0)}delView(e,t){this._handleView(e,t,!1)}addScope(e){var t,s=e.getAttribute("data-tie-scope");if(s){if(s in this.scopes&&this.scopes[s]!==e)throw new Error(`scope key '${s} already claimed by another element`);if(this.scopes[s]!==e){this.scopes[s]=e;for(const i of this.unscoped)e.contains(i)&&(t=o(i))&&(this.addView(i,t),this.unscoped.splice(this.unscoped.indexOf(i),1))}}else e.setAttribute("data-tie-scope",r(16))}delScope(){throw new Error("not implemented")}_handleView(e,t,s){var i,o,r;let a=t.length,n;for(;a--;)if((i=t[a]).targetType===h.METHOD)for(o=i.fParams,n=o.length;n--;)r=o[n],this[s?"_seekAndInsertView":"_seekAndRemoveView"](r,e);else this[s?"_seekAndInsertView":"_seekAndRemoveView"](i,e);s?e[this.dti.paramsKey]=t:delete e[this.dti.paramsKey]}_seekAndInsertView(e,t){let s=e.tieKey;if("scope"===s){if(!(s=this._lookupClosestScopeKey(t)))return void this.unscoped.push(t);e.tieKey=s}var e=e.rawPath,i=this.obtainTieViews(s);let o=i[e];o||(o=[],i[e]=o,i._pathsCache.push(e)),o.indexOf(t)<0&&o.push(t)}_seekAndRemoveView(e,t){var s=e.tieKey,e=e.rawPath,s=this.views[s];s&&(s=s[e])&&0<=(e=s.indexOf(t))&&s.splice(e,1)}_lookupClosestScopeKey(e){let t=e,s;for(;!(s=t.getAttribute("data-tie-scope"))&&(t=(t=t.parentNode).host?t.host:t)&&t.nodeType!==Node.DOCUMENT_NODE;);return s}updateViewByModel(t,e,s,i){var o=e.targetType||h.PROPERTY,r=e.targetKey;try{switch(o){case h.ATTRIBUTE:this._unsafeSetAttribute(t,r,s);break;case h.EVENT:this._unsafeSetEvent(t,r,s,i);break;case h.PROPERTY:this._unsafeSetProperty(t,e,r,s);break;default:throw new Error(`unsupported target type '${o}'`)}}catch(e){console.error(`failed to set '${r}' of '${t}' to '${s}'`,e)}}_unsafeSetAttribute(e,t,s){null==s?e.removeAttribute(t):e.setAttribute(t,String(s))}_unsafeSetEvent(e,t,s,i){"function"==typeof i&&e.removeEventListener(t,i),"function"==typeof s&&e.addEventListener(t,s)}_unsafeSetProperty(e,t,s,i){if("textContent"===s)this._setTextContentProperty(e,i);else if("value"===s)this._setValueProperty(e,i);else if("href"===s&&"object"==typeof e.href)e.href.baseVal=i;else if("scope"===s)this.dti.ties.update(e,i);else if("classList"===s){const o=t.iClasses.slice(0);i&&(Array.isArray(i)&&i.length?i.forEach(e=>{o.indexOf(e)<0&&o.push(e)}):"object"==typeof i?Object.keys(i).forEach(e=>{var t=o.indexOf(e);i[e]?t<0&&o.push(e):0<=t&&o.splice(t,1)}):"string"==typeof i&&o.indexOf(i)<0&&o.push(i)),e.className=o.join(" ")}else e[s]=i}_setTextContentProperty(e,t){e.textContent=null==t?"":t}_setValueProperty(e,t){let s=t;null!=t||"INPUT"!==(t=e.nodeName)&&"SELECT"!==t&&"TEXTAREA"!==t||(s=""),e.value=s}}export{e as Views};