Skip to content

Commit 9b765fa

Browse files
fixed htmx disabledElt key; fixed htmx request behavior
1 parent eaf790b commit 9b765fa

File tree

3 files changed

+77
-9
lines changed

3 files changed

+77
-9
lines changed

Sources/HTMLKitMacros/HTMLElement.swift

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -184,16 +184,20 @@ private extension HTMLElement {
184184
var string:String = "\(first_expression)"
185185
string = String(string[string.index(after: string.startIndex)...])
186186
if let htmx:HTMLElementAttribute.HTMX = HTMLElementAttribute.HTMX(rawValue: string) {
187+
key = "hx-" + htmx.key
188+
let htmlValue:String = htmx.htmlValue
189+
var delimiter:String = "\\\""
187190
switch htmx {
191+
case .request(_, _, _, _):
192+
delimiter = "'"
193+
break
188194
case .ws(let value):
189195
key = "ws-" + value.key
190196
break
191197
default:
192-
key = "hx-" + htmx.key
193198
break
194199
}
195-
let htmlValue:String = htmx.htmlValue
196-
value = key + (htmlValue.isEmpty ? "" : "=\\\"" + htmlValue + "\\\"")
200+
value = key + (htmlValue.isEmpty ? "" : "=" + delimiter + htmlValue + delimiter)
197201
}
198202
} else if let string:String = parse_attribute(context: context, elementType: elementType, key: key, expression: first_expression, lookupFiles: lookupFiles) {
199203
value = string

Sources/HTMLKitUtilities/HTMX.swift

Lines changed: 47 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public extension HTMLElementAttribute {
2727
case prompt(String)
2828
case put(String)
2929
case replaceURL(URL)
30-
case request(js: Bool, timeout: Int = 0, credentials: Bool = false, noHeaders: Bool = false)
30+
case request(js: Bool, timeout: String?, credentials: String?, noHeaders: String?)
3131
case sync(String, strategy: SyncStrategy?)
3232
case validate(TrueOrFalse)
3333

@@ -83,7 +83,40 @@ public extension HTMLElementAttribute {
8383
case "prompt": self = .prompt(string())
8484
case "put": self = .put(string())
8585
case "replaceURL": self = .replaceURL(URL(rawValue: literal())!)
86-
//case "request": self = .request(js: Bool, timeout: Int, credentials: Bool, noHeaders: Bool) // TODO: fix
86+
case "request":
87+
let string:String = literal(), values:[Substring] = string.split(separator: ",")
88+
var timeout_string:Substring = values[1][values[1].index(after: values[1].firstIndex(of: ":")!)...]
89+
while timeout_string.first?.isWhitespace ?? false {
90+
timeout_string.removeFirst()
91+
}
92+
let javascript:Bool = values[0].split(separator: ":")[1].hasSuffix("true")
93+
let timeout:String?
94+
if timeout_string.first == "\"" {
95+
timeout_string.removeFirst()
96+
timeout = String(timeout_string[timeout_string.startIndex..<timeout_string.index(before: timeout_string.endIndex)])
97+
} else {
98+
timeout = nil
99+
}
100+
var credentials:String? = nil
101+
var credentials_string:Substring = values[2][values[2].index(after: values[2].firstIndex(of: ":")!)...]
102+
if !credentials_string.hasSuffix("nil") {
103+
while (credentials_string.first?.isWhitespace ?? false) || credentials_string.first == "\"" {
104+
credentials_string.removeFirst()
105+
}
106+
credentials_string.removeLast()
107+
credentials = String(credentials_string)
108+
}
109+
var noHeaders:String? = nil
110+
if !string.hasSuffix("nil") {
111+
var value:Substring = values[3][values[3].index(after: values[3].firstIndex(of: ":")!)...]
112+
while (value.first?.isWhitespace ?? false) || value.first == "\"" {
113+
value.removeFirst()
114+
}
115+
value.removeLast()
116+
noHeaders = (javascript ? "js:" : "") + value
117+
}
118+
self = .request(js: javascript, timeout: timeout, credentials: credentials, noHeaders: noHeaders)
119+
break
87120
//case "sync": self = .sync(String, strategy: SyncStrategy?) // TODO: fix
88121
case "validate": self = .validate(enumeration())
89122

@@ -126,7 +159,7 @@ public extension HTMLElementAttribute {
126159
case .confirm(_): return "confirm"
127160
case .delete(_): return "delete"
128161
case .disable(_): return "disable"
129-
case .disabledElt(_): return "disable-elt"
162+
case .disabledElt(_): return "disabled-elt"
130163
case .disinherit(_): return "disinherit"
131164
case .encoding(_): return "encoding"
132165
case .ext(_): return "ext"
@@ -173,8 +206,8 @@ public extension HTMLElementAttribute {
173206
case .disinherit(let value): return value
174207
case .encoding(let value): return value
175208
case .ext(let value): return value
176-
case .headers(let js, let headers): // TODO: fix
177-
return js ? "" : "{" + headers.map({ "\\\"" + $0.key + "\\\":\\\"" + $0.value + "\\\"" }).joined(separator: ",") + "}"
209+
case .headers(let js, let headers):
210+
return (js ? "js:" : "") + "{" + headers.map({ "\\\"" + $0.key + "\\\":\\\"" + $0.value + "\\\"" }).joined(separator: ",") + "}"
178211
case .history(let value): return value.rawValue
179212
case .historyElt(_): return ""
180213
case .include(let value): return value
@@ -187,7 +220,15 @@ public extension HTMLElementAttribute {
187220
case .put(let value): return value
188221
case .replaceURL(let url): return url.htmlValue
189222
case .request(let js, let timeout, let credentials, let noHeaders):
190-
return "" // TODO: fix
223+
if let timeout:String = timeout {
224+
return js ? "js: timeout:\(timeout)" : "{\\\"timeout\\\":\(timeout)}"
225+
} else if let credentials:String = credentials {
226+
return js ? "js: credentials:\(credentials)" : "{\\\"credentials\\\":\(credentials)}"
227+
} else if let noHeaders:String = noHeaders {
228+
return js ? "js: noHeaders:\(noHeaders)" : "{\\\"noHeaders\\\":\(noHeaders)}"
229+
} else {
230+
return ""
231+
}
191232
case .sync(let selector, let strategy):
192233
return selector + (strategy == nil ? "" : ":" + strategy!.htmlValue)
193234
case .validate(let value): return value.rawValue

Tests/HTMLKitTests/HTMXTests.swift

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,14 @@ import Testing
99
import HTMLKit
1010

1111
struct HTMXTests {
12+
@Test func boost() {
13+
var string:StaticString = #div(attributes: [.htmx(.boost(.true))])
14+
#expect(string == "<div hx-boost=\"true\"></div>")
15+
16+
string = #div(attributes: [.htmx(.boost(.false))])
17+
#expect(string == "<div hx-boost=\"false\"></div>")
18+
}
19+
1220
// MARK: get
1321
@Test func get() {
1422
let string:StaticString = #div(attributes: [.htmx(.get("/test"))])
@@ -48,6 +56,21 @@ struct HTMXTests {
4856
#expect(string == "<div hx-replace-url=\"https://litleagues.com\"></div>")
4957
}
5058

59+
// MARK: request
60+
@Test func request() {
61+
var string:StaticString = #div(attributes: [.htmx(.request(js: false, timeout: "5", credentials: nil, noHeaders: nil))])
62+
#expect(string == "<div hx-request='{\"timeout\":5}'></div>")
63+
64+
string = #div(attributes: [.htmx(.request(js: true, timeout: "getTimeout()", credentials: nil, noHeaders: nil))])
65+
#expect(string == "<div hx-request='js: timeout:getTimeout()'></div>")
66+
67+
string = #div(attributes: [.htmx(.request(js: false, timeout: nil, credentials: "true", noHeaders: nil))])
68+
#expect(string == "<div hx-request='{\"credentials\":true}'></div>")
69+
70+
string = #div(attributes: [.htmx(.request(js: false, timeout: nil, credentials: nil, noHeaders: "true"))])
71+
#expect(string == "<div hx-request='{\"noHeaders\":true}'></div>")
72+
}
73+
5174
// MARK: ws
5275
@Test func ws() {
5376
var string:StaticString = #div(attributes: [.htmx(.ws(.connect("https://paradigm-app.com")))])

0 commit comments

Comments
 (0)