@elenajs/core 1.0.0-alpha.2 → 1.0.0-rc.10
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/LICENSE +21 -0
- package/README.md +60 -0
- package/dist/bundle.js +6 -2
- package/dist/common/props.d.ts.map +1 -1
- package/dist/common/render.d.ts.map +1 -1
- package/dist/common/utils.d.ts +4 -7
- package/dist/common/utils.d.ts.map +1 -1
- package/dist/elena.d.ts +1 -2
- package/dist/elena.d.ts.map +1 -1
- package/dist/elena.js +6 -2
- package/dist/props.js +1 -2
- package/dist/render.js +1 -2
- package/dist/utils.js +1 -2
- package/package.json +17 -14
- package/src/common/props.js +131 -0
- package/src/common/render.js +236 -0
- package/src/common/utils.js +128 -0
- package/src/elena.js +552 -0
- package/dist/bundle.js.map +0 -1
- package/dist/common/events.d.ts +0 -8
- package/dist/common/events.d.ts.map +0 -1
- package/dist/elena.js.map +0 -1
- package/dist/events.js +0 -2
- package/dist/events.js.map +0 -1
- package/dist/props.js.map +0 -1
- package/dist/render.js.map +0 -1
- package/dist/utils.js.map +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Ariel Salminen https://arielsalminen.com
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<picture>
|
|
3
|
+
<source media="(prefers-color-scheme: dark)" srcset="https://elenajs.com/img/elena-dark.png" alt="Elena" width="558" height="220">
|
|
4
|
+
</source>
|
|
5
|
+
<source media="(prefers-color-scheme: light)" srcset="https://elenajs.com/img/elena-light.png" alt="Elena" width="558" height="220">
|
|
6
|
+
</source>
|
|
7
|
+
<img src="https://elenajs.com/img/elena-light.png" alt="Elena" width="558" height="220">
|
|
8
|
+
</picture>
|
|
9
|
+
|
|
10
|
+
### Simple, tiny library for building Progressive Web Components.
|
|
11
|
+
|
|
12
|
+
<br/>
|
|
13
|
+
|
|
14
|
+
<a href="https://arielsalminen.com"><img src="https://img.shields.io/badge/creator-@arielle-F95B1F" alt="Creator @arielle"/></a>
|
|
15
|
+
<a href="https://www.npmjs.com/org/elenajs"><img src="https://img.shields.io/npm/v/@elenajs/core.svg" alt="Latest version on npm" /></a>
|
|
16
|
+
<a href="https://github.com/getelena/elena/blob/main/LICENSE"><img src="https://img.shields.io/badge/license-MIT-yellow.svg" alt="Elena is released under the MIT license." /></a>
|
|
17
|
+
<a href="https://github.com/getelena/elena/actions/workflows/tests.yml"><img src="https://img.shields.io/badge/coverage-100%25-green" alt="Coverage 100%" /></a>
|
|
18
|
+
<a href="https://www.npmjs.com/package/@elenajs/core"><img src="https://img.shields.io/npm/dt/@elenajs/core.svg" alt="Total Downloads"></a>
|
|
19
|
+
<a href="https://github.com/getelena/elena/actions/workflows/tests.yml"><img src="https://github.com/getelena/elena/actions/workflows/tests.yml/badge.svg" alt="Tests status" /></a>
|
|
20
|
+
|
|
21
|
+
</div>
|
|
22
|
+
|
|
23
|
+
<br/>
|
|
24
|
+
|
|
25
|
+
<p align="center">Elena is a simple, tiny library (2.6kB) for building <a href="https://elenajs.com/">Progressive Web Components</a>. Unlike most web component libraries, Elena doesn’t force JavaScript for everything. You can load HTML and CSS first, then use JavaScript to progressively add interactivity.</p>
|
|
26
|
+
|
|
27
|
+
## Documentation
|
|
28
|
+
|
|
29
|
+
See the full documentation for Elena at [elenajs.com](https://elenajs.com).
|
|
30
|
+
|
|
31
|
+
```sh
|
|
32
|
+
npm install @elenajs/core
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
## Packages
|
|
36
|
+
|
|
37
|
+
Elena is a monorepo containing several packages published to npm under the `@elenajs` scope. These are the main packages intended for development:
|
|
38
|
+
|
|
39
|
+
| Package | Description | Version | Stability |
|
|
40
|
+
| --- | --- | --- | --- |
|
|
41
|
+
| [`@elenajs/core`](https://github.com/getelena/elena/tree/main/packages/core) | Elena core runtime library. | [](https://www.npmjs.com/package/@elenajs/core) |  |
|
|
42
|
+
| [`@elenajs/components`](https://github.com/getelena/elena/tree/main/packages/components) | Elena demo web components. | [](https://www.npmjs.com/package/@elenajs/components) |  |
|
|
43
|
+
| [`@elenajs/bundler`](https://github.com/getelena/elena/tree/main/packages/bundler) | Elena bundler for component libraries. | [](https://www.npmjs.com/package/@elenajs/bundler) |  |
|
|
44
|
+
| [`@elenajs/cli`](https://github.com/getelena/elena/tree/main/packages/cli) | Elena CLI for scaffolding web components. | [](https://www.npmjs.com/package/@elenajs/cli) |  |
|
|
45
|
+
| [`@elenajs/ssr`](https://github.com/getelena/elena/tree/main/packages/ssr) | Elena server-side rendering tools. | [](https://www.npmjs.com/package/@elenajs/ssr) |  |
|
|
46
|
+
| [`@elenajs/mcp`](https://github.com/getelena/elena/tree/main/packages/ssr) | Elena MCP server. | [](https://www.npmjs.com/package/@elenajs/mcp) |  |
|
|
47
|
+
|
|
48
|
+
<!-- https://github.com/mkenney/software-guides/blob/master/STABILITY-BADGES.md -->
|
|
49
|
+
|
|
50
|
+
## Development
|
|
51
|
+
|
|
52
|
+
For more details about pull requests, commit conventions and code style, please see [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
53
|
+
|
|
54
|
+
## License
|
|
55
|
+
|
|
56
|
+
MIT
|
|
57
|
+
|
|
58
|
+
## Copyright
|
|
59
|
+
|
|
60
|
+
Copyright © 2026 [Ariel Salminen](https://arielsalminen.com)
|
package/dist/bundle.js
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @elenajs/core v1.0.0-rc.10
|
|
3
|
+
* (c) 2025-present Ariel Salminen and Elena contributors
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
const t="░█ [ELENA]: ",s=Array.isArray,i=s=>console.warn(t+s),e={"&":"&","<":"<",">":">",'"':""","'":"'"};function n(t){return s(t)?t.map(o).join(""):o(t)}function o(t){return t?.t?String(t):String(t??"").replace(/[&<>"']/g,t=>e[t])}function r(t,...s){let i;return{t:!0,strings:t,values:s,toString:()=>(null==i&&(i=t.reduce((t,i,e)=>t+i+n(s[e]),"")),i)}}function h(t){return{t:!0,toString:()=>t??""}}const c={t:!0,toString:()=>""},u=t=>s(t)?t.some(t=>t?.t):t?.t,f=t=>s(t)?t.join(""):String(t??"");function l(t){return t.replace(/(>)\n\s*|\n\s*(<)/g,"$1$2").replace(/\n\s*/g," ").replace(/>\s+</g,"><")}function a(t,s,e){if(s="boolean"===t&&"boolean"!=typeof s?null!==s:s,!e)return s;if("toAttribute"===e)switch(t){case"object":case"array":return s&&JSON.stringify(s);case"boolean":return s?"":null;default:return""===s?null:s}else switch(t){case"object":case"array":if(!s)return s;try{return JSON.parse(s)}catch{return i("Invalid JSON: "+s),null}case"number":return null!==s?+s:s;default:return s??""}}function d(t,s,e){t?null===e?t.removeAttribute(s):t.setAttribute(s,e):i("Cannot sync attrs.")}const p=new WeakMap,g="e"+(1e5*Math.random()|0),b=()=>document.createElement("template"),y=t=>document.createTreeWalker(t,128);function m(t,i,e){return!function(t,i,e){if(t.i!==i||!t.o)return!1;for(let i=0;i<e.length;i++){const n=e[i],o=s(n)?f(n):n;if(o!==t.h[i]){if(u(n)||!t.o[i])return!1;t.h[i]=o,t.o[i].textContent=f(n)}}return!0}(t,i,e)&&(function(t,i,e){let o=p.get(i);if(!o){const t=i.map(l);o={u:t,l:e.length>0?S(t,e.length):null},p.set(i,o)}if(o.l)t.o=function(t,s,i){const e=s.content.cloneNode(!0),o=y(e),r=Array(i.length),h=[];let c;for(;c=o.nextNode();)c.data===g&&h.push(c);for(let t=0;t<h.length;t++){const s=i[t];if(u(s)){const i=b();i.innerHTML=n(s),h[t].parentNode.replaceChild(i.content,h[t])}else{const i=document.createTextNode(f(s));h[t].parentNode.replaceChild(i,h[t]),r[t]=i}}return t.replaceChildren(e),r}(t,o.l,e);else{const s=e.map(n),i=o.u.reduce((t,i,e)=>t+i+(s[e]??""),"").replace(/>\s+</g,"><").trim(),r=b();r.innerHTML=i,_(t,r.content.childNodes),t.o=null}t.i=i,t.h=e.map(t=>s(t)?f(t):t)}(t,i,e),!0)}function S(t,s){const i=`\x3c!--${g}--\x3e`,e=t.reduce((t,e,n)=>t+e+(n<s?i:""),"").trim(),n=b();n.innerHTML=e;const o=y(n.content);let r=0;for(;o.nextNode();)o.currentNode.data===g&&r++;return r===s?n:null}function _(t,s){const i=Array.from(t.childNodes),e=Array.from(s),n=Math.max(i.length,e.length);for(let s=0;s<n;s++){const n=i[s],o=e[s];n?o?n.nodeType!==o.nodeType||1===n.nodeType&&n.tagName!==o.tagName?t.replaceChild(o,n):3===n.nodeType?n.textContent!==o.textContent&&(n.textContent=o.textContent):1===n.nodeType&&(w(n,o),_(n,o.childNodes)):t.removeChild(n):t.appendChild(o)}}function w(t,s){for(let i=t.attributes.length-1;i>=0;i--){const{name:e}=t.attributes[i];s.hasAttribute(e)||t.removeAttribute(e)}for(let i=0;i<s.attributes.length;i++){const{name:e,value:n}=s.attributes[i];t.getAttribute(e)!==n&&t.setAttribute(e,n)}}const v=new WeakSet,x=(t,s)=>Object.prototype.hasOwnProperty.call(t,s);function C(s){return class extends s{element=null;attributeChangedCallback(t,s,e){super.attributeChangedCallback?.(t,s,e),"text"!==t?(this.p=!0,function(t,s,e,n){if(e!==n){const e=typeof t[s];"undefined"===e&&i(`Prop "${s}" has no default.`);const o=a(e,n,"toProp");t[s]=o}}(this,t,s,e),this.p=!1,this.m&&s!==e&&!this.S&&this._()):this.text=e??""}static get observedAttributes(){if(this.v)return this.v;const t=(this.props||[]).map(t=>"string"==typeof t?t:t.name);return this.v=[...t,"text"],this.v}connectedCallback(){super.connectedCallback?.(),this.C(),this.A(),this.m||void 0!==this.k||(this.text=this.textContent.trim()),this.P(),this.willUpdate(),this.M(),this.N(),this.O(),this.m||(this.m=!0,this.setAttribute("hydrated",""),this.firstUpdated()),this.updated()}C(){const t=this.constructor;if(v.has(t))return;const s=new Set,e=[];if(t.props){for(const i of t.props)"string"==typeof i?e.push(i):(e.push(i.name),!1===i.reflect&&s.add(i.name));e.includes("text")&&i('"text" is reserved.'),function(t,s,i){for(const e of s){const s=!i||!i.has(e);Object.defineProperty(t,e,{configurable:!0,enumerable:!0,get(){return this.j?.get(e)},set(t){if(this.j||(this.j=new Map),t!==this.j.get(e)&&(this.j.set(e,t),this.isConnected))if(s){if(!this.p){const s=a(typeof t,t,"toAttribute");d(this,e,s)}}else this.m&&!this.S&&this._()}})}}(t.prototype,e,s)}if(t.U=e,t.$=s,t.q=t.events||null,t.q)for(const s of t.q)x(t.prototype,s)||(t.prototype[s]=function(...t){return this.element[s](...t)});var n;t.J=(n=t.element)?t=>t.querySelector(n):t=>t.firstElementChild,v.add(t)}A(){this.p=!0;for(const t of this.constructor.U)if(x(this,t)){const s=this[t];delete this[t],this[t]=s}this.p=!1}get R(){return this.W??this.shadowRoot??this}P(){const t=this.constructor;if(!t.shadow)return;this.W||this.shadowRoot||(this.W=this.attachShadow({mode:t.shadow}));const s=this.W??this.shadowRoot;if(t.styles){if(!t.D){const s=[t.styles].flat();t.D=s.map(t=>{if("string"==typeof t){const s=new CSSStyleSheet;return s.replaceSync(t),s}return t})}s.adoptedStyleSheets=t.D}}M(){const t=this.constructor,s=this.R,e=this.render();if(e&&e.strings&&m(s,e.strings,e.values)){const i=this.element;if(this.element=t.J(s),this.F&&i&&this.element!==i){const s=t.q;for(const t of s)i.removeEventListener(t,this),this.element.addEventListener(t,this)}}this.element||(this.element=t.J(s),this.element||(t.element&&i("Element not found."),this.element=s.firstElementChild))}N(){if(this.j){const t=this.constructor.$;for(const[s,i]of this.j){if(t.has(s))continue;const e=a(typeof i,i,"toAttribute");(null!==e||this.hasAttribute(s))&&d(this,s,e)}}}O(){const t=this.constructor.q;if(!this.F&&t?.length)if(this.element){this.F=!0;for(const s of t)this.element.addEventListener(s,this)}else i("Cannot add events.")}render(){}willUpdate(){}firstUpdated(){}updated(){}adoptedCallback(){super.adoptedCallback?.()}disconnectedCallback(){if(super.disconnectedCallback?.(),this.F){this.F=!1;for(const t of this.constructor.q)this.element?.removeEventListener(t,this)}}handleEvent(t){this.constructor.q?.includes(t.type)&&(t.bubbles&&(t.composed||this.R===this)||this.dispatchEvent(new Event(t.type,{bubbles:t.bubbles})))}get text(){return this.k??""}set text(t){const s=this.k;this.k=t,this.m&&s!==t&&!this.S&&this._()}static define(){const t=this.tagName;t?function(t,s){const i=globalThis.customElements;i?.get(t)||i?.define(t,s)}(t,this):i("define() without a tagName.")}_(){this.S||this.I||(this.I=!0,this.L=new Promise(t=>{this.T=t}),queueMicrotask(()=>{try{this.B()}catch(s){console.error(t,s)}}))}B(){this.I=!1;const t=this.T;this.T=null;try{try{this.willUpdate(),this.S=!0,this.M()}finally{this.S=!1}this.updated()}finally{this.L=null,t()}}get updateComplete(){return this.L||Promise.resolve()}requestUpdate(){this.m&&!this.S&&this._()}}}export{C as Elena,r as html,c as nothing,h as unsafeHTML};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../src/common/props.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"props.d.ts","sourceRoot":"","sources":["../../src/common/props.js"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,mCAJW,MAAM,SACN,GAAG,cACH,aAAa,GAAG,QAAQ,OAqClC;AAED;;;;;;GAMG;AACH,uCAJW,OAAO,QACP,MAAM,SACN,MAAM,GAAG,IAAI,QAYvB;AAED;;;;;;;;GAQG;AACH,qDAHW,MAAM,EAAE,cACR,GAAG,CAAC,MAAM,CAAC,QAsCrB;AAED;;;;;;;;GAQG;AACH,kCALW,MAAM,QACN,MAAM,YACN,GAAG,YACH,GAAG,QAWb"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/common/render.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"render.d.ts","sourceRoot":"","sources":["../../src/common/render.js"],"names":[],"mappings":"AAWA;;;;;;;;;GASG;AACH,wCALW,WAAW,WACX,oBAAoB,kBAElB,OAAO,CAQnB"}
|
package/dist/common/utils.d.ts
CHANGED
|
@@ -5,13 +5,7 @@
|
|
|
5
5
|
* @param {Function} Element
|
|
6
6
|
*/
|
|
7
7
|
export function defineElement(tagName: string, Element: Function): void;
|
|
8
|
-
|
|
9
|
-
* Escape a string for safe insertion into HTML.
|
|
10
|
-
*
|
|
11
|
-
* @param {string} str
|
|
12
|
-
* @returns {string}
|
|
13
|
-
*/
|
|
14
|
-
export function escapeHtml(str: string): string;
|
|
8
|
+
export function escapeHtml(str: any): string;
|
|
15
9
|
/**
|
|
16
10
|
* Resolve an interpolated template value to its
|
|
17
11
|
* HTML string representation.
|
|
@@ -51,6 +45,7 @@ export function unsafeHTML(str: string): {
|
|
|
51
45
|
* @returns {string}
|
|
52
46
|
*/
|
|
53
47
|
export function collapseWhitespace(string: string): string;
|
|
48
|
+
export function warn(msg: string): void;
|
|
54
49
|
/**
|
|
55
50
|
* A placeholder you can return from a conditional expression
|
|
56
51
|
* inside a template to render nothing.
|
|
@@ -63,4 +58,6 @@ export const nothing: {
|
|
|
63
58
|
};
|
|
64
59
|
export function isRaw(value: any): boolean;
|
|
65
60
|
export function toPlainText(value: any): string;
|
|
61
|
+
export const prefix: "\u2591\u2588 [ELENA]: ";
|
|
62
|
+
export const isArray: (arg: any) => arg is any[];
|
|
66
63
|
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/common/utils.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/common/utils.js"],"names":[],"mappings":"AAUA;;;;;GAKG;AACH,uCAHW,MAAM,2BAMhB;AASD,6CAEC;AAED;;;;;;GAMG;AACH,oCAHW,GAAC,GACC,MAAM,CAOlB;AAaD;;;;;;;GAOG;AACH,8BAJW,oBAAoB,aACjB,GAAC,EAAA,GACF;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,OAAO,EAAE,oBAAoB,CAAC;IAAC,MAAM,QAAQ;IAAC,QAAQ,IAAI,MAAM,CAAA;CAAE,CAiB7F;AAED;;;;;GAKG;AACH,gCAHW,MAAM,GACJ;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,IAAI,MAAM,CAAA;CAAE,CAI/C;AA0BD;;;;;GAKG;AACH,2CAHW,MAAM,GACJ,MAAM,CAOlB;AAxHM,0BAHI,MAAM,QAGoC;AAqFrD;;;;;GAKG;AACH,sBAFU;IAAE,KAAK,EAAE,IAAI,CAAC;IAAC,QAAQ,IAAI,MAAM,CAAA;CAAE,CAEc;AAQpD,6BAHI,GAAC,GACC,OAAO,CAE2E;AAQxF,mCAHI,GAAC,GACC,MAAM,CAEwE;AAlH3F,qBAAe,wBAAc,CAAC;AAC9B,iDAA8B"}
|
package/dist/elena.d.ts
CHANGED
|
@@ -37,6 +37,5 @@ export type ElenaElementConstructor = (new (...args: any[]) => HTMLElement & Ele
|
|
|
37
37
|
import { html } from "./common/utils.js";
|
|
38
38
|
import { unsafeHTML } from "./common/utils.js";
|
|
39
39
|
import { nothing } from "./common/utils.js";
|
|
40
|
-
|
|
41
|
-
export { html, unsafeHTML, nothing, ElenaEvent };
|
|
40
|
+
export { html, unsafeHTML, nothing };
|
|
42
41
|
//# sourceMappingURL=elena.d.ts.map
|
package/dist/elena.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"elena.d.ts","sourceRoot":"","sources":["../src/elena.js"],"names":[],"mappings":"AAkEA;;;;;;;;;GASG;AACH,kCAHW,gBAAgB,GACd,uBAAuB,
|
|
1
|
+
{"version":3,"file":"elena.d.ts","sourceRoot":"","sources":["../src/elena.js"],"names":[],"mappings":"AAkEA;;;;;;;;;GASG;AACH,kCAHW,gBAAgB,GACd,uBAAuB,CA6dnC;+BAjgBY,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,WAAW;mCAInC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAAC;IAAC,MAAM,IAAI,IAAI,CAAC;IAAC,UAAU,IAAI,IAAI,CAAC;IAAC,YAAY,IAAI,IAAI,CAAC;IAAC,OAAO,IAAI,IAAI,CAAC;IAAC,iBAAiB,IAAI,IAAI,CAAC;IAAC,oBAAoB,IAAI,IAAI,CAAA;CAAE;8BAIjL;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE;sCAInC,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,WAAW,GAAG,oBAAoB,CAAC,GAAG;IACvE,MAAM,IAAI,IAAI,CAAC;IACnB,QAAY,CAAC,kBAAkB,EAAE,MAAM,EAAE,CAAC;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,MAAM,GAAG,eAAe,CAAC,EAAE,CAAC;IACrC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC3B,MAAM,CAAC,EAAE,aAAa,GAAG,MAAM,GAAG,CAAC,aAAa,GAAG,MAAM,CAAC,EAAE,CAAC;CAC9D;qBA5CmE,mBAAmB;2BAAnB,mBAAmB;wBAAnB,mBAAmB"}
|
package/dist/elena.js
CHANGED
|
@@ -1,2 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @elenajs/core v1.0.0-rc.10
|
|
3
|
+
* (c) 2025-present Ariel Salminen and Elena contributors
|
|
4
|
+
* @license MIT
|
|
5
|
+
*/
|
|
6
|
+
import{getProps as t,setProps as e,getPropValue as s,syncAttribute as i}from"./props.js";import{warn as n,defineElement as r,prefix as o}from"./utils.js";export{html,nothing,unsafeHTML}from"./utils.js";import{renderTemplate as h}from"./render.js";const a=new WeakSet,d=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);function l(l){return class extends l{element=null;attributeChangedCallback(e,s,i){super.attributeChangedCallback?.(e,s,i),"text"!==e?(this._syncing=!0,t(this,e,s,i),this._syncing=!1,this._hydrated&&s!==i&&!this._isRendering&&this._safeRender()):this.text=i??""}static get observedAttributes(){if(this._observedAttrs)return this._observedAttrs;const t=(this.props||[]).map(t=>"string"==typeof t?t:t.name);return this._observedAttrs=[...t,"text"],this._observedAttrs}connectedCallback(){super.connectedCallback?.(),this._setupStaticProps(),this._captureClassFieldDefaults(),this._hydrated||void 0!==this._text||(this.text=this.textContent.trim()),this._attachShadow(),this.willUpdate(),this._applyRender(),this._syncProps(),this._delegateEvents(),this._hydrated||(this._hydrated=!0,this.setAttribute("hydrated",""),this.firstUpdated()),this.updated()}_setupStaticProps(){const t=this.constructor;if(a.has(t))return;const s=new Set,i=[];if(t.props){for(const e of t.props)"string"==typeof e?i.push(e):(i.push(e.name),!1===e.reflect&&s.add(e.name));i.includes("text")&&n('"text" is reserved.'),e(t.prototype,i,s)}if(t._propNames=i,t._noReflect=s,t._elenaEvents=t.events||null,t._elenaEvents)for(const e of t._elenaEvents)d(t.prototype,e)||(t.prototype[e]=function(...t){return this.element[e](...t)});var r;t._resolver=(r=t.element)?t=>t.querySelector(r):t=>t.firstElementChild,a.add(t)}_captureClassFieldDefaults(){this._syncing=!0;for(const t of this.constructor._propNames)if(d(this,t)){const e=this[t];delete this[t],this[t]=e}this._syncing=!1}get _renderRoot(){return this._shadow??this.shadowRoot??this}_attachShadow(){const t=this.constructor;if(!t.shadow)return;this._shadow||this.shadowRoot||(this._shadow=this.attachShadow({mode:t.shadow}));const e=this._shadow??this.shadowRoot;if(t.styles){if(!t._adoptedSheets){const e=[t.styles].flat();t._adoptedSheets=e.map(t=>{if("string"==typeof t){const e=new CSSStyleSheet;return e.replaceSync(t),e}return t})}e.adoptedStyleSheets=t._adoptedSheets}}_applyRender(){const t=this.constructor,e=this._renderRoot,s=this.render();if(s&&s.strings&&h(e,s.strings,s.values)){const s=this.element;if(this.element=t._resolver(e),this._events&&s&&this.element!==s){const e=t._elenaEvents;for(const t of e)s.removeEventListener(t,this),this.element.addEventListener(t,this)}}this.element||(this.element=t._resolver(e),this.element||(t.element&&n("Element not found."),this.element=e.firstElementChild))}_syncProps(){if(this._props){const t=this.constructor._noReflect;for(const[e,n]of this._props){if(t.has(e))continue;const r=s(typeof n,n,"toAttribute");(null!==r||this.hasAttribute(e))&&i(this,e,r)}}}_delegateEvents(){const t=this.constructor._elenaEvents;if(!this._events&&t?.length)if(this.element){this._events=!0;for(const e of t)this.element.addEventListener(e,this)}else n("Cannot add events.")}render(){}willUpdate(){}firstUpdated(){}updated(){}adoptedCallback(){super.adoptedCallback?.()}disconnectedCallback(){if(super.disconnectedCallback?.(),this._events){this._events=!1;for(const t of this.constructor._elenaEvents)this.element?.removeEventListener(t,this)}}handleEvent(t){this.constructor._elenaEvents?.includes(t.type)&&(t.bubbles&&(t.composed||this._renderRoot===this)||this.dispatchEvent(new Event(t.type,{bubbles:t.bubbles})))}get text(){return this._text??""}set text(t){const e=this._text;this._text=t,this._hydrated&&e!==t&&!this._isRendering&&this._safeRender()}static define(){const t=this.tagName;t?r(t,this):n("define() without a tagName.")}_safeRender(){this._isRendering||this._renderPending||(this._renderPending=!0,this._updateComplete=new Promise(t=>{this._resolveUpdate=t}),queueMicrotask(()=>{try{this._performUpdate()}catch(t){console.error(o,t)}}))}_performUpdate(){this._renderPending=!1;const t=this._resolveUpdate;this._resolveUpdate=null;try{try{this.willUpdate(),this._isRendering=!0,this._applyRender()}finally{this._isRendering=!1}this.updated()}finally{this._updateComplete=null,t()}}get updateComplete(){return this._updateComplete||Promise.resolve()}requestUpdate(){this._hydrated&&!this._isRendering&&this._safeRender()}}}export{l as Elena};
|
package/dist/props.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
function
|
|
2
|
-
//# sourceMappingURL=props.js.map
|
|
1
|
+
import{warn as t}from"./utils.js";function e(e,n,r){if(n="boolean"===e&&"boolean"!=typeof n?null!==n:n,!r)return n;if("toAttribute"===r)switch(e){case"object":case"array":return n&&JSON.stringify(n);case"boolean":return n?"":null;default:return""===n?null:n}else switch(e){case"object":case"array":if(!n)return n;try{return JSON.parse(n)}catch{return t("Invalid JSON: "+n),null}case"number":return null!==n?+n:n;default:return n??""}}function n(e,n,r){e?null===r?e.removeAttribute(n):e.setAttribute(n,r):t("Cannot sync attrs.")}function r(t,r,s){for(const o of r){const r=!s||!s.has(o);Object.defineProperty(t,o,{configurable:!0,enumerable:!0,get(){return this._props?.get(o)},set(t){if(this._props||(this._props=new Map),t!==this._props.get(o)&&(this._props.set(o,t),this.isConnected))if(r){if(!this._syncing){const r=e(typeof t,t,"toAttribute");n(this,o,r)}}else this._hydrated&&!this._isRendering&&this._safeRender()}})}}function s(n,r,s,o){if(s!==o){const s=typeof n[r];"undefined"===s&&t(`Prop "${r}" has no default.`);const i=e(s,o,"toProp");n[r]=i}}export{e as getPropValue,s as getProps,r as setProps,n as syncAttribute};
|
package/dist/render.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
import{toPlainText as e,isRaw as
|
|
2
|
-
//# sourceMappingURL=render.js.map
|
|
1
|
+
import{isArray as t,toPlainText as e,isRaw as n,collapseWhitespace as r,resolveValue as o}from"./utils.js";const a=new WeakMap,l="e"+(1e5*Math.random()|0),c=()=>document.createElement("template"),s=t=>document.createTreeWalker(t,128);function i(i,p,d){return!function(r,o,a){if(r._templateStrings!==o||!r._templateParts)return!1;for(let o=0;o<a.length;o++){const l=a[o],c=t(l)?e(l):l;if(c!==r._templateValues[o]){if(n(l)||!r._templateParts[o])return!1;r._templateValues[o]=c,r._templateParts[o].textContent=e(l)}}return!0}(i,p,d)&&(function(i,p,d){let f=a.get(p);if(!f){const t=p.map(r);f={_strings:t,_template:d.length>0?u(t,d.length):null},a.set(p,f)}if(f._template)i._templateParts=function(t,r,a){const i=r.content.cloneNode(!0),u=s(i),m=Array(a.length),p=[];let d;for(;d=u.nextNode();)d.data===l&&p.push(d);for(let t=0;t<p.length;t++){const r=a[t];if(n(r)){const e=c();e.innerHTML=o(r),p[t].parentNode.replaceChild(e.content,p[t])}else{const n=document.createTextNode(e(r));p[t].parentNode.replaceChild(n,p[t]),m[t]=n}}return t.replaceChildren(i),m}(i,f._template,d);else{const t=d.map(o),e=f._strings.reduce((e,n,r)=>e+n+(t[r]??""),"").replace(/>\s+</g,"><").trim(),n=c();n.innerHTML=e,m(i,n.content.childNodes),i._templateParts=null}i._templateStrings=p,i._templateValues=d.map(n=>t(n)?e(n):n)}(i,p,d),!0)}function u(t,e){const n=`\x3c!--${l}--\x3e`,r=t.reduce((t,r,o)=>t+r+(o<e?n:""),"").trim(),o=c();o.innerHTML=r;const a=s(o.content);let i=0;for(;a.nextNode();)a.currentNode.data===l&&i++;return i===e?o:null}function m(t,e){const n=Array.from(t.childNodes),r=Array.from(e),o=Math.max(n.length,r.length);for(let e=0;e<o;e++){const o=n[e],a=r[e];o?a?o.nodeType!==a.nodeType||1===o.nodeType&&o.tagName!==a.tagName?t.replaceChild(a,o):3===o.nodeType?o.textContent!==a.textContent&&(o.textContent=a.textContent):1===o.nodeType&&(p(o,a),m(o,a.childNodes)):t.removeChild(o):t.appendChild(a)}}function p(t,e){for(let n=t.attributes.length-1;n>=0;n--){const{name:r}=t.attributes[n];e.hasAttribute(r)||t.removeAttribute(r)}for(let n=0;n<e.attributes.length;n++){const{name:r,value:o}=e.attributes[n];t.getAttribute(r)!==o&&t.setAttribute(r,o)}}export{i as renderTemplate};
|
package/dist/utils.js
CHANGED
|
@@ -1,2 +1 @@
|
|
|
1
|
-
|
|
2
|
-
//# sourceMappingURL=utils.js.map
|
|
1
|
+
const n="░█ [ELENA]: ",r=Array.isArray,t=r=>console.warn(n+r);function e(n,r){const t=globalThis.customElements;t?.get(n)||t?.define(n,r)}const o={"&":"&","<":"<",">":">",'"':""","'":"'"};function i(n){return String(n).replace(/[&<>"']/g,n=>o[n])}function c(n){return r(n)?n.map(u).join(""):u(n)}function u(n){return n?.__raw?String(n):i(n??"")}function a(n,...r){let t;return{__raw:!0,strings:n,values:r,toString:()=>(null==t&&(t=n.reduce((n,t,e)=>n+t+c(r[e]),"")),t)}}function s(n){return{__raw:!0,toString:()=>n??""}}const g={__raw:!0,toString:()=>""},l=n=>r(n)?n.some(n=>n?.__raw):n?.__raw,_=n=>r(n)?n.join(""):String(n??"");function f(n){return n.replace(/(>)\n\s*|\n\s*(<)/g,"$1$2").replace(/\n\s*/g," ").replace(/>\s+</g,"><")}export{f as collapseWhitespace,e as defineElement,i as escapeHtml,a as html,r as isArray,l as isRaw,g as nothing,n as prefix,c as resolveValue,_ as toPlainText,s as unsafeHTML,t as warn};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@elenajs/core",
|
|
3
|
-
"version": "1.0.0-
|
|
3
|
+
"version": "1.0.0-rc.10",
|
|
4
4
|
"description": "Elena is a simple, tiny library for building Progressive Web Components.",
|
|
5
5
|
"author": "Elena <hi@elenajs.com>",
|
|
6
6
|
"homepage": "https://elenajs.com/",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
"publishConfig": {
|
|
17
17
|
"access": "public"
|
|
18
18
|
},
|
|
19
|
+
"source": "./src/elena.js",
|
|
19
20
|
"main": "./dist/elena.js",
|
|
20
21
|
"types": "./dist/elena.d.ts",
|
|
21
22
|
"type": "module",
|
|
@@ -27,7 +28,8 @@
|
|
|
27
28
|
"./bundle": "./dist/bundle.js"
|
|
28
29
|
},
|
|
29
30
|
"files": [
|
|
30
|
-
"dist"
|
|
31
|
+
"dist",
|
|
32
|
+
"src"
|
|
31
33
|
],
|
|
32
34
|
"scripts": {
|
|
33
35
|
"prebuild": "npm run -s clean",
|
|
@@ -41,17 +43,18 @@
|
|
|
41
43
|
"clean": "rm -rf dist/"
|
|
42
44
|
},
|
|
43
45
|
"devDependencies": {
|
|
44
|
-
"@
|
|
45
|
-
"@
|
|
46
|
-
"@
|
|
47
|
-
"@
|
|
48
|
-
"@vitest/coverage-v8": "4.
|
|
49
|
-
"happy-dom": "20.8.
|
|
50
|
-
"lit": "
|
|
51
|
-
"rollup": "4.
|
|
46
|
+
"@playwright/test": "1.58.2",
|
|
47
|
+
"@rollup/plugin-terser": "1.0.0",
|
|
48
|
+
"@vitest/browser": "4.1.1",
|
|
49
|
+
"@vitest/browser-playwright": "4.1.1",
|
|
50
|
+
"@vitest/coverage-v8": "4.1.1",
|
|
51
|
+
"happy-dom": "20.8.9",
|
|
52
|
+
"lit": "3.3.2",
|
|
53
|
+
"rollup": "4.60.0",
|
|
52
54
|
"rollup-plugin-summary": "3.0.1",
|
|
53
|
-
"serve": "
|
|
54
|
-
"typescript": "
|
|
55
|
-
"vitest": "4.
|
|
56
|
-
}
|
|
55
|
+
"serve": "14.2.6",
|
|
56
|
+
"typescript": "6.0.2",
|
|
57
|
+
"vitest": "4.1.1"
|
|
58
|
+
},
|
|
59
|
+
"gitHead": "89275a58542d7a86e64b6052416a935c89d90d52"
|
|
57
60
|
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { warn } from "./utils.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Get the value of the Elena Element property.
|
|
5
|
+
*
|
|
6
|
+
* @param {string} type
|
|
7
|
+
* @param {any} value
|
|
8
|
+
* @param {"toAttribute" | "toProp"} [transform]
|
|
9
|
+
*/
|
|
10
|
+
export function getPropValue(type, value, transform) {
|
|
11
|
+
value = type === "boolean" && typeof value !== "boolean" ? value !== null : value;
|
|
12
|
+
|
|
13
|
+
if (!transform) {
|
|
14
|
+
return value;
|
|
15
|
+
} else if (transform === "toAttribute") {
|
|
16
|
+
switch (type) {
|
|
17
|
+
case "object":
|
|
18
|
+
case "array":
|
|
19
|
+
return value && JSON.stringify(value);
|
|
20
|
+
case "boolean":
|
|
21
|
+
return value ? "" : null;
|
|
22
|
+
// number, string:
|
|
23
|
+
default:
|
|
24
|
+
return value === "" ? null : value;
|
|
25
|
+
}
|
|
26
|
+
} else {
|
|
27
|
+
switch (type) {
|
|
28
|
+
case "object":
|
|
29
|
+
case "array":
|
|
30
|
+
if (!value) {
|
|
31
|
+
return value;
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
return JSON.parse(value);
|
|
35
|
+
} catch {
|
|
36
|
+
warn("Invalid JSON: " + value);
|
|
37
|
+
return null;
|
|
38
|
+
}
|
|
39
|
+
case "number":
|
|
40
|
+
return value !== null ? +value : value;
|
|
41
|
+
default:
|
|
42
|
+
return value ?? "";
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* Set or remove an attribute on an Elena Element.
|
|
49
|
+
*
|
|
50
|
+
* @param {Element} element - Target element
|
|
51
|
+
* @param {string} name - Attribute name
|
|
52
|
+
* @param {string | null} value - Attribute value, or null to remove
|
|
53
|
+
*/
|
|
54
|
+
export function syncAttribute(element, name, value) {
|
|
55
|
+
if (!element) {
|
|
56
|
+
warn("Cannot sync attrs.");
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (value === null) {
|
|
60
|
+
element.removeAttribute(name);
|
|
61
|
+
} else {
|
|
62
|
+
element.setAttribute(name, value);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Define prop getters/setters on the prototype once
|
|
68
|
+
* at class-creation time. Values are stored per-instance
|
|
69
|
+
* via a `_props` Map that is lazily created.
|
|
70
|
+
*
|
|
71
|
+
* @param {Function} proto - The class prototype
|
|
72
|
+
* @param {string[]} propNames - Prop names to define
|
|
73
|
+
* @param {Set<string>} [noReflect] - Props that should not reflect to attributes
|
|
74
|
+
*/
|
|
75
|
+
export function setProps(proto, propNames, noReflect) {
|
|
76
|
+
for (const prop of propNames) {
|
|
77
|
+
const reflects = !noReflect || !noReflect.has(prop);
|
|
78
|
+
Object.defineProperty(proto, prop, {
|
|
79
|
+
configurable: true,
|
|
80
|
+
enumerable: true,
|
|
81
|
+
get() {
|
|
82
|
+
return this._props?.get(prop);
|
|
83
|
+
},
|
|
84
|
+
set(value) {
|
|
85
|
+
if (!this._props) {
|
|
86
|
+
this._props = new Map();
|
|
87
|
+
}
|
|
88
|
+
if (value === this._props.get(prop)) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
this._props.set(prop, value);
|
|
93
|
+
if (!this.isConnected) {
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
if (reflects) {
|
|
98
|
+
// Skip reflection when called from attributeChangedCallback. The
|
|
99
|
+
// attribute is already at the new value, setting it again is redundant
|
|
100
|
+
// and would fire an extra attributeChangedCallback with identical values.
|
|
101
|
+
if (!this._syncing) {
|
|
102
|
+
const attrValue = getPropValue(typeof value, value, "toAttribute");
|
|
103
|
+
syncAttribute(this, prop, attrValue);
|
|
104
|
+
}
|
|
105
|
+
} else if (this._hydrated && !this._isRendering) {
|
|
106
|
+
this._safeRender();
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/**
|
|
114
|
+
* We need to update the internals of the Elena Element
|
|
115
|
+
* when props on the host element are changed.
|
|
116
|
+
*
|
|
117
|
+
* @param {object} context
|
|
118
|
+
* @param {string} name
|
|
119
|
+
* @param {any} oldValue
|
|
120
|
+
* @param {any} newValue
|
|
121
|
+
*/
|
|
122
|
+
export function getProps(context, name, oldValue, newValue) {
|
|
123
|
+
if (oldValue !== newValue) {
|
|
124
|
+
const type = typeof context[name];
|
|
125
|
+
if (type === "undefined") {
|
|
126
|
+
warn(`Prop "${name}" has no default.`);
|
|
127
|
+
}
|
|
128
|
+
const newAttr = getPropValue(type, newValue, "toProp");
|
|
129
|
+
context[name] = newAttr;
|
|
130
|
+
}
|
|
131
|
+
}
|