jq79 0.4.9 → 0.4.11
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/jq79.cjs +10 -10
- package/dist/jq79.cjs.map +1 -1
- package/dist/jq79.d.ts +1 -0
- package/dist/jq79.global.js +10 -10
- package/dist/jq79.global.js.map +1 -1
- package/dist/jq79.js +10 -10
- package/dist/jq79.js.map +1 -1
- package/package.json +1 -1
- package/src/jq79.ts +31 -13
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jq79",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.11",
|
|
4
4
|
"description": "Mini reactive component library: single-file components, Svelte-style setup scripts, fine-grained proxy reactivity. Single-file build, zero dependencies.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"reactive",
|
package/src/jq79.ts
CHANGED
|
@@ -97,6 +97,12 @@ const interpolate = (template: string, scope: Record<string, any>): string =>
|
|
|
97
97
|
|
|
98
98
|
|
|
99
99
|
const CONTROL_ATTRS = new Set([":attrs", ":class", ":value", ":checked", ":selected", ":if", ":elseif", ":else", ":each", ":key", ":with", ":text", ":html", ":html.allowed"])
|
|
100
|
+
|
|
101
|
+
// a control attribute is one the static-attr loop and nested-component prop
|
|
102
|
+
// collection must skip. The set holds the fixed names; `:class.<name>` (the
|
|
103
|
+
// single-flag shorthand) is open-ended, so it's matched by prefix - it can't be
|
|
104
|
+
// enumerated into the set
|
|
105
|
+
const isControlAttr = (attr: string): boolean => CONTROL_ATTRS.has(attr) || attr.startsWith(":class.")
|
|
100
106
|
// `item in items`, `item, i in items`, `(value, key) in props` - the second
|
|
101
107
|
// binding is the array index or the object key, parens optional (Vue-style).
|
|
102
108
|
// The list expression can span lines, so it matches [\s\S] rather than `.`
|
|
@@ -238,7 +244,7 @@ const renderNestedComponent = (key: string, node: TemplateNode, scope: Record<st
|
|
|
238
244
|
Object.entries(node.attrs).forEach(([attr, value]) => {
|
|
239
245
|
// the parent's scope stamp is stamped on every template element, this tag
|
|
240
246
|
// included - it's not a prop, and the child renders under its own scope
|
|
241
|
-
if (attr === SCOPE_ATTR ||
|
|
247
|
+
if (attr === SCOPE_ATTR || isControlAttr(attr)) return
|
|
242
248
|
if (attr.startsWith("@")) {
|
|
243
249
|
events.push([attr, value])
|
|
244
250
|
} else if (attr === ":model" || attr.startsWith(":model.")) {
|
|
@@ -491,7 +497,7 @@ const renderNode = (node: TemplateNode, outerScope: Record<string, any>, fx: Eff
|
|
|
491
497
|
if (!(el instanceof HTMLUnknownElement || node.tag.includes("-"))) {
|
|
492
498
|
console.warn(`jq79: ${key} on <${node.tag}> does nothing - :model binds component tags only (for now)`)
|
|
493
499
|
}
|
|
494
|
-
} else if (!
|
|
500
|
+
} else if (!isControlAttr(key)) el.setAttribute(key, value)
|
|
495
501
|
})
|
|
496
502
|
|
|
497
503
|
const bindExpr = node.attrs[":attrs"]
|
|
@@ -509,17 +515,27 @@ const renderNode = (node: TemplateNode, outerScope: Record<string, any>, fx: Eff
|
|
|
509
515
|
})
|
|
510
516
|
}
|
|
511
517
|
|
|
512
|
-
// :class="expr" adds classes on top of the static `class` attribute
|
|
513
|
-
//
|
|
514
|
-
//
|
|
515
|
-
//
|
|
518
|
+
// :class="expr" adds classes on top of the static `class` attribute, and
|
|
519
|
+
// :class.<name>="expr" is the single-flag shorthand for `{ <name>: expr }`
|
|
520
|
+
// (the name routed through classNames, so an empty `:class.` can't reach
|
|
521
|
+
// classList.add, which throws on ""). Both feed one effect and one set of
|
|
522
|
+
// added classes: only classes this binding added are ever removed, so the
|
|
523
|
+
// static list survives every re-run, even when the expression names one of
|
|
524
|
+
// its classes and then drops it (class="btn" :class="{ btn: cond }" keeps
|
|
525
|
+
// btn on false)
|
|
516
526
|
const classExpr = node.attrs[":class"]
|
|
517
|
-
|
|
527
|
+
const classToggles = Object.entries(node.attrs)
|
|
528
|
+
.filter(([key]) => key.startsWith(":class."))
|
|
529
|
+
.map(([key, expr]): [string, string] => [key.slice(":class.".length), expr])
|
|
530
|
+
if (classExpr !== undefined || classToggles.length) {
|
|
518
531
|
const staticClasses = new Set(classNames(node.attrs.class ?? ""))
|
|
519
532
|
let bound: string[] = []
|
|
520
533
|
|
|
521
534
|
fx.effect(() => {
|
|
522
|
-
const next = classNames(evalExpr(classExpr, scope))
|
|
535
|
+
const next = classExpr !== undefined ? classNames(evalExpr(classExpr, scope)) : []
|
|
536
|
+
classToggles.forEach(([name, expr]) => {
|
|
537
|
+
if (evalExpr(expr, scope)) next.push(...classNames(name))
|
|
538
|
+
})
|
|
523
539
|
bound.forEach(name => {
|
|
524
540
|
if (!next.includes(name) && !staticClasses.has(name)) el.classList.remove(name)
|
|
525
541
|
})
|
|
@@ -1039,11 +1055,6 @@ const releaseStyle = (content: string) => {
|
|
|
1039
1055
|
}
|
|
1040
1056
|
}
|
|
1041
1057
|
|
|
1042
|
-
// library helpers injected into setup scripts. They behave like extra
|
|
1043
|
-
// globals: a same-named scope property (render data or a top-level
|
|
1044
|
-
// declaration) shadows them
|
|
1045
|
-
const SETUP_HELPERS: Record<string, any> = { $, $$, $create, $reactive }
|
|
1046
|
-
|
|
1047
1058
|
// scripts run inside `with (scriptScope)`, where scriptScope's `has` trap
|
|
1048
1059
|
// claims ownership of every name that is neither a real global, an injected
|
|
1049
1060
|
// library helper, nor one of the internal helpers. This makes `with` route ALL
|
|
@@ -1556,8 +1567,15 @@ export class Component79 {
|
|
|
1556
1567
|
}
|
|
1557
1568
|
}
|
|
1558
1569
|
|
|
1570
|
+
export { Component79 as C79 }
|
|
1571
|
+
|
|
1559
1572
|
export const parseComponent = (component: string): Component79 => new Component79(component)
|
|
1560
1573
|
|
|
1574
|
+
// library helpers injected into setup scripts. They behave like extra
|
|
1575
|
+
// globals: a same-named scope property (render data or a top-level
|
|
1576
|
+
// declaration) shadows them
|
|
1577
|
+
const SETUP_HELPERS: Record<string, any> = { $, $$, $create, $reactive, Component79 }
|
|
1578
|
+
|
|
1561
1579
|
// the hot-reload handshake. jq79/dev serves a classic script that sets the flag
|
|
1562
1580
|
// below; classic scripts run before deferred module ones, so the flag is always
|
|
1563
1581
|
// set before this module evaluates. The page's copy of the runtime can come from
|