Compare commits

...

2 Commits

Author SHA1 Message Date
a65219759d Improved XXS
All checks were successful
Deploy Docs to Synology / deploy (push) Successful in 4s
2026-04-27 10:32:11 +02:00
25975eb89a Corrected docs 2026-04-27 10:31:58 +02:00
10 changed files with 32 additions and 22 deletions

View File

@@ -22,7 +22,7 @@ That extra development time and the cognitive load of "learning the framework" i
* 🛠️ **Build-Tool Agnostic:** Total freedom. Use it with **Vite, Webpack, or Rollup** for enterprise projects, or simply import it via a **`<script>` tag** for rapid prototyping. No tooling required. * 🛠️ **Build-Tool Agnostic:** Total freedom. Use it with **Vite, Webpack, or Rollup** for enterprise projects, or simply import it via a **`<script>` tag** for rapid prototyping. No tooling required.
* 🚀 **Vite-Powered DX:** First-class Vite support with **file-based routing** out of the box. The official `sigpro/vite` plugin automatically scans your `src/pages` directory and generates reactive routes—no manual route configuration needed. * 🚀 **Vite-Powered DX:** First-class Vite support with **file-based routing** out of the box. The official `sigpro/vite` plugin automatically scans your `src/pages` directory and generates reactive routes—no manual route configuration needed.
* 📈 **Zero-Scale Bloat:** Unlike other frameworks where the bundle grows exponentially, SigPro's footprint remains **flat and predictable**. You only pay for the code you write. * 📈 **Zero-Scale Bloat:** Unlike other frameworks where the bundle grows exponentially, SigPro's footprint remains **flat and predictable**. You only pay for the code you write.
* 💎 **Premium DX (Developer Experience):** Forget boilerplate imports. SigPro injects an elegant, functional syntax (`Div()`, `Button()`, `Span()`) directly into your scope for a **"Zero-Import"** workflow. * 💎 **Premium DX (Developer Experience):** Forget boilerplate imports. SigPro injects an elegant, functional syntax (`div()`, `button()`, `span()`) directly into your scope for a **"Zero-Import"** workflow.
* 📦 **Fully Loaded:** Built-in Hash Routing, native **`localStorage` persistence**, and automatic lifecycle management (cleanups) included in less than 2KB. * 📦 **Fully Loaded:** Built-in Hash Routing, native **`localStorage` persistence**, and automatic lifecycle management (cleanups) included in less than 2KB.
* 🌳 **Tree-Shakable:** Optimized for modern bundlers. Import only what you use, or load the full engine for rapid prototyping. * 🌳 **Tree-Shakable:** Optimized for modern bundlers. Import only what you use, or load the full engine for rapid prototyping.

8
dist/sigpro.esm.js vendored
View File

@@ -244,7 +244,8 @@ var cleanupNode = (node) => {
node.childNodes.forEach((n) => cleanupNode(n)); node.childNodes.forEach((n) => cleanupNode(n));
}; };
var DANGEROUS_PROTOCOL = /^\s*(javascript|data|vbscript):/i; var DANGEROUS_PROTOCOL = /^\s*(javascript|data|vbscript):/i;
var isDangerousAttr = (key) => key === "src" || key === "href" || key.startsWith("on"); var DANGEROUS_URI_ATTRS = new Set(["src", "href", "formaction", "action", "background", "code", "archive"]);
var isDangerousAttr = (key) => DANGEROUS_URI_ATTRS.has(key) || key.startsWith("on");
var validateAttr = (key, val) => { var validateAttr = (key, val) => {
if (val == null || val === false) if (val == null || val === false)
return null; return null;
@@ -298,8 +299,9 @@ var h = (tag, props = {}, children = []) => {
continue; continue;
} }
if (isSVG && k.startsWith("xlink:")) { if (isSVG && k.startsWith("xlink:")) {
const ns = "http://www.w3.org/1999/xlink"; const cleanVal = validateAttr(k.slice(6), v);
v == null ? el.removeAttributeNS(ns, k.slice(6)) : el.setAttributeNS(ns, k.slice(6), v); let lnk = "http://www.w3.org/1999/xlink";
cleanVal == null ? el.removeAttributeNS(lnk, k.slice(6)) : el.setAttributeNS(lnk, k.slice(6), cleanVal);
continue; continue;
} }
if (k.startsWith("on")) { if (k.startsWith("on")) {

File diff suppressed because one or more lines are too long

8
dist/sigpro.js vendored
View File

@@ -300,7 +300,8 @@
node.childNodes.forEach((n) => cleanupNode(n)); node.childNodes.forEach((n) => cleanupNode(n));
}; };
var DANGEROUS_PROTOCOL = /^\s*(javascript|data|vbscript):/i; var DANGEROUS_PROTOCOL = /^\s*(javascript|data|vbscript):/i;
var isDangerousAttr = (key) => key === "src" || key === "href" || key.startsWith("on"); var DANGEROUS_URI_ATTRS = new Set(["src", "href", "formaction", "action", "background", "code", "archive"]);
var isDangerousAttr = (key) => DANGEROUS_URI_ATTRS.has(key) || key.startsWith("on");
var validateAttr = (key, val) => { var validateAttr = (key, val) => {
if (val == null || val === false) if (val == null || val === false)
return null; return null;
@@ -354,8 +355,9 @@
continue; continue;
} }
if (isSVG && k.startsWith("xlink:")) { if (isSVG && k.startsWith("xlink:")) {
const ns = "http://www.w3.org/1999/xlink"; const cleanVal = validateAttr(k.slice(6), v);
v == null ? el.removeAttributeNS(ns, k.slice(6)) : el.setAttributeNS(ns, k.slice(6), v); let lnk = "http://www.w3.org/1999/xlink";
cleanVal == null ? el.removeAttributeNS(lnk, k.slice(6)) : el.setAttributeNS(lnk, k.slice(6), cleanVal);
continue; continue;
} }
if (k.startsWith("on")) { if (k.startsWith("on")) {

2
dist/sigpro.min.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -184,7 +184,7 @@ Applies smooth enter animations (CSS transitions / keyframes). Returns the modif
```javascript ```javascript
fx({ name: 'fade', duration: 300 }, fx({ name: 'fade', duration: 300 },
Div({}, 'Hello') div({}, 'Hello')
) )
``` ```

View File

@@ -224,7 +224,7 @@ Or using the classic script (autoglobal):
## 8. Important Notes ## 8. Important Notes
- **Naming:** All tag helpers are **lowercase** no PascalCase helpers (`Div`, `Button`). - **Naming:** All tag helpers are **lowercase**.
- **Global availability:** - **Global availability:**
- **IIFE script** → automatically on `window`. - **IIFE script** → automatically on `window`.
- **ESM module** → not global by default; use `import { div } from 'sigpro'` or call `sigpro()` to inject all globals. - **ESM module** → not global by default; use `import { div } from 'sigpro'` or call `sigpro()` to inject all globals.

View File

@@ -300,7 +300,8 @@
node.childNodes.forEach((n) => cleanupNode(n)); node.childNodes.forEach((n) => cleanupNode(n));
}; };
var DANGEROUS_PROTOCOL = /^\s*(javascript|data|vbscript):/i; var DANGEROUS_PROTOCOL = /^\s*(javascript|data|vbscript):/i;
var isDangerousAttr = (key) => key === "src" || key === "href" || key.startsWith("on"); var DANGEROUS_URI_ATTRS = new Set(["src", "href", "formaction", "action", "background", "code", "archive"]);
var isDangerousAttr = (key) => DANGEROUS_URI_ATTRS.has(key) || key.startsWith("on");
var validateAttr = (key, val) => { var validateAttr = (key, val) => {
if (val == null || val === false) if (val == null || val === false)
return null; return null;
@@ -354,8 +355,9 @@
continue; continue;
} }
if (isSVG && k.startsWith("xlink:")) { if (isSVG && k.startsWith("xlink:")) {
const ns = "http://www.w3.org/1999/xlink"; const cleanVal = validateAttr(k.slice(6), v);
v == null ? el.removeAttributeNS(ns, k.slice(6)) : el.setAttributeNS(ns, k.slice(6), v); let lnk = "http://www.w3.org/1999/xlink";
cleanVal == null ? el.removeAttributeNS(lnk, k.slice(6)) : el.setAttributeNS(lnk, k.slice(6), cleanVal);
continue; continue;
} }
if (k.startsWith("on")) { if (k.startsWith("on")) {

View File

@@ -1,6 +1,6 @@
{ {
"name": "sigpro", "name": "sigpro",
"version": "1.2.20", "version": "1.2.21",
"type": "module", "type": "module",
"license": "MIT", "license": "MIT",
"main": "./dist/sigpro.esm.min.js", "main": "./dist/sigpro.esm.min.js",
@@ -28,10 +28,10 @@
"homepage": "https://sigpro.natxocc.com/#/", "homepage": "https://sigpro.natxocc.com/#/",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://git.natxocc.com/natxocc/sigpro" "url": "https://github.com/natxocc/sigpro"
}, },
"bugs": { "bugs": {
"url": "https://git.natxocc.com/natxocc/sigpro/issues" "url": "https://github.com/natxocc/sigpro/issues"
}, },
"scripts": { "scripts": {
"clean": "rm -rf dist", "clean": "rm -rf dist",

View File

@@ -230,8 +230,9 @@ const cleanupNode = (node) => {
if (node.childNodes) node.childNodes.forEach(n => cleanupNode(n)); if (node.childNodes) node.childNodes.forEach(n => cleanupNode(n));
}; };
const DANGEROUS_PROTOCOL = /^\s*(javascript|data|vbscript):/i var DANGEROUS_PROTOCOL = /^\s*(javascript|data|vbscript):/i;
const isDangerousAttr = key => key === 'src' || key === 'href' || key.startsWith('on') var DANGEROUS_URI_ATTRS = new Set(["src", "href", "formaction", "action", "background", "code", "archive"]);
var isDangerousAttr = (key) => DANGEROUS_URI_ATTRS.has(key) || key.startsWith("on");
const validateAttr = (key, val) => { const validateAttr = (key, val) => {
if (val == null || val === false) return null if (val == null || val === false) return null
@@ -292,9 +293,12 @@ const h = (tag, props = {}, children = []) => {
continue continue
} }
if (isSVG && k.startsWith("xlink:")) { if (isSVG && k.startsWith("xlink:")) {
const ns = "http://www.w3.org/1999/xlink" const cleanVal = validateAttr(k.slice(6), v);
v == null ? el.removeAttributeNS(ns, k.slice(6)) : el.setAttributeNS(ns, k.slice(6), v) let lnk = "http://www.w3.org/1999/xlink"
continue cleanVal == null
? el.removeAttributeNS(lnk, k.slice(6))
: el.setAttributeNS(lnk, k.slice(6), cleanVal);
continue;
} }
if (k.startsWith("on")) { if (k.startsWith("on")) {
const ev = k.slice(2).toLowerCase() const ev = k.slice(2).toLowerCase()