@getforma/core 1.0.9 → 1.0.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/README.md +1 -1
- package/dist/chunk-263HW3KN.cjs +35 -0
- package/dist/chunk-263HW3KN.cjs.map +1 -0
- package/dist/chunk-2QQBKQIF.js +30 -0
- package/dist/chunk-2QQBKQIF.js.map +1 -0
- package/dist/forma-runtime-csp.js +40 -2
- package/dist/forma-runtime.js +40 -2
- package/dist/formajs-runtime-hardened.global.js +40 -2
- package/dist/formajs-runtime-hardened.global.js.map +1 -1
- package/dist/formajs-runtime.global.js +40 -2
- package/dist/formajs-runtime.global.js.map +1 -1
- package/dist/runtime-hardened.cjs +40 -2
- package/dist/runtime-hardened.cjs.map +1 -1
- package/dist/runtime-hardened.js +40 -2
- package/dist/runtime-hardened.js.map +1 -1
- package/dist/runtime.cjs +18 -2
- package/dist/runtime.cjs.map +1 -1
- package/dist/runtime.js +18 -2
- package/dist/runtime.js.map +1 -1
- package/dist/ssr/index.cjs +23 -42
- package/dist/ssr/index.cjs.map +1 -1
- package/dist/ssr/index.js +23 -42
- package/dist/ssr/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](https://socket.dev/npm/package/@getforma/core)
|
|
6
6
|
[](https://opensource.org/licenses/MIT)
|
|
7
7
|
|
|
8
|
-
Reactive DOM library with fine-grained signals. No virtual DOM — signals update only the DOM nodes that changed. Components run once. ~
|
|
8
|
+
Reactive DOM library with fine-grained signals. No virtual DOM — signals update only the DOM nodes that changed. Components run once. The core entry (`@getforma/core`) is ~8 KB gzipped; the full HTML runtime bundle (`formajs-runtime.global.js`) is ~24 KB gzipped.
|
|
9
9
|
|
|
10
10
|
```tsx
|
|
11
11
|
import { createSignal, h, mount } from "@getforma/core";
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/security/url-safety.ts
|
|
4
|
+
var URL_IGNORED_CHARS_RE = /[\u0000-\u0020\u007F-\u009F]/g;
|
|
5
|
+
var DANGEROUS_SCHEME_RE = /^(?:javascript|vbscript|data:text\/html)/i;
|
|
6
|
+
var URL_ATTRS = /* @__PURE__ */ new Set([
|
|
7
|
+
"href",
|
|
8
|
+
"src",
|
|
9
|
+
"action",
|
|
10
|
+
"formaction",
|
|
11
|
+
"xlink:href",
|
|
12
|
+
"poster",
|
|
13
|
+
"background"
|
|
14
|
+
]);
|
|
15
|
+
function isUrlAttr(name) {
|
|
16
|
+
return URL_ATTRS.has(name.toLowerCase());
|
|
17
|
+
}
|
|
18
|
+
function isDangerousUrl(value) {
|
|
19
|
+
const normalized = value.replace(URL_IGNORED_CHARS_RE, "");
|
|
20
|
+
return DANGEROUS_SCHEME_RE.test(normalized);
|
|
21
|
+
}
|
|
22
|
+
function isEventHandlerAttr(name) {
|
|
23
|
+
return /^on/i.test(name);
|
|
24
|
+
}
|
|
25
|
+
var SAFE_ATTR_NAME_RE = /^[A-Za-z_:][-A-Za-z0-9_:.]*$/;
|
|
26
|
+
function isSafeAttrName(name) {
|
|
27
|
+
return SAFE_ATTR_NAME_RE.test(name);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
exports.isDangerousUrl = isDangerousUrl;
|
|
31
|
+
exports.isEventHandlerAttr = isEventHandlerAttr;
|
|
32
|
+
exports.isSafeAttrName = isSafeAttrName;
|
|
33
|
+
exports.isUrlAttr = isUrlAttr;
|
|
34
|
+
//# sourceMappingURL=chunk-263HW3KN.cjs.map
|
|
35
|
+
//# sourceMappingURL=chunk-263HW3KN.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/security/url-safety.ts"],"names":[],"mappings":";;;AAgBA,IAAM,oBAAA,GAAuB,+BAAA;AAK7B,IAAM,mBAAA,GAAsB,2CAAA;AAGrB,IAAM,SAAA,uBAAgB,GAAA,CAAI;AAAA,EAC/B,MAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAC,CAAA;AAGM,SAAS,UAAU,IAAA,EAAuB;AAC/C,EAAA,OAAO,SAAA,CAAU,GAAA,CAAI,IAAA,CAAK,WAAA,EAAa,CAAA;AACzC;AAMO,SAAS,eAAe,KAAA,EAAwB;AACrD,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,OAAA,CAAQ,oBAAA,EAAsB,EAAE,CAAA;AACzD,EAAA,OAAO,mBAAA,CAAoB,KAAK,UAAU,CAAA;AAC5C;AAGO,SAAS,mBAAmB,IAAA,EAAuB;AACxD,EAAA,OAAO,MAAA,CAAO,KAAK,IAAI,CAAA;AACzB;AAKA,IAAM,iBAAA,GAAoB,8BAAA;AAGnB,SAAS,eAAe,IAAA,EAAuB;AACpD,EAAA,OAAO,iBAAA,CAAkB,KAAK,IAAI,CAAA;AACpC","file":"chunk-263HW3KN.cjs","sourcesContent":["/**\n * URL / attribute safety helpers shared by the SSR renderer (`src/ssr`) and the\n * DOM runtime (`src/runtime.ts`).\n *\n * The subtle part is scheme detection. Browsers strip ASCII whitespace and C0\n * control characters out of a URL before resolving its scheme, so\n * `java\\tscript:alert(1)`, `javas\\ncript:...` and `\\x01javascript:...` all\n * execute even though a naive `/^javascript:/` test does not match them. We\n * normalize the value the same way the browser does *before* testing.\n *\n * This module has no dependencies so it can be pulled into every build variant\n * (standard, hardened/CSP, SSR) cheaply.\n */\n\n// C0 controls + space (0x00-0x20), DEL and C1 controls (0x7F-0x9F). These are\n// exactly the bytes a URL parser ignores/strips when reading the scheme.\nconst URL_IGNORED_CHARS_RE = /[\\u0000-\\u0020\\u007F-\\u009F]/g;\n\n// Schemes that can execute script or smuggle an active HTML document.\n// Kept intentionally narrow to avoid blocking legitimate `data:image/*` inline\n// assets; `data:image/svg+xml` in a navigable context is handled separately.\nconst DANGEROUS_SCHEME_RE = /^(?:javascript|vbscript|data:text\\/html)/i;\n\n/** Attributes whose values are resolved as URLs and must be scheme-checked. */\nexport const URL_ATTRS = new Set([\n 'href',\n 'src',\n 'action',\n 'formaction',\n 'xlink:href',\n 'poster',\n 'background',\n]);\n\n/** True if `name` is a URL-bearing attribute (case-insensitive). */\nexport function isUrlAttr(name: string): boolean {\n return URL_ATTRS.has(name.toLowerCase());\n}\n\n/**\n * True if `value` uses a scheme that can execute script, after normalizing away\n * the whitespace and control characters that browsers ignore in a URL scheme.\n */\nexport function isDangerousUrl(value: string): boolean {\n const normalized = value.replace(URL_IGNORED_CHARS_RE, '');\n return DANGEROUS_SCHEME_RE.test(normalized);\n}\n\n/** True for any `on…` event-handler attribute name (case-insensitive). */\nexport function isEventHandlerAttr(name: string): boolean {\n return /^on/i.test(name);\n}\n\n// A well-formed HTML attribute name: starts with a letter/`_`/`:`, followed by\n// letters, digits, `-`, `_`, `:` or `.`. Rejects whitespace, `=`, quotes and\n// `/`, which is what an attacker needs to break out and inject a new attribute.\nconst SAFE_ATTR_NAME_RE = /^[A-Za-z_:][-A-Za-z0-9_:.]*$/;\n\n/** True if `name` is safe to emit verbatim as an attribute name. */\nexport function isSafeAttrName(name: string): boolean {\n return SAFE_ATTR_NAME_RE.test(name);\n}\n"]}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
// src/security/url-safety.ts
|
|
2
|
+
var URL_IGNORED_CHARS_RE = /[\u0000-\u0020\u007F-\u009F]/g;
|
|
3
|
+
var DANGEROUS_SCHEME_RE = /^(?:javascript|vbscript|data:text\/html)/i;
|
|
4
|
+
var URL_ATTRS = /* @__PURE__ */ new Set([
|
|
5
|
+
"href",
|
|
6
|
+
"src",
|
|
7
|
+
"action",
|
|
8
|
+
"formaction",
|
|
9
|
+
"xlink:href",
|
|
10
|
+
"poster",
|
|
11
|
+
"background"
|
|
12
|
+
]);
|
|
13
|
+
function isUrlAttr(name) {
|
|
14
|
+
return URL_ATTRS.has(name.toLowerCase());
|
|
15
|
+
}
|
|
16
|
+
function isDangerousUrl(value) {
|
|
17
|
+
const normalized = value.replace(URL_IGNORED_CHARS_RE, "");
|
|
18
|
+
return DANGEROUS_SCHEME_RE.test(normalized);
|
|
19
|
+
}
|
|
20
|
+
function isEventHandlerAttr(name) {
|
|
21
|
+
return /^on/i.test(name);
|
|
22
|
+
}
|
|
23
|
+
var SAFE_ATTR_NAME_RE = /^[A-Za-z_:][-A-Za-z0-9_:.]*$/;
|
|
24
|
+
function isSafeAttrName(name) {
|
|
25
|
+
return SAFE_ATTR_NAME_RE.test(name);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export { isDangerousUrl, isEventHandlerAttr, isSafeAttrName, isUrlAttr };
|
|
29
|
+
//# sourceMappingURL=chunk-2QQBKQIF.js.map
|
|
30
|
+
//# sourceMappingURL=chunk-2QQBKQIF.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/security/url-safety.ts"],"names":[],"mappings":";AAgBA,IAAM,oBAAA,GAAuB,+BAAA;AAK7B,IAAM,mBAAA,GAAsB,2CAAA;AAGrB,IAAM,SAAA,uBAAgB,GAAA,CAAI;AAAA,EAC/B,MAAA;AAAA,EACA,KAAA;AAAA,EACA,QAAA;AAAA,EACA,YAAA;AAAA,EACA,YAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAC,CAAA;AAGM,SAAS,UAAU,IAAA,EAAuB;AAC/C,EAAA,OAAO,SAAA,CAAU,GAAA,CAAI,IAAA,CAAK,WAAA,EAAa,CAAA;AACzC;AAMO,SAAS,eAAe,KAAA,EAAwB;AACrD,EAAA,MAAM,UAAA,GAAa,KAAA,CAAM,OAAA,CAAQ,oBAAA,EAAsB,EAAE,CAAA;AACzD,EAAA,OAAO,mBAAA,CAAoB,KAAK,UAAU,CAAA;AAC5C;AAGO,SAAS,mBAAmB,IAAA,EAAuB;AACxD,EAAA,OAAO,MAAA,CAAO,KAAK,IAAI,CAAA;AACzB;AAKA,IAAM,iBAAA,GAAoB,8BAAA;AAGnB,SAAS,eAAe,IAAA,EAAuB;AACpD,EAAA,OAAO,iBAAA,CAAkB,KAAK,IAAI,CAAA;AACpC","file":"chunk-2QQBKQIF.js","sourcesContent":["/**\n * URL / attribute safety helpers shared by the SSR renderer (`src/ssr`) and the\n * DOM runtime (`src/runtime.ts`).\n *\n * The subtle part is scheme detection. Browsers strip ASCII whitespace and C0\n * control characters out of a URL before resolving its scheme, so\n * `java\\tscript:alert(1)`, `javas\\ncript:...` and `\\x01javascript:...` all\n * execute even though a naive `/^javascript:/` test does not match them. We\n * normalize the value the same way the browser does *before* testing.\n *\n * This module has no dependencies so it can be pulled into every build variant\n * (standard, hardened/CSP, SSR) cheaply.\n */\n\n// C0 controls + space (0x00-0x20), DEL and C1 controls (0x7F-0x9F). These are\n// exactly the bytes a URL parser ignores/strips when reading the scheme.\nconst URL_IGNORED_CHARS_RE = /[\\u0000-\\u0020\\u007F-\\u009F]/g;\n\n// Schemes that can execute script or smuggle an active HTML document.\n// Kept intentionally narrow to avoid blocking legitimate `data:image/*` inline\n// assets; `data:image/svg+xml` in a navigable context is handled separately.\nconst DANGEROUS_SCHEME_RE = /^(?:javascript|vbscript|data:text\\/html)/i;\n\n/** Attributes whose values are resolved as URLs and must be scheme-checked. */\nexport const URL_ATTRS = new Set([\n 'href',\n 'src',\n 'action',\n 'formaction',\n 'xlink:href',\n 'poster',\n 'background',\n]);\n\n/** True if `name` is a URL-bearing attribute (case-insensitive). */\nexport function isUrlAttr(name: string): boolean {\n return URL_ATTRS.has(name.toLowerCase());\n}\n\n/**\n * True if `value` uses a scheme that can execute script, after normalizing away\n * the whitespace and control characters that browsers ignore in a URL scheme.\n */\nexport function isDangerousUrl(value: string): boolean {\n const normalized = value.replace(URL_IGNORED_CHARS_RE, '');\n return DANGEROUS_SCHEME_RE.test(normalized);\n}\n\n/** True for any `on…` event-handler attribute name (case-insensitive). */\nexport function isEventHandlerAttr(name: string): boolean {\n return /^on/i.test(name);\n}\n\n// A well-formed HTML attribute name: starts with a letter/`_`/`:`, followed by\n// letters, digits, `-`, `_`, `:` or `.`. Rejects whitespace, `=`, quotes and\n// `/`, which is what an attacker needs to break out and inject a new attribute.\nconst SAFE_ATTR_NAME_RE = /^[A-Za-z_:][-A-Za-z0-9_:.]*$/;\n\n/** True if `name` is safe to emit verbatim as an attribute name. */\nexport function isSafeAttrName(name: string): boolean {\n return SAFE_ATTR_NAME_RE.test(name);\n}\n"]}
|
|
@@ -1047,7 +1047,35 @@ var FormaRuntime = (function (exports) {
|
|
|
1047
1047
|
};
|
|
1048
1048
|
}
|
|
1049
1049
|
|
|
1050
|
+
// src/security/url-safety.ts
|
|
1051
|
+
var URL_IGNORED_CHARS_RE = /[\u0000-\u0020\u007F-\u009F]/g;
|
|
1052
|
+
var DANGEROUS_SCHEME_RE = /^(?:javascript|vbscript|data:text\/html)/i;
|
|
1053
|
+
var URL_ATTRS = /* @__PURE__ */ new Set([
|
|
1054
|
+
"href",
|
|
1055
|
+
"src",
|
|
1056
|
+
"action",
|
|
1057
|
+
"formaction",
|
|
1058
|
+
"xlink:href",
|
|
1059
|
+
"poster",
|
|
1060
|
+
"background"
|
|
1061
|
+
]);
|
|
1062
|
+
function isUrlAttr(name) {
|
|
1063
|
+
return URL_ATTRS.has(name.toLowerCase());
|
|
1064
|
+
}
|
|
1065
|
+
function isDangerousUrl(value2) {
|
|
1066
|
+
const normalized = value2.replace(URL_IGNORED_CHARS_RE, "");
|
|
1067
|
+
return DANGEROUS_SCHEME_RE.test(normalized);
|
|
1068
|
+
}
|
|
1069
|
+
function isEventHandlerAttr(name) {
|
|
1070
|
+
return /^on/i.test(name);
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1050
1073
|
// src/runtime.ts
|
|
1074
|
+
function isUnsafeAttrBinding(name, value2) {
|
|
1075
|
+
if (isEventHandlerAttr(name)) return true;
|
|
1076
|
+
if (isUrlAttr(name) && isDangerousUrl(value2)) return true;
|
|
1077
|
+
return false;
|
|
1078
|
+
}
|
|
1051
1079
|
var _refetchRegistry = /* @__PURE__ */ new Map();
|
|
1052
1080
|
function $refetch(id) {
|
|
1053
1081
|
const fn = _refetchRegistry.get(id);
|
|
@@ -2012,7 +2040,12 @@ var FormaRuntime = (function (exports) {
|
|
|
2012
2040
|
if (attr.value.includes("{item")) {
|
|
2013
2041
|
const compiled = compileTemplate(attr.value);
|
|
2014
2042
|
entries.push({ attr: attr.name, compiled });
|
|
2015
|
-
|
|
2043
|
+
const value2 = evaluateCompiledTemplate(compiled, item);
|
|
2044
|
+
if (isUnsafeAttrBinding(attr.name, value2)) {
|
|
2045
|
+
node.removeAttribute(attr.name);
|
|
2046
|
+
} else {
|
|
2047
|
+
node.setAttribute(attr.name, value2);
|
|
2048
|
+
}
|
|
2016
2049
|
}
|
|
2017
2050
|
}
|
|
2018
2051
|
if (entries.length > 0) {
|
|
@@ -2784,7 +2817,12 @@ var FormaRuntime = (function (exports) {
|
|
|
2784
2817
|
if (val == null || val === false) {
|
|
2785
2818
|
el.removeAttribute(attrName);
|
|
2786
2819
|
} else {
|
|
2787
|
-
|
|
2820
|
+
const str = String(val);
|
|
2821
|
+
if (isUnsafeAttrBinding(attrName, str)) {
|
|
2822
|
+
el.removeAttribute(attrName);
|
|
2823
|
+
} else {
|
|
2824
|
+
el.setAttribute(attrName, str);
|
|
2825
|
+
}
|
|
2788
2826
|
}
|
|
2789
2827
|
});
|
|
2790
2828
|
disposers.push(dispose);
|
package/dist/forma-runtime.js
CHANGED
|
@@ -1116,7 +1116,35 @@ var FormaRuntime = (() => {
|
|
|
1116
1116
|
};
|
|
1117
1117
|
}
|
|
1118
1118
|
|
|
1119
|
+
// src/security/url-safety.ts
|
|
1120
|
+
var URL_IGNORED_CHARS_RE = /[\u0000-\u0020\u007F-\u009F]/g;
|
|
1121
|
+
var DANGEROUS_SCHEME_RE = /^(?:javascript|vbscript|data:text\/html)/i;
|
|
1122
|
+
var URL_ATTRS = /* @__PURE__ */ new Set([
|
|
1123
|
+
"href",
|
|
1124
|
+
"src",
|
|
1125
|
+
"action",
|
|
1126
|
+
"formaction",
|
|
1127
|
+
"xlink:href",
|
|
1128
|
+
"poster",
|
|
1129
|
+
"background"
|
|
1130
|
+
]);
|
|
1131
|
+
function isUrlAttr(name) {
|
|
1132
|
+
return URL_ATTRS.has(name.toLowerCase());
|
|
1133
|
+
}
|
|
1134
|
+
function isDangerousUrl(value2) {
|
|
1135
|
+
const normalized = value2.replace(URL_IGNORED_CHARS_RE, "");
|
|
1136
|
+
return DANGEROUS_SCHEME_RE.test(normalized);
|
|
1137
|
+
}
|
|
1138
|
+
function isEventHandlerAttr(name) {
|
|
1139
|
+
return /^on/i.test(name);
|
|
1140
|
+
}
|
|
1141
|
+
|
|
1119
1142
|
// src/runtime.ts
|
|
1143
|
+
function isUnsafeAttrBinding(name, value2) {
|
|
1144
|
+
if (isEventHandlerAttr(name)) return true;
|
|
1145
|
+
if (isUrlAttr(name) && isDangerousUrl(value2)) return true;
|
|
1146
|
+
return false;
|
|
1147
|
+
}
|
|
1120
1148
|
var _refetchRegistry = /* @__PURE__ */ new Map();
|
|
1121
1149
|
function $refetch(id) {
|
|
1122
1150
|
const fn = _refetchRegistry.get(id);
|
|
@@ -2120,7 +2148,12 @@ var FormaRuntime = (() => {
|
|
|
2120
2148
|
if (attr.value.includes("{item")) {
|
|
2121
2149
|
const compiled = compileTemplate(attr.value);
|
|
2122
2150
|
entries.push({ attr: attr.name, compiled });
|
|
2123
|
-
|
|
2151
|
+
const value2 = evaluateCompiledTemplate(compiled, item);
|
|
2152
|
+
if (isUnsafeAttrBinding(attr.name, value2)) {
|
|
2153
|
+
node.removeAttribute(attr.name);
|
|
2154
|
+
} else {
|
|
2155
|
+
node.setAttribute(attr.name, value2);
|
|
2156
|
+
}
|
|
2124
2157
|
}
|
|
2125
2158
|
}
|
|
2126
2159
|
if (entries.length > 0) {
|
|
@@ -2962,7 +2995,12 @@ var FormaRuntime = (() => {
|
|
|
2962
2995
|
if (val == null || val === false) {
|
|
2963
2996
|
el.removeAttribute(attrName);
|
|
2964
2997
|
} else {
|
|
2965
|
-
|
|
2998
|
+
const str = String(val);
|
|
2999
|
+
if (isUnsafeAttrBinding(attrName, str)) {
|
|
3000
|
+
el.removeAttribute(attrName);
|
|
3001
|
+
} else {
|
|
3002
|
+
el.setAttribute(attrName, str);
|
|
3003
|
+
}
|
|
2966
3004
|
}
|
|
2967
3005
|
});
|
|
2968
3006
|
disposers.push(dispose);
|
|
@@ -1047,7 +1047,35 @@ var FormaRuntime = (function (exports) {
|
|
|
1047
1047
|
};
|
|
1048
1048
|
}
|
|
1049
1049
|
|
|
1050
|
+
// src/security/url-safety.ts
|
|
1051
|
+
var URL_IGNORED_CHARS_RE = /[\u0000-\u0020\u007F-\u009F]/g;
|
|
1052
|
+
var DANGEROUS_SCHEME_RE = /^(?:javascript|vbscript|data:text\/html)/i;
|
|
1053
|
+
var URL_ATTRS = /* @__PURE__ */ new Set([
|
|
1054
|
+
"href",
|
|
1055
|
+
"src",
|
|
1056
|
+
"action",
|
|
1057
|
+
"formaction",
|
|
1058
|
+
"xlink:href",
|
|
1059
|
+
"poster",
|
|
1060
|
+
"background"
|
|
1061
|
+
]);
|
|
1062
|
+
function isUrlAttr(name) {
|
|
1063
|
+
return URL_ATTRS.has(name.toLowerCase());
|
|
1064
|
+
}
|
|
1065
|
+
function isDangerousUrl(value2) {
|
|
1066
|
+
const normalized = value2.replace(URL_IGNORED_CHARS_RE, "");
|
|
1067
|
+
return DANGEROUS_SCHEME_RE.test(normalized);
|
|
1068
|
+
}
|
|
1069
|
+
function isEventHandlerAttr(name) {
|
|
1070
|
+
return /^on/i.test(name);
|
|
1071
|
+
}
|
|
1072
|
+
|
|
1050
1073
|
// src/runtime.ts
|
|
1074
|
+
function isUnsafeAttrBinding(name, value2) {
|
|
1075
|
+
if (isEventHandlerAttr(name)) return true;
|
|
1076
|
+
if (isUrlAttr(name) && isDangerousUrl(value2)) return true;
|
|
1077
|
+
return false;
|
|
1078
|
+
}
|
|
1051
1079
|
var _refetchRegistry = /* @__PURE__ */ new Map();
|
|
1052
1080
|
function $refetch(id) {
|
|
1053
1081
|
const fn = _refetchRegistry.get(id);
|
|
@@ -2012,7 +2040,12 @@ var FormaRuntime = (function (exports) {
|
|
|
2012
2040
|
if (attr.value.includes("{item")) {
|
|
2013
2041
|
const compiled = compileTemplate(attr.value);
|
|
2014
2042
|
entries.push({ attr: attr.name, compiled });
|
|
2015
|
-
|
|
2043
|
+
const value2 = evaluateCompiledTemplate(compiled, item);
|
|
2044
|
+
if (isUnsafeAttrBinding(attr.name, value2)) {
|
|
2045
|
+
node.removeAttribute(attr.name);
|
|
2046
|
+
} else {
|
|
2047
|
+
node.setAttribute(attr.name, value2);
|
|
2048
|
+
}
|
|
2016
2049
|
}
|
|
2017
2050
|
}
|
|
2018
2051
|
if (entries.length > 0) {
|
|
@@ -2784,7 +2817,12 @@ var FormaRuntime = (function (exports) {
|
|
|
2784
2817
|
if (val == null || val === false) {
|
|
2785
2818
|
el.removeAttribute(attrName);
|
|
2786
2819
|
} else {
|
|
2787
|
-
|
|
2820
|
+
const str = String(val);
|
|
2821
|
+
if (isUnsafeAttrBinding(attrName, str)) {
|
|
2822
|
+
el.removeAttribute(attrName);
|
|
2823
|
+
} else {
|
|
2824
|
+
el.setAttribute(attrName, str);
|
|
2825
|
+
}
|
|
2788
2826
|
}
|
|
2789
2827
|
});
|
|
2790
2828
|
disposers.push(dispose);
|