data-tier
Advanced tools
Comparing version 3.4.0 to 3.5.0
@@ -7,3 +7,3 @@ import { DOMProcessor } from './dom-processor.js'; | ||
export const version = '3.4.0'; | ||
export const version = '3.5.0'; | ||
@@ -10,0 +10,0 @@ const initStartTime = performance.now(); |
@@ -1,1 +0,1 @@ | ||
import{DOMProcessor as o}from"./dom-processor.min.js";import{Ties as s}from"./ties.min.js";import{Views as e}from"./views.min.js";export{Observable}from"./ties.min.js";export const version="3.4.0";const t=performance.now();console.info("DT (3.4.0): starting initialization...");const r=new class{constructor(){this.params=Object.freeze(Array.from(new URL(import.meta.url).searchParams).reduce((o,s)=>(o[s[0]]=s[1],o),{})),this.paramsKey=Symbol("view.params.key"),this.domProcessor=new o(this),this.ties=new s(this),this.views=new e(this),"false"!==this.params.autostart&&!1!==this.params.autostart&&this.domProcessor.addDocument(document)}};export const ties=r.ties;export const addDocument=r.domProcessor.addDocument.bind(r.domProcessor);export const removeDocument=r.domProcessor.removeDocument.bind(r.domProcessor);console.info(`DT (3.4.0): ... initialization DONE (took ${(performance.now()-t).toFixed(2)}ms)`); | ||
import{DOMProcessor as o}from"./dom-processor.min.js";import{Ties as s}from"./ties.min.js";import{Views as e}from"./views.min.js";export{Observable}from"./ties.min.js";export const version="3.5.0";const t=performance.now();console.info("DT (3.5.0): starting initialization...");const r=new class{constructor(){this.params=Object.freeze(Array.from(new URL(import.meta.url).searchParams).reduce((o,s)=>(o[s[0]]=s[1],o),{})),this.paramsKey=Symbol("view.params.key"),this.domProcessor=new o(this),this.ties=new s(this),this.views=new e(this),"false"!==this.params.autostart&&!1!==this.params.autostart&&this.domProcessor.addDocument(document)}};export const ties=r.ties;export const addDocument=r.domProcessor.addDocument.bind(r.domProcessor);export const removeDocument=r.domProcessor.removeDocument.bind(r.domProcessor);console.info(`DT (3.5.0): ... initialization DONE (took ${(performance.now()-t).toFixed(2)}ms)`); |
@@ -130,3 +130,3 @@ import { Observable } from './object-observer.min.js'; | ||
} | ||
this.ties._dti.views.updateViewByModel(element, param, newValue); | ||
this.ties._dti.views.updateViewByModel(element, param, newValue, change.oldValue); | ||
} | ||
@@ -133,0 +133,0 @@ } |
@@ -1,1 +0,1 @@ | ||
import{Observable as e}from"./object-observer.min.js";import{TARGET_TYPES as t,getPath as i,callViewMethod as s,getRandomKey as o}from"./utils.min.js";export{e as Observable};const r=/^[a-zA-Z0-9]+$/,a=["scope"];class n{constructor(e,t,i){this.key=e,this.ties=i,this.model=t}set model(t){const[i,s]=function(t={}){return e.isObservable(t)?[t,!0]:t&&"object"==typeof t?[e.from(t),!0]:[t,!1]}(t);this._model=i,s&&this._model.observe(e=>this.processDataChanges(e))}get model(){return this._model}processDataChanges(e){const t=this.ties._dti.views.obtainTieViews(this.key),i=t._pathsCache,s=i.length;if(!s)return;let o,r,a,n,h,l,d,p,c,f,y,m,g,u,w="";for(let _=0,b=e.length;_<b;_++)if(n=(a=(o=e[_]).path).length,!a.some(e=>"symbol"==typeof e))for(m=!1,r=o.object,!Array.isArray(r)||"insert"!==o.type&&"delete"!==o.type||isNaN(a[a.length-1])?1===n?w=a[0]:n&&(w=2===n?a[0]+"."+a[1]:a.join(".")):(w=a.slice(0,-1).join("."),m=!0),c=w.length,h=s;h--;)if(c>(l=i[h]).length?(f=l,y=w):(f=w,y=l),g=f===y&&!m,0===y.indexOf(f))for(p=(d=t[l]).length;p--;)u=d[p],this.updateView(u,l,g,o)}updateView(e,o,r,a){const n=e[this.ties._dti.paramsKey];let h=n.length;for(;h--;){const l=n[h];if(l.targetType===t.METHOD){if(l.fParams.some(e=>e.tieKey===this.key&&e.rawPath===o)){let t=!1;const o=[];l.fParams.forEach(e=>{let s;const r=this.ties.get(e.tieKey);r&&(s=i(r,e.path),t=!0),o.push(s)}),t&&(o.push([a]),s(e,l.targetKey,o))}}else{if(l.tieKey!==this.key||l.rawPath!==o)continue;let t;t=void 0!==a.value&&r?a.value:i(this._model,l.path),this.ties._dti.views.updateViewByModel(e,l,t)}}}}export class Ties{constructor(e){this._dti=e,this._ties={}}get(e){const t="string"==typeof e?e:e&&e.getAttribute?e.getAttribute("data-tie-scope"):null,i=this._ties[t];return i?i.model:void 0}create(e,t){let i;if("string"==typeof e?i=e:e&&e.nodeType===Node.ELEMENT_NODE&&((i=e.getAttribute("data-tie-scope"))?console.log("inspect this"):(i=o(16),e.setAttribute("data-tie-scope",i))),Ties.validateTieKey(i),this._ties[i])throw new Error(`tie '${i}' already exists`);e.nodeType&&this._dti.views.addScope(e);const s=new n(i,t,this);return this._ties[i]=s,s.processDataChanges([{path:[]}]),s.model}update(e,t){if(void 0===t)throw new Error(`illegal model '${t}'`);const i="string"==typeof e?e:e&&e.getAttribute?e.getAttribute("data-tie-scope"):null,s=this._ties[i];return s?(s.model!==t&&(s.model=t,s.processDataChanges([{path:[]}])),s.model):this.create(e,t)}remove(e){let t=e;if("object"==typeof e)t=e.nodeType===Node.ELEMENT_NODE?e.getAttribute("data-tie-scope"):Object.keys(this._ties).find(t=>this._ties[t].model===e);else if("string"!=typeof e)throw new Error(`invalid tieToRemove parameter ${e}`);this._ties[t]&&(delete this._ties[t],this._dti.views.deleteTieViews(t))}static validateTieKey(e){if(!e||"string"!=typeof e)throw new Error(`invalid key '${e}'`);if(!r.test(e))throw new Error(`tie key MUST match ${r}; '${e}' doesn't`);if(a.indexOf(e)>=0)throw new Error(`tie key MUST NOT be one of those: ${a.join(", ")}`)}}; | ||
import{Observable as e}from"./object-observer.min.js";import{TARGET_TYPES as t,getPath as i,callViewMethod as s,getRandomKey as o}from"./utils.min.js";export{e as Observable};const r=/^[a-zA-Z0-9]+$/,a=["scope"];class n{constructor(e,t,i){this.key=e,this.ties=i,this.model=t}set model(t){const[i,s]=function(t={}){return e.isObservable(t)?[t,!0]:t&&"object"==typeof t?[e.from(t),!0]:[t,!1]}(t);this._model=i,s&&this._model.observe(e=>this.processDataChanges(e))}get model(){return this._model}processDataChanges(e){const t=this.ties._dti.views.obtainTieViews(this.key),i=t._pathsCache,s=i.length;if(!s)return;let o,r,a,n,h,l,d,p,c,f,y,m,g,u,w="";for(let _=0,b=e.length;_<b;_++)if(n=(a=(o=e[_]).path).length,!a.some(e=>"symbol"==typeof e))for(m=!1,r=o.object,!Array.isArray(r)||"insert"!==o.type&&"delete"!==o.type||isNaN(a[a.length-1])?1===n?w=a[0]:n&&(w=2===n?a[0]+"."+a[1]:a.join(".")):(w=a.slice(0,-1).join("."),m=!0),c=w.length,h=s;h--;)if(c>(l=i[h]).length?(f=l,y=w):(f=w,y=l),g=f===y&&!m,0===y.indexOf(f))for(p=(d=t[l]).length;p--;)u=d[p],this.updateView(u,l,g,o)}updateView(e,o,r,a){const n=e[this.ties._dti.paramsKey];let h=n.length;for(;h--;){const l=n[h];if(l.targetType===t.METHOD){if(l.fParams.some(e=>e.tieKey===this.key&&e.rawPath===o)){let t=!1;const o=[];l.fParams.forEach(e=>{let s;const r=this.ties.get(e.tieKey);r&&(s=i(r,e.path),t=!0),o.push(s)}),t&&(o.push([a]),s(e,l.targetKey,o))}}else{if(l.tieKey!==this.key||l.rawPath!==o)continue;let t;t=void 0!==a.value&&r?a.value:i(this._model,l.path),this.ties._dti.views.updateViewByModel(e,l,t,a.oldValue)}}}}export class Ties{constructor(e){this._dti=e,this._ties={}}get(e){const t="string"==typeof e?e:e&&e.getAttribute?e.getAttribute("data-tie-scope"):null,i=this._ties[t];return i?i.model:void 0}create(e,t){let i;if("string"==typeof e?i=e:e&&e.nodeType===Node.ELEMENT_NODE&&((i=e.getAttribute("data-tie-scope"))?console.log("inspect this"):(i=o(16),e.setAttribute("data-tie-scope",i))),Ties.validateTieKey(i),this._ties[i])throw new Error(`tie '${i}' already exists`);e.nodeType&&this._dti.views.addScope(e);const s=new n(i,t,this);return this._ties[i]=s,s.processDataChanges([{path:[]}]),s.model}update(e,t){if(void 0===t)throw new Error(`illegal model '${t}'`);const i="string"==typeof e?e:e&&e.getAttribute?e.getAttribute("data-tie-scope"):null,s=this._ties[i];return s?(s.model!==t&&(s.model=t,s.processDataChanges([{path:[]}])),s.model):this.create(e,t)}remove(e){let t=e;if("object"==typeof e)t=e.nodeType===Node.ELEMENT_NODE?e.getAttribute("data-tie-scope"):Object.keys(this._ties).find(t=>this._ties[t].model===e);else if("string"!=typeof e)throw new Error(`invalid tieToRemove parameter ${e}`);this._ties[t]&&(delete this._ties[t],this._dti.views.deleteTieViews(t))}static validateTieKey(e){if(!e||"string"!=typeof e)throw new Error(`invalid key '${e}'`);if(!r.test(e))throw new Error(`tie key MUST match ${r}; '${e}' doesn't`);if(a.indexOf(e)>=0)throw new Error(`tie key MUST NOT be one of those: ${a.join(", ")}`)}}; |
@@ -139,3 +139,3 @@ import { extractViewParams, getRandomKey, TARGET_TYPES } from './utils.js'; | ||
updateViewByModel(elem, param, value) { | ||
updateViewByModel(elem, param, value, oldValue) { | ||
const targetType = param.targetType || TARGET_TYPES.PROPERTY; | ||
@@ -146,6 +146,9 @@ const targetKey = param.targetKey; | ||
case TARGET_TYPES.ATTRIBUTE: | ||
this._unsafeSetAttribute(elem, param, value, targetKey); | ||
this._unsafeSetAttribute(elem, targetKey, value); | ||
break; | ||
case TARGET_TYPES.EVENT: | ||
this._unsafeSetEvent(elem, targetKey, value, oldValue); | ||
break; | ||
case TARGET_TYPES.PROPERTY: | ||
this._unsafeSetProperty(elem, param, value, targetKey); | ||
this._unsafeSetProperty(elem, param, targetKey, value); | ||
break; | ||
@@ -160,3 +163,3 @@ default: | ||
_unsafeSetAttribute(view, _param, value, targetAttribute) { | ||
_unsafeSetAttribute(view, targetAttribute, value) { | ||
if (value === null || value === undefined) { | ||
@@ -169,3 +172,12 @@ view.removeAttribute(targetAttribute); | ||
_unsafeSetProperty(view, param, value, targetProperty) { | ||
_unsafeSetEvent(view, targetEvent, value, oldValue) { | ||
if (typeof oldValue === 'function') { | ||
view.removeEventListener(targetEvent, oldValue); | ||
} | ||
if (typeof value === 'function') { | ||
view.addEventListener(targetEvent, value); | ||
} | ||
} | ||
_unsafeSetProperty(view, param, targetProperty, value) { | ||
if (targetProperty === 'textContent') { | ||
@@ -172,0 +184,0 @@ this._setTextContentProperty(view, value); |
@@ -1,1 +0,1 @@ | ||
import{extractViewParams as e,getRandomKey as t,TARGET_TYPES as s}from"./utils.min.js";export class Views{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(s){let i=s.getAttribute("data-tie-scope");if(i){if(i in this.scopes&&this.scopes[i]!==s)throw new Error(`scope key '${i} already claimed by another element`);if(this.scopes[i]!==s){this.scopes[i]=s;for(const t of this.unscoped)if(s.contains(t)){const s=e(t);s&&(this.addView(t,s),this.unscoped.splice(this.unscoped.indexOf(t),1))}}}else s.setAttribute("data-tie-scope",t(16))}delScope(){throw new Error("not implemented")}_handleView(e,t,i){let o,r,n,a,h=t.length;for(;h--;)if((o=t[h]).targetType===s.METHOD)for(a=(r=o.fParams).length;a--;)n=r[a],this[i?"_seekAndInsertView":"_seekAndRemoveView"](n,e);else this[i?"_seekAndInsertView":"_seekAndRemoveView"](o,e);i?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}const i=e.rawPath,o=this.obtainTieViews(s);let r=o[i];r||(r=[],o[i]=r,o._pathsCache.push(i)),r.indexOf(t)<0&&r.push(t)}_seekAndRemoveView(e,t){const s=e.tieKey,i=e.rawPath,o=this.views[s];if(o){const e=o[i];if(e){const s=e.indexOf(t);s>=0&&e.splice(s,1)}}}_lookupClosestScopeKey(e){let t,s=e;do{if(t=s.getAttribute("data-tie-scope"))break;(s=s.parentNode).host&&(s=s.host)}while(s&&s.nodeType!==Node.DOCUMENT_NODE);return t}updateViewByModel(e,t,i){const o=t.targetType||s.PROPERTY,r=t.targetKey;try{switch(o){case s.ATTRIBUTE:this._unsafeSetAttribute(e,t,i,r);break;case s.PROPERTY:this._unsafeSetProperty(e,t,i,r);break;default:throw new Error(`unsupported target type '${o}'`)}}catch(t){console.error(`failed to set '${r}' of '${e}' to '${i}'`,t)}}_unsafeSetAttribute(e,t,s,i){null===s||void 0===s?e.removeAttribute(i):e.setAttribute(i,String(s))}_unsafeSetProperty(e,t,s,i){if("textContent"===i)this._setTextContentProperty(e,s);else if("value"===i)this._setValueProperty(e,s);else if("href"===i&&"object"==typeof e.href)e.href.baseVal=s;else if("scope"===i)this.dti.ties.update(e,s);else if("classList"===i){const i=t.iClasses.slice(0);s&&(Array.isArray(s)&&s.length?s.forEach(e=>{i.indexOf(e)<0&&i.push(e)}):"object"==typeof s?Object.keys(s).forEach(e=>{const t=i.indexOf(e);s[e]?t<0&&i.push(e):t>=0&&i.splice(t,1)}):"string"==typeof s&&i.indexOf(s)<0&&i.push(s)),e.className=i.join(" ")}else e[i]=s}_setTextContentProperty(e,t){e.textContent=void 0===t||null===t?"":t}_setValueProperty(e,t){let s=t;if(void 0===t||null===t){const t=e.nodeName;"INPUT"!==t&&"SELECT"!==t&&"TEXTAREA"!==t||(s="")}e.value=s}}; | ||
import{extractViewParams as e,getRandomKey as t,TARGET_TYPES as s}from"./utils.min.js";export class Views{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(s){let i=s.getAttribute("data-tie-scope");if(i){if(i in this.scopes&&this.scopes[i]!==s)throw new Error(`scope key '${i} already claimed by another element`);if(this.scopes[i]!==s){this.scopes[i]=s;for(const t of this.unscoped)if(s.contains(t)){const s=e(t);s&&(this.addView(t,s),this.unscoped.splice(this.unscoped.indexOf(t),1))}}}else s.setAttribute("data-tie-scope",t(16))}delScope(){throw new Error("not implemented")}_handleView(e,t,i){let o,n,r,a,h=t.length;for(;h--;)if((o=t[h]).targetType===s.METHOD)for(a=(n=o.fParams).length;a--;)r=n[a],this[i?"_seekAndInsertView":"_seekAndRemoveView"](r,e);else this[i?"_seekAndInsertView":"_seekAndRemoveView"](o,e);i?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}const i=e.rawPath,o=this.obtainTieViews(s);let n=o[i];n||(n=[],o[i]=n,o._pathsCache.push(i)),n.indexOf(t)<0&&n.push(t)}_seekAndRemoveView(e,t){const s=e.tieKey,i=e.rawPath,o=this.views[s];if(o){const e=o[i];if(e){const s=e.indexOf(t);s>=0&&e.splice(s,1)}}}_lookupClosestScopeKey(e){let t,s=e;do{if(t=s.getAttribute("data-tie-scope"))break;(s=s.parentNode).host&&(s=s.host)}while(s&&s.nodeType!==Node.DOCUMENT_NODE);return t}updateViewByModel(e,t,i,o){const n=t.targetType||s.PROPERTY,r=t.targetKey;try{switch(n){case s.ATTRIBUTE:this._unsafeSetAttribute(e,r,i);break;case s.EVENT:this._unsafeSetEvent(e,r,i,o);break;case s.PROPERTY:this._unsafeSetProperty(e,t,r,i);break;default:throw new Error(`unsupported target type '${n}'`)}}catch(t){console.error(`failed to set '${r}' of '${e}' to '${i}'`,t)}}_unsafeSetAttribute(e,t,s){null===s||void 0===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 s=t.iClasses.slice(0);i&&(Array.isArray(i)&&i.length?i.forEach(e=>{s.indexOf(e)<0&&s.push(e)}):"object"==typeof i?Object.keys(i).forEach(e=>{const t=s.indexOf(e);i[e]?t<0&&s.push(e):t>=0&&s.splice(t,1)}):"string"==typeof i&&s.indexOf(i)<0&&s.push(i)),e.className=s.join(" ")}else e[s]=i}_setTextContentProperty(e,t){e.textContent=void 0===t||null===t?"":t}_setValueProperty(e,t){let s=t;if(void 0===t||null===t){const t=e.nodeName;"INPUT"!==t&&"SELECT"!==t&&"TEXTAREA"!==t||(s="")}e.value=s}}; |
{ | ||
"name": "data-tier", | ||
"version": "3.4.0", | ||
"version": "3.5.0", | ||
"description": "Tiny and fast two way (MV-VM) data binding framework for browser environments.", | ||
@@ -5,0 +5,0 @@ "type": "module", |
@@ -25,3 +25,3 @@ [![NPM](https://img.shields.io/npm/v/data-tier.svg?label=npm%20data-tier)](https://www.npmjs.com/package/data-tier) | ||
- attribute | ||
- event (in progress) | ||
- event | ||
- method | ||
@@ -28,0 +28,0 @@ - property |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
54801
890