rasti 4.0.0-alpha.2 → 4.0.0-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/rasti.js +13 -10
- package/dist/rasti.min.js +1 -1
- package/es/Component.js +11 -8
- package/es/View.js +1 -1
- package/es/core/Interpolation.js +1 -1
- package/lib/Component.cjs +11 -8
- package/lib/View.cjs +1 -1
- package/lib/core/Interpolation.cjs +1 -1
- package/package.json +1 -1
- package/src/Component.js +11 -8
- package/src/View.js +1 -1
- package/src/core/Interpolation.js +1 -1
- package/src/index.js +0 -1
package/dist/rasti.js
CHANGED
|
@@ -838,7 +838,7 @@
|
|
|
838
838
|
* You shouldn't call this method directly. It's called from the constructor.
|
|
839
839
|
* You may override it if you want to use a different logic or to
|
|
840
840
|
* postpone element creation.
|
|
841
|
-
*/
|
|
841
|
+
*/
|
|
842
842
|
ensureElement() {
|
|
843
843
|
// Element is already present.
|
|
844
844
|
if (this.el) {
|
|
@@ -1494,7 +1494,7 @@
|
|
|
1494
1494
|
const endComment = findComment(parent, this.getEnd(), this.isComponent, startComment);
|
|
1495
1495
|
|
|
1496
1496
|
this.ref = [
|
|
1497
|
-
startComment,
|
|
1497
|
+
startComment,
|
|
1498
1498
|
endComment
|
|
1499
1499
|
];
|
|
1500
1500
|
}
|
|
@@ -1614,7 +1614,7 @@
|
|
|
1614
1614
|
* @return {string} String with placeholders.
|
|
1615
1615
|
* @private
|
|
1616
1616
|
*/
|
|
1617
|
-
const addPlaceholders = (strings, expressions) =>
|
|
1617
|
+
const addPlaceholders = (strings, expressions) =>
|
|
1618
1618
|
strings.reduce((out, string, i) => {
|
|
1619
1619
|
// Add string part.
|
|
1620
1620
|
out.push(string);
|
|
@@ -1684,10 +1684,11 @@
|
|
|
1684
1684
|
* Expand events.
|
|
1685
1685
|
* @param {object} attributes Attributes object.
|
|
1686
1686
|
* @param {EventsManager} eventsManager Events manager.
|
|
1687
|
+
* @param {Function} getDataAttribute Function to get data attribute name with uid.
|
|
1687
1688
|
* @return {object} Attributes object.
|
|
1688
1689
|
* @private
|
|
1689
1690
|
*/
|
|
1690
|
-
const expandEvents = (attributes, eventsManager) => {
|
|
1691
|
+
const expandEvents = (attributes, eventsManager, getDataAttribute) => {
|
|
1691
1692
|
const out = {};
|
|
1692
1693
|
Object.keys(attributes).forEach(key => {
|
|
1693
1694
|
// Check if key is an event listener.
|
|
@@ -1699,7 +1700,7 @@
|
|
|
1699
1700
|
if (listener) {
|
|
1700
1701
|
const index = eventsManager.addListener(listener, type);
|
|
1701
1702
|
// Add event listener index.
|
|
1702
|
-
out[
|
|
1703
|
+
out[getDataAttribute(type)] = index;
|
|
1703
1704
|
}
|
|
1704
1705
|
} else {
|
|
1705
1706
|
// Add attribute.
|
|
@@ -1839,7 +1840,8 @@
|
|
|
1839
1840
|
// Expand attributes and events.
|
|
1840
1841
|
const attributes = expandEvents(
|
|
1841
1842
|
expandAttributes(parsedAttributes, value => getExpressionResult(value, this)),
|
|
1842
|
-
this.eventsManager
|
|
1843
|
+
this.eventsManager,
|
|
1844
|
+
type => Component.ATTRIBUTE_EVENT(type, this.uid)
|
|
1843
1845
|
);
|
|
1844
1846
|
// Extend template attributes with `options.attributes`.
|
|
1845
1847
|
if (isRoot && this.attributes) {
|
|
@@ -1893,7 +1895,8 @@
|
|
|
1893
1895
|
const getAttributes = function() {
|
|
1894
1896
|
const attributes = expandEvents(
|
|
1895
1897
|
expandAttributes(parsedAttributes, value => getExpressionResult(value, this)),
|
|
1896
|
-
this.eventsManager
|
|
1898
|
+
this.eventsManager,
|
|
1899
|
+
type => Component.ATTRIBUTE_EVENT(type, this.uid)
|
|
1897
1900
|
);
|
|
1898
1901
|
|
|
1899
1902
|
return attributes;
|
|
@@ -2038,7 +2041,7 @@
|
|
|
2038
2041
|
const events = {};
|
|
2039
2042
|
// Create events object.
|
|
2040
2043
|
this.eventsManager.types.forEach(type => {
|
|
2041
|
-
const dataAttribute = Component.ATTRIBUTE_EVENT(type);
|
|
2044
|
+
const dataAttribute = Component.ATTRIBUTE_EVENT(type, this.uid);
|
|
2042
2045
|
// Create a listener function that gets the listener index from the data attribute and calls the listener.
|
|
2043
2046
|
const listener = function(event, component, matched) {
|
|
2044
2047
|
// Get the listener index from the data attribute.
|
|
@@ -2135,7 +2138,7 @@
|
|
|
2135
2138
|
this.el = this.children[0].el;
|
|
2136
2139
|
} else {
|
|
2137
2140
|
// Search for every element in template using getSelector
|
|
2138
|
-
this.template.elements.forEach((element, index) => {
|
|
2141
|
+
this.template.elements.forEach((element, index) => {
|
|
2139
2142
|
if (index === 0) {
|
|
2140
2143
|
element.hydrate(parent);
|
|
2141
2144
|
if (this.el) element.ref = this.el;
|
|
@@ -2726,7 +2729,7 @@
|
|
|
2726
2729
|
* Attributes used to identify elements and events.
|
|
2727
2730
|
*/
|
|
2728
2731
|
Component.ATTRIBUTE_ELEMENT = 'data-rasti-el';
|
|
2729
|
-
Component.ATTRIBUTE_EVENT = (type) => `data-rasti-on-${type}`;
|
|
2732
|
+
Component.ATTRIBUTE_EVENT = (type, uid) => `data-rasti-on-${type}-${uid}`;
|
|
2730
2733
|
|
|
2731
2734
|
/*
|
|
2732
2735
|
* Dataset attribute used to identify elements.
|
package/dist/rasti.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).Rasti={})}(this,(function(t){"use strict";function e(t){if("function"!=typeof t)throw new TypeError("Listener must be a function")}class s{on(t,s){return e(s),this.listeners||(this.listeners={}),this.listeners[t]||(this.listeners[t]=[]),this.listeners[t].push(s),()=>this.off(t,s)}once(t,s){e(s);const i=(...e)=>{s(...e),this.off(t,i)};return this.on(t,i)}off(t,e){this.listeners&&(t?this.listeners[t]&&(e?(this.listeners[t]=this.listeners[t].filter((t=>t!==e)),this.listeners[t].length||delete this.listeners[t]):delete this.listeners[t],Object.keys(this.listeners).length||delete this.listeners):delete this.listeners)}emit(t,...e){this.listeners&&this.listeners[t]&&this.listeners[t].slice().forEach((t=>t(...e)))}listenTo(t,e,s){return t.on(e,s),this.listeningTo||(this.listeningTo=[]),this.listeningTo.push({emitter:t,type:e,listener:s}),()=>this.stopListening(t,e,s)}listenToOnce(t,s,i){e(i);const n=(...e)=>{i(...e),this.stopListening(t,s,n)};return this.listenTo(t,s,n)}stopListening(t,e,s){this.listeningTo&&(this.listeningTo=this.listeningTo.filter((i=>!(!t||t===i.emitter&&!e||t===i.emitter&&e===i.type&&!s||t===i.emitter&&e===i.type&&s===i.listener)||(i.emitter.off(i.type,i.listener),!1))),this.listeningTo.length||delete this.listeningTo)}}const i=(t,e,...s)=>"function"!=typeof t?t:t.apply(e,s);class n extends s{constructor(){super(),this.preinitialize.apply(this,arguments),this.attributes=Object.assign({},i(this.defaults,this),this.parse.apply(this,arguments)),this.previous={},Object.keys(this.attributes).forEach(this.defineAttribute.bind(this))}preinitialize(){}defineAttribute(t){Object.defineProperty(this,`${this.constructor.attributePrefix}${t}`,{get:()=>this.get(t),set:e=>{this.set(t,e)}})}get(t){return this.attributes[t]}set(t,e,...s){let i,n;"object"==typeof t?(i=t,n=[e,...s]):(i={[t]:e},n=s);const r=this._changing;this._changing=!0;const h={};r||(this.previous=Object.assign({},this.attributes)),Object.keys(i).forEach((t=>{i[t]!==this.attributes[t]&&(h[t]=i[t],this.attributes[t]=i[t])}));const o=Object.keys(h);if(o.length&&(this._pending=["change",this,h,...n]),o.forEach((t=>{this.emit(`change:${t}`,this,i[t],...n)})),r)return this;for(;this._pending;){const t=this._pending;this._pending=null,this.emit.apply(this,t)}return this._pending=null,this._changing=!1,this}parse(t){return t}toJSON(){return Object.assign({},this.attributes)}}n.attributePrefix="";const r=["el","tag","attributes","events","model","template","onDestroy"];class h extends s{constructor(t={}){super(),this.preinitialize.apply(this,arguments),this.delegatedEventListeners=[],this.children=[],this.destroyQueue=[],this.viewOptions=[],r.forEach((e=>{e in t&&(this[e]=t[e],this.viewOptions.push(e))})),this.ensureUid(),this.ensureElement()}preinitialize(){}$(t){return this.el.querySelector(t)}$$(t){return this.el.querySelectorAll(t)}destroy(){return this.destroyChildren(),this.undelegateEvents(),this.stopListening(),this.off(),this.destroyQueue.forEach((t=>t())),this.destroyQueue=[],this.onDestroy.apply(this,arguments),this.destroyed=!0,this}onDestroy(){}addChild(t){return this.children.push(t),t}destroyChildren(){this.children.forEach((t=>t.destroy())),this.children=[]}ensureUid(){this.uid||(this.uid="r-"+ ++h.uid)}ensureElement(){if(this.el)this.el=i(this.el,this);else{const t=i(this.tag,this),e=i(this.attributes,this);this.el=this.createElement(t,e)}this.delegateEvents()}createElement(t="div",e={}){let s=document.createElement(t);return Object.keys(e).forEach((t=>s.setAttribute(t,e[t]))),s}removeElement(){return this.el.parentNode.removeChild(this.el),this}delegateEvents(t){if(t||(t=i(this.events,this)),!t)return this;this.delegatedEventListeners.length&&this.undelegateEvents();let s={};return Object.keys(t).forEach((i=>{const n=i.split(" "),r=n.shift(),h=n.join(" ");let o=t[i];"string"==typeof o&&(o=this[o]),e(o),s[r]||(s[r]=[]),s[r].push({selector:h,listener:o})})),Object.keys(s).forEach((t=>{const e=e=>{s[t].forEach((({selector:t,listener:s})=>{if(!t)return void s.call(this,e,this,this.el);let i=e.target;for(;i&&i!==this.el;)i.matches&&i.matches(t)&&s.call(this,e,this,i),i=i.parentElement}))};this.delegatedEventListeners.push({type:t,listener:e}),this.el.addEventListener(t,e)})),this}undelegateEvents(){return this.delegatedEventListeners.forEach((({type:t,listener:e})=>{this.el.removeEventListener(t,e)})),this.delegatedEventListeners=[],this}render(){return this.template&&(this.el.innerHTML=this.template(this.model)),this}static sanitize(t){return`${t}`.replace(/[&<>"']/g,(t=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[t])))}}h.uid=0;class o{constructor(t){this.value=t}toString(){return this.value}}class a{constructor(t){this.items=t}}class l{constructor(t,e){this.interpolationUid=t,this.result=e}}class c{constructor(){this.listeners=[],this.types=new Set,this.previousSize=0}addListener(t,e){return this.types.add(e),this.listeners.push(t),this.listeners.length-1}reset(){this.listeners=[],this.previousSize=this.types.size}hasPendingTypes(){return this.types.size>this.previousSize}}class u{constructor(){}reset(){this.paused=0,this.previous=this.tracked||new Map,this.tracked=new Map,this.positionStack=[0]}push(){this.positionStack.push(0)}pop(){this.positionStack.pop()}increment(){this.positionStack[this.positionStack.length-1]++}pause(){this.paused++}resume(){this.paused--}getPath(){return this.positionStack.join("-")}track(t){return 0===this.paused&&this.tracked.set(this.getPath(),t),t}findRecyclable(t){const e=this.previous.get(this.getPath());return e&&e.constructor===t&&!e.key?e:null}}const d=["value","checked","selected"];class p{constructor(t){this.getSelector=t.getSelector,this.getAttributes=t.getAttributes,this.previousAttributes={}}hydrate(t){this.ref=t.querySelector(this.getSelector())}update(){const t=this.getAttributes(),{remove:e,add:s}=function(t,e={}){const s={},i=[];return Object.keys(t).forEach((i=>{let n=t[i];n!==e[i]&&(!0===n?s[i]="":!1!==n&&(null==n&&(n=""),s[i]=n))})),Object.keys(e).forEach((s=>{(!(s in t)||e[s]!==t[s]&&!1===t[s])&&i.push(s)})),{add:s,remove:i}}(t,this.previousAttributes);this.previousAttributes=t,e.forEach((t=>{this.ref.removeAttribute(t),d.includes(t)&&t in this.ref&&(this.ref[t]="value"===t&&"")})),Object.keys(s).forEach((t=>{const e=s[t];this.ref.setAttribute(t,e),d.includes(t)&&t in this.ref&&(this.ref[t]="value"===t?e:!1!==e&&"false"!==e)}))}}const f=["value","checked","selected"];function g(t,e){t.nodeType===e.nodeType?t.nodeType!==Node.TEXT_NODE?t.tagName===e.tagName?(((t,e)=>{const s=e.attributes,i=t.attributes,n=new Set;for(let e=0,i=s.length;e<i;e++){const{name:i,value:r}=s[e];n.add(i),t.getAttribute(i)!==r&&t.setAttribute(i,r)}for(let e=i.length-1;e>=0;e--){const{name:s}=i[e];n.has(s)||t.removeAttribute(s)}for(let s=0,i=f.length;s<i;s++){const i=f[s];i in t&&t[i]!==e[i]&&(t[i]=e[i])}})(t,e),((t,e)=>{const s=t.childNodes,i=e.childNodes,n=s.length;if(n!==i.length)return!1;for(let t=0;t<n;t++)if(!s[t].isEqualNode(i[t]))return!1;return!0})(t,e)||((t,e)=>{const s=Array.from(e.childNodes);t.replaceChildren(...s)})(t,e)):t.replaceWith(e):t.nodeValue!==e.nodeValue&&(t.nodeValue=e.nodeValue):t.replaceWith(e)}function E(t,e,s=(()=>!1),i){let n=i||t.firstChild;for(;n;){if(n.nodeType===Node.COMMENT_NODE&&n.data.trim()===e)return n;if(n.nodeType!==Node.ELEMENT_NODE||s(n)||!n.firstChild){for(;n&&!n.nextSibling;)if(n=n.parentNode,!n||n===t)return null;n&&(n=n.nextSibling)}else n=n.firstChild}return null}class m{constructor(t){this.getStart=t.getStart,this.getEnd=t.getEnd,this.expression=t.expression,this.isComponent=t.isComponent,this.isElement=t.isElement}hydrate(t){const e=E(t,this.getStart(),this.isComponent),s=E(t,this.getEnd(),this.isComponent,e);this.ref=[e,s]}update(t){const[e,s]=this.ref,i=e.nextSibling,n=i.nextSibling===s,r=i==s,h=t.children;if(n&&1===h.length&&!this.isElement(i))g(i,h[0]);else if(r)s.parentNode.insertBefore(t,s);else{const i=document.createRange();i.setStartAfter(e),i.setEndBefore(s),i.deleteContents(),i.insertNode(t)}}}const y=t=>t.reduce(((t,e)=>(Array.isArray(e)?t.push(...y(e)):t.push(e),t)),[]);function T(t){const e=document.createElement("template");return e.innerHTML=`${t}`.trim(),e.content}function b(t){const e=[];return Object.keys(t).forEach((s=>{let i=t[s];!0===i?e.push(s):!1!==i&&(null==i&&(i=""),e.push(`${s}="${i}"`))})),e.join(" ")}const A=(t,e)=>i(t,e,e),v=t=>!!t.dataset[j.DATASET_ELEMENT]&&t.dataset[j.DATASET_ELEMENT].endsWith("-1"),R=t=>!!t.dataset[j.DATASET_ELEMENT],M=(t,e)=>t.reduce(((t,s,i)=>(t.push(s),void 0!==e[i]&&t.push(j.PLACEHOLDER(i)),t)),[]).join(""),L=(t,e)=>{const s=j.PLACEHOLDER("(\\d+)"),i=new RegExp(`${s}`,"g"),n=[];let r,h=0;for(;null!==(r=i.exec(t));){const s=t.slice(h,r.index);n.push(j.markAsSafeHTML(s),e[r[1]]),h=r.index+r[0].length}return n.push(j.markAsSafeHTML(t.slice(h))),n},C=(t,e)=>t.reduce(((t,s)=>{const i=e(s[0]);if(1===s.length)"object"==typeof i?t=Object.assign(t,i):"string"==typeof i&&(t[i]=!0);else{const n=s[2]?e(s[1]):s[1];t[i]=n}return t}),{}),S=(t,e)=>{const s={};return Object.keys(t).forEach((i=>{const n=i.match(/on(([A-Z]{1}[a-z]+)+)/);if(n&&n[1]){const r=n[1].toLowerCase(),h=t[i];if(h){const t=e.addListener(h,r);s[j.ATTRIBUTE_EVENT(r)]=t}}else s[i]=t[i]})),s},$=(t,e,s=!1)=>{const i=j.PLACEHOLDER("(\\d+)"),n=new Map;return s||(t=t.replace(new RegExp(i,"g"),((t,s)=>{const i=e[s];if(i&&i.prototype instanceof j){if(n.has(i))return n.get(i);n.set(i,t)}return t}))),t.replace(new RegExp(`<(${i})([^>]*)>([\\s\\S]*?)</\\1>|<(${i})([^>]*)/>`,"g"),((t,s,i,n,r,h,o,l)=>{let c,u,d;if(s?(c=e[i],u=n):(c=void 0!==o?e[o]:h,u=l),!(c.prototype instanceof j))return t;if(s){const t=$(r,e,!0),s=k(t,e);d=L(s,e)}const p=w(u,e);return e.push((function(){const t=C(p,(t=>A(t,this)));return d&&(t.renderChildren=()=>new a(d.map((t=>A(t,this))))),c.mount(t)})),j.PLACEHOLDER(e.length-1)}))},O=(t,e)=>{const s=j.PLACEHOLDER("(?:\\d+)");return t.replace(new RegExp(`<(${s}|[a-z]+[1-6]?)(?:\\s*)((?:"[^"]*"|'[^']*'|[^>])*)(/?>)`,"gi"),e)},x=(t,e,s)=>{const n=j.PLACEHOLDER("(?:\\d+)");if(t.match(new RegExp(`^\\s*${n}\\s*$`)))return t;if(!t.match(new RegExp(`^\\s*<([a-z]+[1-6]?|${n})([^>]*)>([\\s\\S]*?)</(\\1|${n})>\\s*$|^\\s*<([a-z]+[1-6]?|${n})([^>]*)/>\\s*$`)))throw new SyntaxError(`Template must have a single root element or be a container component: "${t.trim()}"`);let r=0;return O(t,((t,h,o,a)=>{const l=0===r,c=++r;if(!l&&!o.match(new RegExp(n)))return t;const u=w(o,e),d=t=>`${t}-${c}`,p=function(){const t=S(C(u,(t=>A(t,this))),this.eventsManager);return l&&this.attributes&&Object.assign(t,i(this.attributes,this)),t[j.ATTRIBUTE_ELEMENT]=d(this.uid),t};s.push({getSelector:function(){return`[${j.ATTRIBUTE_ELEMENT}="${d(this.uid)}"]`},getAttributes:p}),e.push((function(){const t=p.call(this);return j.markAsSafeHTML(b(t))}));return`<${h} ${j.PLACEHOLDER(e.length-1)}${a}`}))},k=(t,e)=>{const s=j.PLACEHOLDER("(?:\\d+)");return O(t,((t,i,n,r)=>{if(!n.match(new RegExp(s)))return t;const h=w(n,e),o=function(){return S(C(h,(t=>A(t,this))),this.eventsManager)};e.push((function(){const t=o.call(this);return j.markAsSafeHTML(b(t))}));return`<${i} ${j.PLACEHOLDER(e.length-1)}${r}`}))},N=(t,e,s)=>{const i=j.PLACEHOLDER("(\\d+)");let n=0;return t.replace(new RegExp(i,"g"),(function(i,r,h){const o=t.substring(0,h);if(o.lastIndexOf("<")>o.lastIndexOf(">"))return i;const a=++n;return s.push({getStart:function(){return j.MARKER_START(`${this.uid}-${a}`)},getEnd:function(){return j.MARKER_END(`${this.uid}-${a}`)},expression:e[r]}),e.push((function(){const t=A(e[r],this),s=`${this.uid}-${a}`;return new l(s,t)})),j.PLACEHOLDER(e.length-1)}))},w=(t,e)=>{const s=j.PLACEHOLDER("(\\d+)"),i=[],n=new RegExp(`(${s}|[\\w-]+)(?:=(["']?)(?:${s}|((?:.?(?!["']?\\s+(?:\\S+)=|\\s*/?[>"']))+.))\\3)?`,"g");let r;for(;null!==(r=n.exec(t));){const[,t,s,n,h,o]=r,a=void 0!==s?e[parseInt(s,10)]:t,l=void 0!==h?e[parseInt(h,10)]:o;void 0!==l?i.push([a,l,!!n]):i.push([a])}return i},_=["key","state","onCreate","onChange","onHydrate","onMount","onRecycle","onUpdate"];class j extends h{constructor(t={}){super(...arguments),this.componentOptions=[],_.forEach((e=>{e in t&&(this[e]=t[e],this.componentOptions.push(e))}));const e={};Object.keys(t).forEach((s=>{this.viewOptions.includes(s)||this.componentOptions.includes(s)||(e[s]=t[s])})),this.props=new n(e),this.options=t,this.partial=this.partial.bind(this),this.onChange=this.onChange.bind(this),this.onCreate.apply(this,arguments)}events(){const t={};return this.eventsManager.types.forEach((s=>{const i=j.ATTRIBUTE_EVENT(s),n=function(t,s,n){const r=n.getAttribute(i);if(r){let i=this.eventsManager.listeners[parseInt(r,10)];"string"==typeof i&&(i=this[i]),e(i),i.call(this,t,s,n)}};t[`${s} [${i}]`]=n,t[s]=n})),t}ensureElement(){this.eventsManager=new c,this.pathManager=new u,this.template=i(this.template,this),this.el&&(this.el=i(this.el,this),this.toString(),this.hydrate(this.el.parentNode))}isContainer(){return 0===this.template.elements.length&&1===this.template.interpolations.length}subscribe(t,e="change",s=this.onChange){return t.on&&this.listenTo(t,e,s),this}hydrate(t){return["model","state","props"].forEach((t=>{this[t]&&this.subscribe(this[t])})),this.isContainer()?(this.template.interpolations[0].hydrate(t),this.children[0].hydrate(t),this.el=this.children[0].el):(this.template.elements.forEach(((e,s)=>{0===s?(e.hydrate(t),this.el?e.ref=this.el:this.el=e.ref):e.hydrate(this.el)})),this.delegateEvents(),this.template.interpolations.forEach((t=>t.hydrate(this.el))),this.children.forEach((t=>t.hydrate(this.el)))),this.onHydrate.call(this),this}recycle(t){return E(t,j.MARKER_RECYCLED(this.uid),v).replaceWith(...this.getNodes()),this.onRecycle.call(this),this}getRecycledMarker(){return`\x3c!--${j.MARKER_RECYCLED(this.uid)}--\x3e`}getNodes(){return this.isContainer()?[this.template.interpolations[0].ref[0],...this.children[0].getNodes(),this.template.interpolations[0].ref[1]]:[this.el]}callOnMount(){return this.children.forEach((t=>t.callOnMount())),this.onMount.call(this),this}partial(t,...e){const s=L(k($(M(t,e),e),e),e).map((t=>A(t,this)));return new a(s)}renderTemplatePart(t,e){const s=A(t,this),i=t=>{if(null!=t&&!1!==t&&!0!==t){if(t instanceof o)return t;if(t instanceof j)return e(t);if(t instanceof a){this.pathManager.push();const e=t.items.map((t=>(this.pathManager.increment(),i(t)))).join("");return this.pathManager.pop(),e}if(Array.isArray(t)){this.pathManager.pause();const e=y(t).map(i).join("");return this.pathManager.resume(),e}if(t instanceof l){this.pathManager.increment();const e=`\x3c!--${j.MARKER_START(t.interpolationUid)}--\x3e`,s=`\x3c!--${j.MARKER_END(t.interpolationUid)}--\x3e`;return`${e}${i(t.result)}${s}`}return j.sanitize(t)}return""};return`${i(s)}`}toString(){this.destroyChildren(),this.eventsManager.reset(),this.pathManager.reset();const t=t=>(this.pathManager.track(t),this.addChild(t));return this.template.parts.map((e=>this.renderTemplatePart(e,t))).join("")}render(){if(this.destroyed)return this;if(!this.el){const t=T(this);return this.hydrate(t),this}this.eventsManager.reset(),this.pathManager.reset();const t=this.isContainer()?null:document.activeElement;this.template.elements.forEach((t=>t.update()));const e=this.children;return this.children=[],this.template.interpolations.forEach((t=>{const s=[],i=[];this.pathManager.increment();const n=T(this.renderTemplatePart(t.expression,(t=>{let n=t,r=null;return r=t.key?e.find((e=>e.key===t.key)):this.pathManager.findRecyclable(t.constructor),r?(n=r.getRecycledMarker(),i.push([r,t]),r.key||this.pathManager.track(r)):(s.push(t),this.pathManager.track(t)),n})));i.forEach((([t,e])=>{this.addChild(t).recycle(n),t.props.set(e.props.toJSON()),e.destroy()})),s.forEach((t=>this.addChild(t).hydrate(n))),t.update(n)})),this.children.forEach((t=>t.callOnMount())),e.forEach((t=>{this.children.indexOf(t)<0&&t.destroy()})),this.isContainer()?this.el=this.children[0].el:this.eventsManager.hasPendingTypes()&&this.delegateEvents(),t&&this.el.contains(t)&&t.focus(),this.onUpdate.call(this),this}onCreate(){}onChange(){this.render()}onHydrate(){}onMount(){}onRecycle(){}onUpdate(){}onDestroy(){}static markAsSafeHTML(t){return new o(t)}static extend(t){const e=this;class s extends e{}return Object.assign(s.prototype,"function"==typeof t?t(e.prototype):t),s}static mount(t,e,s){const i=new this(t);return e&&(s?(i.toString(),i.hydrate(e)):e.append(...i.render().getNodes()),i.callOnMount()),i}static create(t,...e){"function"==typeof t&&(e=[t],t=["",""]);const s=[],i=[],n=L(N(x($(M(t,e).trim(),e),e,s),e,i),e);return this.extend({template(){return{elements:s.map((t=>new p({getSelector:t.getSelector.bind(this),getAttributes:t.getAttributes.bind(this)}))),interpolations:i.map((t=>new m({getStart:t.getStart.bind(this),getEnd:t.getEnd.bind(this),expression:t.expression,isComponent:v,isElement:R}))),parts:n}}})}}j.ATTRIBUTE_ELEMENT="data-rasti-el",j.ATTRIBUTE_EVENT=t=>`data-rasti-on-${t}`,j.DATASET_ELEMENT="rastiEl",j.PLACEHOLDER=t=>`__RASTI-${t}__`,j.MARKER_RECYCLED=t=>`rasti-recycled-${t}`,j.MARKER_START=t=>`rasti-start-${t}`,j.MARKER_END=t=>`rasti-end-${t}`;var D=j.create`<div></div>`;t.Component=D,t.Emitter=s,t.Model=n,t.View=h}));
|
|
1
|
+
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).Rasti={})}(this,(function(t){"use strict";function e(t){if("function"!=typeof t)throw new TypeError("Listener must be a function")}class s{on(t,s){return e(s),this.listeners||(this.listeners={}),this.listeners[t]||(this.listeners[t]=[]),this.listeners[t].push(s),()=>this.off(t,s)}once(t,s){e(s);const i=(...e)=>{s(...e),this.off(t,i)};return this.on(t,i)}off(t,e){this.listeners&&(t?this.listeners[t]&&(e?(this.listeners[t]=this.listeners[t].filter((t=>t!==e)),this.listeners[t].length||delete this.listeners[t]):delete this.listeners[t],Object.keys(this.listeners).length||delete this.listeners):delete this.listeners)}emit(t,...e){this.listeners&&this.listeners[t]&&this.listeners[t].slice().forEach((t=>t(...e)))}listenTo(t,e,s){return t.on(e,s),this.listeningTo||(this.listeningTo=[]),this.listeningTo.push({emitter:t,type:e,listener:s}),()=>this.stopListening(t,e,s)}listenToOnce(t,s,i){e(i);const n=(...e)=>{i(...e),this.stopListening(t,s,n)};return this.listenTo(t,s,n)}stopListening(t,e,s){this.listeningTo&&(this.listeningTo=this.listeningTo.filter((i=>!(!t||t===i.emitter&&!e||t===i.emitter&&e===i.type&&!s||t===i.emitter&&e===i.type&&s===i.listener)||(i.emitter.off(i.type,i.listener),!1))),this.listeningTo.length||delete this.listeningTo)}}const i=(t,e,...s)=>"function"!=typeof t?t:t.apply(e,s);class n extends s{constructor(){super(),this.preinitialize.apply(this,arguments),this.attributes=Object.assign({},i(this.defaults,this),this.parse.apply(this,arguments)),this.previous={},Object.keys(this.attributes).forEach(this.defineAttribute.bind(this))}preinitialize(){}defineAttribute(t){Object.defineProperty(this,`${this.constructor.attributePrefix}${t}`,{get:()=>this.get(t),set:e=>{this.set(t,e)}})}get(t){return this.attributes[t]}set(t,e,...s){let i,n;"object"==typeof t?(i=t,n=[e,...s]):(i={[t]:e},n=s);const r=this._changing;this._changing=!0;const h={};r||(this.previous=Object.assign({},this.attributes)),Object.keys(i).forEach((t=>{i[t]!==this.attributes[t]&&(h[t]=i[t],this.attributes[t]=i[t])}));const o=Object.keys(h);if(o.length&&(this._pending=["change",this,h,...n]),o.forEach((t=>{this.emit(`change:${t}`,this,i[t],...n)})),r)return this;for(;this._pending;){const t=this._pending;this._pending=null,this.emit.apply(this,t)}return this._pending=null,this._changing=!1,this}parse(t){return t}toJSON(){return Object.assign({},this.attributes)}}n.attributePrefix="";const r=["el","tag","attributes","events","model","template","onDestroy"];class h extends s{constructor(t={}){super(),this.preinitialize.apply(this,arguments),this.delegatedEventListeners=[],this.children=[],this.destroyQueue=[],this.viewOptions=[],r.forEach((e=>{e in t&&(this[e]=t[e],this.viewOptions.push(e))})),this.ensureUid(),this.ensureElement()}preinitialize(){}$(t){return this.el.querySelector(t)}$$(t){return this.el.querySelectorAll(t)}destroy(){return this.destroyChildren(),this.undelegateEvents(),this.stopListening(),this.off(),this.destroyQueue.forEach((t=>t())),this.destroyQueue=[],this.onDestroy.apply(this,arguments),this.destroyed=!0,this}onDestroy(){}addChild(t){return this.children.push(t),t}destroyChildren(){this.children.forEach((t=>t.destroy())),this.children=[]}ensureUid(){this.uid||(this.uid="r-"+ ++h.uid)}ensureElement(){if(this.el)this.el=i(this.el,this);else{const t=i(this.tag,this),e=i(this.attributes,this);this.el=this.createElement(t,e)}this.delegateEvents()}createElement(t="div",e={}){let s=document.createElement(t);return Object.keys(e).forEach((t=>s.setAttribute(t,e[t]))),s}removeElement(){return this.el.parentNode.removeChild(this.el),this}delegateEvents(t){if(t||(t=i(this.events,this)),!t)return this;this.delegatedEventListeners.length&&this.undelegateEvents();let s={};return Object.keys(t).forEach((i=>{const n=i.split(" "),r=n.shift(),h=n.join(" ");let o=t[i];"string"==typeof o&&(o=this[o]),e(o),s[r]||(s[r]=[]),s[r].push({selector:h,listener:o})})),Object.keys(s).forEach((t=>{const e=e=>{s[t].forEach((({selector:t,listener:s})=>{if(!t)return void s.call(this,e,this,this.el);let i=e.target;for(;i&&i!==this.el;)i.matches&&i.matches(t)&&s.call(this,e,this,i),i=i.parentElement}))};this.delegatedEventListeners.push({type:t,listener:e}),this.el.addEventListener(t,e)})),this}undelegateEvents(){return this.delegatedEventListeners.forEach((({type:t,listener:e})=>{this.el.removeEventListener(t,e)})),this.delegatedEventListeners=[],this}render(){return this.template&&(this.el.innerHTML=this.template(this.model)),this}static sanitize(t){return`${t}`.replace(/[&<>"']/g,(t=>({"&":"&","<":"<",">":">",'"':""","'":"'"}[t])))}}h.uid=0;class o{constructor(t){this.value=t}toString(){return this.value}}class a{constructor(t){this.items=t}}class l{constructor(t,e){this.interpolationUid=t,this.result=e}}class c{constructor(){this.listeners=[],this.types=new Set,this.previousSize=0}addListener(t,e){return this.types.add(e),this.listeners.push(t),this.listeners.length-1}reset(){this.listeners=[],this.previousSize=this.types.size}hasPendingTypes(){return this.types.size>this.previousSize}}class u{constructor(){}reset(){this.paused=0,this.previous=this.tracked||new Map,this.tracked=new Map,this.positionStack=[0]}push(){this.positionStack.push(0)}pop(){this.positionStack.pop()}increment(){this.positionStack[this.positionStack.length-1]++}pause(){this.paused++}resume(){this.paused--}getPath(){return this.positionStack.join("-")}track(t){return 0===this.paused&&this.tracked.set(this.getPath(),t),t}findRecyclable(t){const e=this.previous.get(this.getPath());return e&&e.constructor===t&&!e.key?e:null}}const d=["value","checked","selected"];class p{constructor(t){this.getSelector=t.getSelector,this.getAttributes=t.getAttributes,this.previousAttributes={}}hydrate(t){this.ref=t.querySelector(this.getSelector())}update(){const t=this.getAttributes(),{remove:e,add:s}=function(t,e={}){const s={},i=[];return Object.keys(t).forEach((i=>{let n=t[i];n!==e[i]&&(!0===n?s[i]="":!1!==n&&(null==n&&(n=""),s[i]=n))})),Object.keys(e).forEach((s=>{(!(s in t)||e[s]!==t[s]&&!1===t[s])&&i.push(s)})),{add:s,remove:i}}(t,this.previousAttributes);this.previousAttributes=t,e.forEach((t=>{this.ref.removeAttribute(t),d.includes(t)&&t in this.ref&&(this.ref[t]="value"===t&&"")})),Object.keys(s).forEach((t=>{const e=s[t];this.ref.setAttribute(t,e),d.includes(t)&&t in this.ref&&(this.ref[t]="value"===t?e:!1!==e&&"false"!==e)}))}}const f=["value","checked","selected"];function E(t,e){t.nodeType===e.nodeType?t.nodeType!==Node.TEXT_NODE?t.tagName===e.tagName?(((t,e)=>{const s=e.attributes,i=t.attributes,n=new Set;for(let e=0,i=s.length;e<i;e++){const{name:i,value:r}=s[e];n.add(i),t.getAttribute(i)!==r&&t.setAttribute(i,r)}for(let e=i.length-1;e>=0;e--){const{name:s}=i[e];n.has(s)||t.removeAttribute(s)}for(let s=0,i=f.length;s<i;s++){const i=f[s];i in t&&t[i]!==e[i]&&(t[i]=e[i])}})(t,e),((t,e)=>{const s=t.childNodes,i=e.childNodes,n=s.length;if(n!==i.length)return!1;for(let t=0;t<n;t++)if(!s[t].isEqualNode(i[t]))return!1;return!0})(t,e)||((t,e)=>{const s=Array.from(e.childNodes);t.replaceChildren(...s)})(t,e)):t.replaceWith(e):t.nodeValue!==e.nodeValue&&(t.nodeValue=e.nodeValue):t.replaceWith(e)}function g(t,e,s=(()=>!1),i){let n=i||t.firstChild;for(;n;){if(n.nodeType===Node.COMMENT_NODE&&n.data.trim()===e)return n;if(n.nodeType!==Node.ELEMENT_NODE||s(n)||!n.firstChild){for(;n&&!n.nextSibling;)if(n=n.parentNode,!n||n===t)return null;n&&(n=n.nextSibling)}else n=n.firstChild}return null}class m{constructor(t){this.getStart=t.getStart,this.getEnd=t.getEnd,this.expression=t.expression,this.isComponent=t.isComponent,this.isElement=t.isElement}hydrate(t){const e=g(t,this.getStart(),this.isComponent),s=g(t,this.getEnd(),this.isComponent,e);this.ref=[e,s]}update(t){const[e,s]=this.ref,i=e.nextSibling,n=i.nextSibling===s,r=i==s,h=t.children;if(n&&1===h.length&&!this.isElement(i))E(i,h[0]);else if(r)s.parentNode.insertBefore(t,s);else{const i=document.createRange();i.setStartAfter(e),i.setEndBefore(s),i.deleteContents(),i.insertNode(t)}}}const y=t=>t.reduce(((t,e)=>(Array.isArray(e)?t.push(...y(e)):t.push(e),t)),[]);function T(t){const e=document.createElement("template");return e.innerHTML=`${t}`.trim(),e.content}function b(t){const e=[];return Object.keys(t).forEach((s=>{let i=t[s];!0===i?e.push(s):!1!==i&&(null==i&&(i=""),e.push(`${s}="${i}"`))})),e.join(" ")}const A=(t,e)=>i(t,e,e),v=t=>!!t.dataset[j.DATASET_ELEMENT]&&t.dataset[j.DATASET_ELEMENT].endsWith("-1"),R=t=>!!t.dataset[j.DATASET_ELEMENT],M=(t,e)=>t.reduce(((t,s,i)=>(t.push(s),void 0!==e[i]&&t.push(j.PLACEHOLDER(i)),t)),[]).join(""),L=(t,e)=>{const s=j.PLACEHOLDER("(\\d+)"),i=new RegExp(`${s}`,"g"),n=[];let r,h=0;for(;null!==(r=i.exec(t));){const s=t.slice(h,r.index);n.push(j.markAsSafeHTML(s),e[r[1]]),h=r.index+r[0].length}return n.push(j.markAsSafeHTML(t.slice(h))),n},$=(t,e)=>t.reduce(((t,s)=>{const i=e(s[0]);if(1===s.length)"object"==typeof i?t=Object.assign(t,i):"string"==typeof i&&(t[i]=!0);else{const n=s[2]?e(s[1]):s[1];t[i]=n}return t}),{}),C=(t,e,s)=>{const i={};return Object.keys(t).forEach((n=>{const r=n.match(/on(([A-Z]{1}[a-z]+)+)/);if(r&&r[1]){const h=r[1].toLowerCase(),o=t[n];if(o){const t=e.addListener(o,h);i[s(h)]=t}}else i[n]=t[n]})),i},S=(t,e,s=!1)=>{const i=j.PLACEHOLDER("(\\d+)"),n=new Map;return s||(t=t.replace(new RegExp(i,"g"),((t,s)=>{const i=e[s];if(i&&i.prototype instanceof j){if(n.has(i))return n.get(i);n.set(i,t)}return t}))),t.replace(new RegExp(`<(${i})([^>]*)>([\\s\\S]*?)</\\1>|<(${i})([^>]*)/>`,"g"),((t,s,i,n,r,h,o,l)=>{let c,u,d;if(s?(c=e[i],u=n):(c=void 0!==o?e[o]:h,u=l),!(c.prototype instanceof j))return t;if(s){const t=S(r,e,!0),s=k(t,e);d=L(s,e)}const p=w(u,e);return e.push((function(){const t=$(p,(t=>A(t,this)));return d&&(t.renderChildren=()=>new a(d.map((t=>A(t,this))))),c.mount(t)})),j.PLACEHOLDER(e.length-1)}))},O=(t,e)=>{const s=j.PLACEHOLDER("(?:\\d+)");return t.replace(new RegExp(`<(${s}|[a-z]+[1-6]?)(?:\\s*)((?:"[^"]*"|'[^']*'|[^>])*)(/?>)`,"gi"),e)},x=(t,e,s)=>{const n=j.PLACEHOLDER("(?:\\d+)");if(t.match(new RegExp(`^\\s*${n}\\s*$`)))return t;if(!t.match(new RegExp(`^\\s*<([a-z]+[1-6]?|${n})([^>]*)>([\\s\\S]*?)</(\\1|${n})>\\s*$|^\\s*<([a-z]+[1-6]?|${n})([^>]*)/>\\s*$`)))throw new SyntaxError(`Template must have a single root element or be a container component: "${t.trim()}"`);let r=0;return O(t,((t,h,o,a)=>{const l=0===r,c=++r;if(!l&&!o.match(new RegExp(n)))return t;const u=w(o,e),d=t=>`${t}-${c}`,p=function(){const t=C($(u,(t=>A(t,this))),this.eventsManager,(t=>j.ATTRIBUTE_EVENT(t,this.uid)));return l&&this.attributes&&Object.assign(t,i(this.attributes,this)),t[j.ATTRIBUTE_ELEMENT]=d(this.uid),t};s.push({getSelector:function(){return`[${j.ATTRIBUTE_ELEMENT}="${d(this.uid)}"]`},getAttributes:p}),e.push((function(){const t=p.call(this);return j.markAsSafeHTML(b(t))}));return`<${h} ${j.PLACEHOLDER(e.length-1)}${a}`}))},k=(t,e)=>{const s=j.PLACEHOLDER("(?:\\d+)");return O(t,((t,i,n,r)=>{if(!n.match(new RegExp(s)))return t;const h=w(n,e),o=function(){return C($(h,(t=>A(t,this))),this.eventsManager,(t=>j.ATTRIBUTE_EVENT(t,this.uid)))};e.push((function(){const t=o.call(this);return j.markAsSafeHTML(b(t))}));return`<${i} ${j.PLACEHOLDER(e.length-1)}${r}`}))},N=(t,e,s)=>{const i=j.PLACEHOLDER("(\\d+)");let n=0;return t.replace(new RegExp(i,"g"),(function(i,r,h){const o=t.substring(0,h);if(o.lastIndexOf("<")>o.lastIndexOf(">"))return i;const a=++n;return s.push({getStart:function(){return j.MARKER_START(`${this.uid}-${a}`)},getEnd:function(){return j.MARKER_END(`${this.uid}-${a}`)},expression:e[r]}),e.push((function(){const t=A(e[r],this),s=`${this.uid}-${a}`;return new l(s,t)})),j.PLACEHOLDER(e.length-1)}))},w=(t,e)=>{const s=j.PLACEHOLDER("(\\d+)"),i=[],n=new RegExp(`(${s}|[\\w-]+)(?:=(["']?)(?:${s}|((?:.?(?!["']?\\s+(?:\\S+)=|\\s*/?[>"']))+.))\\3)?`,"g");let r;for(;null!==(r=n.exec(t));){const[,t,s,n,h,o]=r,a=void 0!==s?e[parseInt(s,10)]:t,l=void 0!==h?e[parseInt(h,10)]:o;void 0!==l?i.push([a,l,!!n]):i.push([a])}return i},_=["key","state","onCreate","onChange","onHydrate","onMount","onRecycle","onUpdate"];class j extends h{constructor(t={}){super(...arguments),this.componentOptions=[],_.forEach((e=>{e in t&&(this[e]=t[e],this.componentOptions.push(e))}));const e={};Object.keys(t).forEach((s=>{this.viewOptions.includes(s)||this.componentOptions.includes(s)||(e[s]=t[s])})),this.props=new n(e),this.options=t,this.partial=this.partial.bind(this),this.onChange=this.onChange.bind(this),this.onCreate.apply(this,arguments)}events(){const t={};return this.eventsManager.types.forEach((s=>{const i=j.ATTRIBUTE_EVENT(s,this.uid),n=function(t,s,n){const r=n.getAttribute(i);if(r){let i=this.eventsManager.listeners[parseInt(r,10)];"string"==typeof i&&(i=this[i]),e(i),i.call(this,t,s,n)}};t[`${s} [${i}]`]=n,t[s]=n})),t}ensureElement(){this.eventsManager=new c,this.pathManager=new u,this.template=i(this.template,this),this.el&&(this.el=i(this.el,this),this.toString(),this.hydrate(this.el.parentNode))}isContainer(){return 0===this.template.elements.length&&1===this.template.interpolations.length}subscribe(t,e="change",s=this.onChange){return t.on&&this.listenTo(t,e,s),this}hydrate(t){return["model","state","props"].forEach((t=>{this[t]&&this.subscribe(this[t])})),this.isContainer()?(this.template.interpolations[0].hydrate(t),this.children[0].hydrate(t),this.el=this.children[0].el):(this.template.elements.forEach(((e,s)=>{0===s?(e.hydrate(t),this.el?e.ref=this.el:this.el=e.ref):e.hydrate(this.el)})),this.delegateEvents(),this.template.interpolations.forEach((t=>t.hydrate(this.el))),this.children.forEach((t=>t.hydrate(this.el)))),this.onHydrate.call(this),this}recycle(t){return g(t,j.MARKER_RECYCLED(this.uid),v).replaceWith(...this.getNodes()),this.onRecycle.call(this),this}getRecycledMarker(){return`\x3c!--${j.MARKER_RECYCLED(this.uid)}--\x3e`}getNodes(){return this.isContainer()?[this.template.interpolations[0].ref[0],...this.children[0].getNodes(),this.template.interpolations[0].ref[1]]:[this.el]}callOnMount(){return this.children.forEach((t=>t.callOnMount())),this.onMount.call(this),this}partial(t,...e){const s=L(k(S(M(t,e),e),e),e).map((t=>A(t,this)));return new a(s)}renderTemplatePart(t,e){const s=A(t,this),i=t=>{if(null!=t&&!1!==t&&!0!==t){if(t instanceof o)return t;if(t instanceof j)return e(t);if(t instanceof a){this.pathManager.push();const e=t.items.map((t=>(this.pathManager.increment(),i(t)))).join("");return this.pathManager.pop(),e}if(Array.isArray(t)){this.pathManager.pause();const e=y(t).map(i).join("");return this.pathManager.resume(),e}if(t instanceof l){this.pathManager.increment();const e=`\x3c!--${j.MARKER_START(t.interpolationUid)}--\x3e`,s=`\x3c!--${j.MARKER_END(t.interpolationUid)}--\x3e`;return`${e}${i(t.result)}${s}`}return j.sanitize(t)}return""};return`${i(s)}`}toString(){this.destroyChildren(),this.eventsManager.reset(),this.pathManager.reset();const t=t=>(this.pathManager.track(t),this.addChild(t));return this.template.parts.map((e=>this.renderTemplatePart(e,t))).join("")}render(){if(this.destroyed)return this;if(!this.el){const t=T(this);return this.hydrate(t),this}this.eventsManager.reset(),this.pathManager.reset();const t=this.isContainer()?null:document.activeElement;this.template.elements.forEach((t=>t.update()));const e=this.children;return this.children=[],this.template.interpolations.forEach((t=>{const s=[],i=[];this.pathManager.increment();const n=T(this.renderTemplatePart(t.expression,(t=>{let n=t,r=null;return r=t.key?e.find((e=>e.key===t.key)):this.pathManager.findRecyclable(t.constructor),r?(n=r.getRecycledMarker(),i.push([r,t]),r.key||this.pathManager.track(r)):(s.push(t),this.pathManager.track(t)),n})));i.forEach((([t,e])=>{this.addChild(t).recycle(n),t.props.set(e.props.toJSON()),e.destroy()})),s.forEach((t=>this.addChild(t).hydrate(n))),t.update(n)})),this.children.forEach((t=>t.callOnMount())),e.forEach((t=>{this.children.indexOf(t)<0&&t.destroy()})),this.isContainer()?this.el=this.children[0].el:this.eventsManager.hasPendingTypes()&&this.delegateEvents(),t&&this.el.contains(t)&&t.focus(),this.onUpdate.call(this),this}onCreate(){}onChange(){this.render()}onHydrate(){}onMount(){}onRecycle(){}onUpdate(){}onDestroy(){}static markAsSafeHTML(t){return new o(t)}static extend(t){const e=this;class s extends e{}return Object.assign(s.prototype,"function"==typeof t?t(e.prototype):t),s}static mount(t,e,s){const i=new this(t);return e&&(s?(i.toString(),i.hydrate(e)):e.append(...i.render().getNodes()),i.callOnMount()),i}static create(t,...e){"function"==typeof t&&(e=[t],t=["",""]);const s=[],i=[],n=L(N(x(S(M(t,e).trim(),e),e,s),e,i),e);return this.extend({template(){return{elements:s.map((t=>new p({getSelector:t.getSelector.bind(this),getAttributes:t.getAttributes.bind(this)}))),interpolations:i.map((t=>new m({getStart:t.getStart.bind(this),getEnd:t.getEnd.bind(this),expression:t.expression,isComponent:v,isElement:R}))),parts:n}}})}}j.ATTRIBUTE_ELEMENT="data-rasti-el",j.ATTRIBUTE_EVENT=(t,e)=>`data-rasti-on-${t}-${e}`,j.DATASET_ELEMENT="rastiEl",j.PLACEHOLDER=t=>`__RASTI-${t}__`,j.MARKER_RECYCLED=t=>`rasti-recycled-${t}`,j.MARKER_START=t=>`rasti-start-${t}`,j.MARKER_END=t=>`rasti-end-${t}`;var D=j.create`<div></div>`;t.Component=D,t.Emitter=s,t.Model=n,t.View=h}));
|
package/es/Component.js
CHANGED
|
@@ -52,7 +52,7 @@ const isElement = (el) => !!el.dataset[Component.DATASET_ELEMENT];
|
|
|
52
52
|
* @return {string} String with placeholders.
|
|
53
53
|
* @private
|
|
54
54
|
*/
|
|
55
|
-
const addPlaceholders = (strings, expressions) =>
|
|
55
|
+
const addPlaceholders = (strings, expressions) =>
|
|
56
56
|
strings.reduce((out, string, i) => {
|
|
57
57
|
// Add string part.
|
|
58
58
|
out.push(string);
|
|
@@ -122,10 +122,11 @@ const expandAttributes = (attributes, getExpressionResult) => attributes.reduce(
|
|
|
122
122
|
* Expand events.
|
|
123
123
|
* @param {object} attributes Attributes object.
|
|
124
124
|
* @param {EventsManager} eventsManager Events manager.
|
|
125
|
+
* @param {Function} getDataAttribute Function to get data attribute name with uid.
|
|
125
126
|
* @return {object} Attributes object.
|
|
126
127
|
* @private
|
|
127
128
|
*/
|
|
128
|
-
const expandEvents = (attributes, eventsManager) => {
|
|
129
|
+
const expandEvents = (attributes, eventsManager, getDataAttribute) => {
|
|
129
130
|
const out = {};
|
|
130
131
|
Object.keys(attributes).forEach(key => {
|
|
131
132
|
// Check if key is an event listener.
|
|
@@ -137,7 +138,7 @@ const expandEvents = (attributes, eventsManager) => {
|
|
|
137
138
|
if (listener) {
|
|
138
139
|
const index = eventsManager.addListener(listener, type);
|
|
139
140
|
// Add event listener index.
|
|
140
|
-
out[
|
|
141
|
+
out[getDataAttribute(type)] = index;
|
|
141
142
|
}
|
|
142
143
|
} else {
|
|
143
144
|
// Add attribute.
|
|
@@ -277,7 +278,8 @@ const parseElements = (template, expressions, elements) => {
|
|
|
277
278
|
// Expand attributes and events.
|
|
278
279
|
const attributes = expandEvents(
|
|
279
280
|
expandAttributes(parsedAttributes, value => getExpressionResult(value, this)),
|
|
280
|
-
this.eventsManager
|
|
281
|
+
this.eventsManager,
|
|
282
|
+
type => Component.ATTRIBUTE_EVENT(type, this.uid)
|
|
281
283
|
);
|
|
282
284
|
// Extend template attributes with `options.attributes`.
|
|
283
285
|
if (isRoot && this.attributes) {
|
|
@@ -331,7 +333,8 @@ const parsePartialElements = (template, expressions) => {
|
|
|
331
333
|
const getAttributes = function() {
|
|
332
334
|
const attributes = expandEvents(
|
|
333
335
|
expandAttributes(parsedAttributes, value => getExpressionResult(value, this)),
|
|
334
|
-
this.eventsManager
|
|
336
|
+
this.eventsManager,
|
|
337
|
+
type => Component.ATTRIBUTE_EVENT(type, this.uid)
|
|
335
338
|
);
|
|
336
339
|
|
|
337
340
|
return attributes;
|
|
@@ -476,7 +479,7 @@ class Component extends View {
|
|
|
476
479
|
const events = {};
|
|
477
480
|
// Create events object.
|
|
478
481
|
this.eventsManager.types.forEach(type => {
|
|
479
|
-
const dataAttribute = Component.ATTRIBUTE_EVENT(type);
|
|
482
|
+
const dataAttribute = Component.ATTRIBUTE_EVENT(type, this.uid);
|
|
480
483
|
// Create a listener function that gets the listener index from the data attribute and calls the listener.
|
|
481
484
|
const listener = function(event, component, matched) {
|
|
482
485
|
// Get the listener index from the data attribute.
|
|
@@ -573,7 +576,7 @@ class Component extends View {
|
|
|
573
576
|
this.el = this.children[0].el;
|
|
574
577
|
} else {
|
|
575
578
|
// Search for every element in template using getSelector
|
|
576
|
-
this.template.elements.forEach((element, index) => {
|
|
579
|
+
this.template.elements.forEach((element, index) => {
|
|
577
580
|
if (index === 0) {
|
|
578
581
|
element.hydrate(parent);
|
|
579
582
|
if (this.el) element.ref = this.el;
|
|
@@ -1164,7 +1167,7 @@ class Component extends View {
|
|
|
1164
1167
|
* Attributes used to identify elements and events.
|
|
1165
1168
|
*/
|
|
1166
1169
|
Component.ATTRIBUTE_ELEMENT = 'data-rasti-el';
|
|
1167
|
-
Component.ATTRIBUTE_EVENT = (type) => `data-rasti-on-${type}`;
|
|
1170
|
+
Component.ATTRIBUTE_EVENT = (type, uid) => `data-rasti-on-${type}-${uid}`;
|
|
1168
1171
|
|
|
1169
1172
|
/*
|
|
1170
1173
|
* Dataset attribute used to identify elements.
|
package/es/View.js
CHANGED
|
@@ -168,7 +168,7 @@ class View extends Emitter {
|
|
|
168
168
|
* You shouldn't call this method directly. It's called from the constructor.
|
|
169
169
|
* You may override it if you want to use a different logic or to
|
|
170
170
|
* postpone element creation.
|
|
171
|
-
*/
|
|
171
|
+
*/
|
|
172
172
|
ensureElement() {
|
|
173
173
|
// Element is already present.
|
|
174
174
|
if (this.el) {
|
package/es/core/Interpolation.js
CHANGED
package/lib/Component.cjs
CHANGED
|
@@ -54,7 +54,7 @@ const isElement = (el) => !!el.dataset[Component.DATASET_ELEMENT];
|
|
|
54
54
|
* @return {string} String with placeholders.
|
|
55
55
|
* @private
|
|
56
56
|
*/
|
|
57
|
-
const addPlaceholders = (strings, expressions) =>
|
|
57
|
+
const addPlaceholders = (strings, expressions) =>
|
|
58
58
|
strings.reduce((out, string, i) => {
|
|
59
59
|
// Add string part.
|
|
60
60
|
out.push(string);
|
|
@@ -124,10 +124,11 @@ const expandAttributes = (attributes, getExpressionResult) => attributes.reduce(
|
|
|
124
124
|
* Expand events.
|
|
125
125
|
* @param {object} attributes Attributes object.
|
|
126
126
|
* @param {EventsManager} eventsManager Events manager.
|
|
127
|
+
* @param {Function} getDataAttribute Function to get data attribute name with uid.
|
|
127
128
|
* @return {object} Attributes object.
|
|
128
129
|
* @private
|
|
129
130
|
*/
|
|
130
|
-
const expandEvents = (attributes, eventsManager) => {
|
|
131
|
+
const expandEvents = (attributes, eventsManager, getDataAttribute) => {
|
|
131
132
|
const out = {};
|
|
132
133
|
Object.keys(attributes).forEach(key => {
|
|
133
134
|
// Check if key is an event listener.
|
|
@@ -139,7 +140,7 @@ const expandEvents = (attributes, eventsManager) => {
|
|
|
139
140
|
if (listener) {
|
|
140
141
|
const index = eventsManager.addListener(listener, type);
|
|
141
142
|
// Add event listener index.
|
|
142
|
-
out[
|
|
143
|
+
out[getDataAttribute(type)] = index;
|
|
143
144
|
}
|
|
144
145
|
} else {
|
|
145
146
|
// Add attribute.
|
|
@@ -279,7 +280,8 @@ const parseElements = (template, expressions, elements) => {
|
|
|
279
280
|
// Expand attributes and events.
|
|
280
281
|
const attributes = expandEvents(
|
|
281
282
|
expandAttributes(parsedAttributes, value => getExpressionResult(value, this)),
|
|
282
|
-
this.eventsManager
|
|
283
|
+
this.eventsManager,
|
|
284
|
+
type => Component.ATTRIBUTE_EVENT(type, this.uid)
|
|
283
285
|
);
|
|
284
286
|
// Extend template attributes with `options.attributes`.
|
|
285
287
|
if (isRoot && this.attributes) {
|
|
@@ -333,7 +335,8 @@ const parsePartialElements = (template, expressions) => {
|
|
|
333
335
|
const getAttributes = function() {
|
|
334
336
|
const attributes = expandEvents(
|
|
335
337
|
expandAttributes(parsedAttributes, value => getExpressionResult(value, this)),
|
|
336
|
-
this.eventsManager
|
|
338
|
+
this.eventsManager,
|
|
339
|
+
type => Component.ATTRIBUTE_EVENT(type, this.uid)
|
|
337
340
|
);
|
|
338
341
|
|
|
339
342
|
return attributes;
|
|
@@ -478,7 +481,7 @@ class Component extends View {
|
|
|
478
481
|
const events = {};
|
|
479
482
|
// Create events object.
|
|
480
483
|
this.eventsManager.types.forEach(type => {
|
|
481
|
-
const dataAttribute = Component.ATTRIBUTE_EVENT(type);
|
|
484
|
+
const dataAttribute = Component.ATTRIBUTE_EVENT(type, this.uid);
|
|
482
485
|
// Create a listener function that gets the listener index from the data attribute and calls the listener.
|
|
483
486
|
const listener = function(event, component, matched) {
|
|
484
487
|
// Get the listener index from the data attribute.
|
|
@@ -575,7 +578,7 @@ class Component extends View {
|
|
|
575
578
|
this.el = this.children[0].el;
|
|
576
579
|
} else {
|
|
577
580
|
// Search for every element in template using getSelector
|
|
578
|
-
this.template.elements.forEach((element, index) => {
|
|
581
|
+
this.template.elements.forEach((element, index) => {
|
|
579
582
|
if (index === 0) {
|
|
580
583
|
element.hydrate(parent);
|
|
581
584
|
if (this.el) element.ref = this.el;
|
|
@@ -1166,7 +1169,7 @@ class Component extends View {
|
|
|
1166
1169
|
* Attributes used to identify elements and events.
|
|
1167
1170
|
*/
|
|
1168
1171
|
Component.ATTRIBUTE_ELEMENT = 'data-rasti-el';
|
|
1169
|
-
Component.ATTRIBUTE_EVENT = (type) => `data-rasti-on-${type}`;
|
|
1172
|
+
Component.ATTRIBUTE_EVENT = (type, uid) => `data-rasti-on-${type}-${uid}`;
|
|
1170
1173
|
|
|
1171
1174
|
/*
|
|
1172
1175
|
* Dataset attribute used to identify elements.
|
package/lib/View.cjs
CHANGED
|
@@ -170,7 +170,7 @@ class View extends Emitter {
|
|
|
170
170
|
* You shouldn't call this method directly. It's called from the constructor.
|
|
171
171
|
* You may override it if you want to use a different logic or to
|
|
172
172
|
* postpone element creation.
|
|
173
|
-
*/
|
|
173
|
+
*/
|
|
174
174
|
ensureElement() {
|
|
175
175
|
// Element is already present.
|
|
176
176
|
if (this.el) {
|
package/package.json
CHANGED
package/src/Component.js
CHANGED
|
@@ -49,7 +49,7 @@ const isElement = (el) => !!el.dataset[Component.DATASET_ELEMENT];
|
|
|
49
49
|
* @return {string} String with placeholders.
|
|
50
50
|
* @private
|
|
51
51
|
*/
|
|
52
|
-
const addPlaceholders = (strings, expressions) =>
|
|
52
|
+
const addPlaceholders = (strings, expressions) =>
|
|
53
53
|
strings.reduce((out, string, i) => {
|
|
54
54
|
// Add string part.
|
|
55
55
|
out.push(string);
|
|
@@ -119,10 +119,11 @@ const expandAttributes = (attributes, getExpressionResult) => attributes.reduce(
|
|
|
119
119
|
* Expand events.
|
|
120
120
|
* @param {object} attributes Attributes object.
|
|
121
121
|
* @param {EventsManager} eventsManager Events manager.
|
|
122
|
+
* @param {Function} getDataAttribute Function to get data attribute name with uid.
|
|
122
123
|
* @return {object} Attributes object.
|
|
123
124
|
* @private
|
|
124
125
|
*/
|
|
125
|
-
const expandEvents = (attributes, eventsManager) => {
|
|
126
|
+
const expandEvents = (attributes, eventsManager, getDataAttribute) => {
|
|
126
127
|
const out = {};
|
|
127
128
|
Object.keys(attributes).forEach(key => {
|
|
128
129
|
// Check if key is an event listener.
|
|
@@ -134,7 +135,7 @@ const expandEvents = (attributes, eventsManager) => {
|
|
|
134
135
|
if (listener) {
|
|
135
136
|
const index = eventsManager.addListener(listener, type);
|
|
136
137
|
// Add event listener index.
|
|
137
|
-
out[
|
|
138
|
+
out[getDataAttribute(type)] = index;
|
|
138
139
|
}
|
|
139
140
|
} else {
|
|
140
141
|
// Add attribute.
|
|
@@ -274,7 +275,8 @@ const parseElements = (template, expressions, elements) => {
|
|
|
274
275
|
// Expand attributes and events.
|
|
275
276
|
const attributes = expandEvents(
|
|
276
277
|
expandAttributes(parsedAttributes, value => getExpressionResult(value, this)),
|
|
277
|
-
this.eventsManager
|
|
278
|
+
this.eventsManager,
|
|
279
|
+
type => Component.ATTRIBUTE_EVENT(type, this.uid)
|
|
278
280
|
);
|
|
279
281
|
// Extend template attributes with `options.attributes`.
|
|
280
282
|
if (isRoot && this.attributes) {
|
|
@@ -328,7 +330,8 @@ const parsePartialElements = (template, expressions) => {
|
|
|
328
330
|
const getAttributes = function() {
|
|
329
331
|
const attributes = expandEvents(
|
|
330
332
|
expandAttributes(parsedAttributes, value => getExpressionResult(value, this)),
|
|
331
|
-
this.eventsManager
|
|
333
|
+
this.eventsManager,
|
|
334
|
+
type => Component.ATTRIBUTE_EVENT(type, this.uid)
|
|
332
335
|
);
|
|
333
336
|
|
|
334
337
|
return attributes;
|
|
@@ -473,7 +476,7 @@ class Component extends View {
|
|
|
473
476
|
const events = {};
|
|
474
477
|
// Create events object.
|
|
475
478
|
this.eventsManager.types.forEach(type => {
|
|
476
|
-
const dataAttribute = Component.ATTRIBUTE_EVENT(type);
|
|
479
|
+
const dataAttribute = Component.ATTRIBUTE_EVENT(type, this.uid);
|
|
477
480
|
// Create a listener function that gets the listener index from the data attribute and calls the listener.
|
|
478
481
|
const listener = function(event, component, matched) {
|
|
479
482
|
// Get the listener index from the data attribute.
|
|
@@ -570,7 +573,7 @@ class Component extends View {
|
|
|
570
573
|
this.el = this.children[0].el;
|
|
571
574
|
} else {
|
|
572
575
|
// Search for every element in template using getSelector
|
|
573
|
-
this.template.elements.forEach((element, index) => {
|
|
576
|
+
this.template.elements.forEach((element, index) => {
|
|
574
577
|
if (index === 0) {
|
|
575
578
|
element.hydrate(parent);
|
|
576
579
|
if (this.el) element.ref = this.el;
|
|
@@ -1161,7 +1164,7 @@ class Component extends View {
|
|
|
1161
1164
|
* Attributes used to identify elements and events.
|
|
1162
1165
|
*/
|
|
1163
1166
|
Component.ATTRIBUTE_ELEMENT = 'data-rasti-el';
|
|
1164
|
-
Component.ATTRIBUTE_EVENT = (type) => `data-rasti-on-${type}`;
|
|
1167
|
+
Component.ATTRIBUTE_EVENT = (type, uid) => `data-rasti-on-${type}-${uid}`;
|
|
1165
1168
|
|
|
1166
1169
|
/*
|
|
1167
1170
|
* Dataset attribute used to identify elements.
|
package/src/View.js
CHANGED
|
@@ -168,7 +168,7 @@ export default class View extends Emitter {
|
|
|
168
168
|
* You shouldn't call this method directly. It's called from the constructor.
|
|
169
169
|
* You may override it if you want to use a different logic or to
|
|
170
170
|
* postpone element creation.
|
|
171
|
-
*/
|
|
171
|
+
*/
|
|
172
172
|
ensureElement() {
|
|
173
173
|
// Element is already present.
|
|
174
174
|
if (this.el) {
|
package/src/index.js
CHANGED