Skip to content

Commit 91332c6

Browse files
committed
Allow : in attributes
1 parent 0f3179f commit 91332c6

File tree

3 files changed

+55
-2
lines changed

3 files changed

+55
-2
lines changed

index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ const ALIASES = {
338338
}
339339

340340
// Pre-compiled regex for better performance
341-
const KEY_VALIDATION_REGEX = /^[a-zA-Z0-9\-_]+$/
341+
const KEY_VALIDATION_REGEX = /^[a-zA-Z0-9\-_:]+$/
342342
const isKeyValid = (key) => KEY_VALIDATION_REGEX.test(key)
343343

344344
const attributes = (options) => {

test/tags/attributes/index.js

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,18 @@ module.exports = () => {
66
Div(null, "No attrs"),
77
Div(undefined, "No attrs 2"),
88
// Test style with invalid key
9-
Div({ style: { 'invalid-key!': 'value', color: 'red' } }, "Invalid style key"),
9+
Div(
10+
{ style: { "invalid-key!": "value", color: "red" } },
11+
"Invalid style key",
12+
),
13+
// Test namespaced attributes with colons
14+
Div({ "xml:lang": "en", "data-test": "value" }, "Namespaced attributes"),
15+
Div({ "xmlns:xlink": "http://www.w3.org/1999/xlink" }, "XML namespace"),
16+
Div({ "xlink:href": "#icon" }, "XLink attribute"),
17+
// Test that invalid characters are still filtered
18+
Div(
19+
{ "invalid@attr": "value", "valid-attr": "ok", "invalid!key": "no" },
20+
"Invalid chars filtered",
21+
),
1022
]
1123
}

test/tags/attributes/index.test.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,44 @@ test("attributes: filters invalid style keys", async () => {
1515
assert(html.includes("color:red"))
1616
assert(!html.includes("invalid-key!"))
1717
})
18+
19+
test("attributes: accepts namespaced attributes with colons", async () => {
20+
const { template } = await compile(__dirname)
21+
const html = template()
22+
// Test xml:lang namespace
23+
assert(html.includes('xml:lang="en"'), "Should include xml:lang attribute")
24+
// Test xmlns:xlink namespace declaration
25+
assert(
26+
html.includes('xmlns:xlink="http://www.w3.org/1999/xlink"'),
27+
"Should include xmlns:xlink attribute",
28+
)
29+
// Test xlink:href attribute
30+
assert(
31+
html.includes('xlink:href="#icon"'),
32+
"Should include xlink:href attribute",
33+
)
34+
// Verify data attributes still work
35+
assert(
36+
html.includes('data-test="value"'),
37+
"Should include data-test attribute",
38+
)
39+
})
40+
41+
test("attributes: filters out invalid characters while allowing colons", async () => {
42+
const { template } = await compile(__dirname)
43+
const html = template()
44+
// Valid attributes with hyphens should be included
45+
assert(
46+
html.includes('valid-attr="ok"'),
47+
"Should include valid-attr attribute",
48+
)
49+
// Invalid attributes with @ and ! should be filtered
50+
assert(
51+
!html.includes("invalid@attr"),
52+
"Should not include attributes with @ character",
53+
)
54+
assert(
55+
!html.includes("invalid!key"),
56+
"Should not include attributes with ! character",
57+
)
58+
})

0 commit comments

Comments
 (0)