Skip to content

Commit d6b9d73

Browse files
committed
feat: add support for vue components
1 parent e255dcb commit d6b9d73

File tree

6 files changed

+106
-83
lines changed

6 files changed

+106
-83
lines changed

Package.resolved

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Package.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ let package = Package(
99
],
1010
dependencies: [
1111
.package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.4.0"),
12-
.package(url: "https://github.com/erikbdev/swift-web.git", exact: "0.0.9"),
12+
.package(url: "https://github.com/erikbdev/swift-web.git", exact: "0.0.11"),
1313
.package(url: "https://github.com/hummingbird-project/hummingbird.git", exact: "2.5.0"),
1414
.package(url: "https://github.com/pointfreeco/swift-case-paths.git", from: "1.0.0"),
1515
.package(url: "https://github.com/pointfreeco/swift-url-routing.git", from: "0.6.2"),

Sources/Pages/Components/HeaderView.swift

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ struct HeaderView: HTML {
1818
.inlineStyle("text-decoration", "none")
1919
// TODO: Add buttons to allow switching between code styling or plain text
2020

21-
CodeStyleSelector()
21+
CodeSelector()
2222
}
2323
.containerStyling()
2424
.inlineStyle("display", "flex")
@@ -31,21 +31,21 @@ struct HeaderView: HTML {
3131
}
3232
}
3333

34-
private struct CodeStyleSelector: VueComponent {
34+
private struct CodeSelector: VueComponent {
3535
@Reactive let visible = false
3636

3737
var body: some HTML {
3838
div {
39-
button {
39+
button(.v.on(.click, Expression(rawValue: "\($visible.name) = \(!$visible)"))) {
4040
code { "</>" }
4141
.inlineStyle("color", "#AAA")
4242
}
4343
.inlineStyle("font-weight", "bold")
4444
.inlineStyle("font-size", "0.7em")
4545
.inlineStyle("background", "unset")
46-
.inlineStyle("border", "1px solid #444")
47-
.inlineStyle("border-radius", "0.2rem")
48-
.inlineStyle("padding", "0.2rem 0.35rem")
46+
.inlineStyle("border", "1.16px solid #444")
47+
.inlineStyle("border-radius", "0.3rem")
48+
.inlineStyle("padding", "0.28rem 0.4rem")
4949

5050
ul(.v.show($visible)) {
5151
li { "Plain Text" }

Sources/Pages/Components/Page.swift

Lines changed: 89 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -18,85 +18,106 @@ extension Page {
1818
public var headers: HTTPFields { [.contentType: "text/html; charset=utf-8"] }
1919

2020
public static func _render<Output: HTMLByteStream>(
21-
_ document: consuming Self,
21+
_ document: consuming Self,
2222
into output: inout Output
2323
) {
2424
withDependencies {
2525
$0.ssg = .class
2626
} operation: {
27-
BaseLayout._render(
28-
BaseLayout(
29-
head: HTMLGroup {
30-
meta(.charset(.utf8))
31-
tag("title") { document.title }
32-
meta(.name("viewport"), .content("width=device-width, initial-scale=1.0"))
33-
style { HTMLRaw("/*! modern-normalize v3.0.1 | MIT License | https://github.com/sindresorhus/modern-normalize */*,::after,::before{box-sizing:border-box}html{font-family:system-ui,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji';line-height:1.15;-webkit-text-size-adjust:100%;tab-size:4}body{margin:0}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Consolas,'Liberation Mono',Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-color:currentcolor}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}legend{padding:0}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}") }
34-
style {
35-
HTMLRaw(
36-
"""
37-
@font-face {
38-
font-family: "CommitMono";
39-
src: url("https://raw.githubusercontent.com/eigilnikolajsen/commit-mono/ecd81cdbd7f7eb2acaaa2f2f7e1a585676f9beff/src/fonts/fontlab/CommitMonoV143-VF.woff2");
40-
font-style: normal;
41-
font-weight: 400;
42-
font-display: swap;
43-
}
44-
html {
45-
line-height: 1.5;
46-
}
47-
pre a {
48-
text-decoration: none;
49-
}
50-
h1, h2, h3, h4, h5, figure, p, ol, ul, pre {
51-
margin: 0;
52-
}
53-
ol[role="list"], ul[role="list"] {
54-
list-style: none;
55-
padding-inline: 0;
56-
}
57-
img, video {
58-
display: block;
59-
max-inline-size: 100%;
60-
}
61-
code {
62-
font-family: "CommitMono", monospace;
63-
font-feature-settings", "ss03", "ss04", "ss05";
64-
line-height: 1;
65-
}
66-
"""
27+
VueDocument._render(
28+
VueDocument(
29+
head: {
30+
meta(.charset(.utf8))
31+
tag("title") { document.title }
32+
meta(.name("viewport"), .content("width=device-width, initial-scale=1.0"))
33+
style {
34+
HTMLRaw(
35+
"/*! modern-normalize v3.0.1 | MIT License | https://github.com/sindresorhus/modern-normalize */*,::after,::before{box-sizing:border-box}html{font-family:system-ui,'Segoe UI',Roboto,Helvetica,Arial,sans-serif,'Apple Color Emoji','Segoe UI Emoji';line-height:1.15;-webkit-text-size-adjust:100%;tab-size:4}body{margin:0}b,strong{font-weight:bolder}code,kbd,pre,samp{font-family:ui-monospace,SFMono-Regular,Consolas,'Liberation Mono',Menlo,monospace;font-size:1em}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}table{border-color:currentcolor}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}legend{padding:0}progress{vertical-align:baseline}::-webkit-inner-spin-button,::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}summary{display:list-item}"
36+
)
37+
}
38+
style {
39+
HTMLRaw(
40+
"""
41+
@font-face {
42+
font-family: "CommitMono";
43+
src: url("https://raw.githubusercontent.com/eigilnikolajsen/commit-mono/ecd81cdbd7f7eb2acaaa2f2f7e1a585676f9beff/src/fonts/fontlab/CommitMonoV143-VF.woff2");
44+
font-style: normal;
45+
font-weight: 400;
46+
font-display: swap;
47+
}
48+
html {
49+
line-height: 1.5;
50+
}
51+
pre a {
52+
text-decoration: none;
53+
}
54+
h1, h2, h3, h4, h5, figure, p, ol, ul, pre {
55+
margin: 0;
56+
}
57+
ol[role="list"], ul[role="list"] {
58+
list-style: none;
59+
padding-inline: 0;
60+
}
61+
img, video {
62+
display: block;
63+
max-inline-size: 100%;
64+
}
65+
code {
66+
font-family: "CommitMono", monospace;
67+
font-feature-settings", "ss03", "ss04", "ss05";
68+
line-height: 1;
69+
}
70+
"""
71+
)
72+
}
73+
/// Xcode Styling
74+
style {
75+
HTMLRaw(".xml .hljs-meta{color:#6C7986}.hljs-comment,.hljs-quote{color:#6C7986}.hljs-tag,.hljs-attribute,.hljs-keyword,.hljs-selector-tag,.hljs-literal,.hljs-name{color:#FC5FA3}.hljs-variable,.hljs-template-variable{color:#FC5FA3}.hljs-code,.hljs-string,.hljs-meta-string{color:#FC6A5D}.hljs-regexp,.hljs-link{color:#5482FF}.hljs-title,.hljs-symbol,.hljs-bullet,.hljs-number{color:#41A1C0}.hljs-section,.hljs-meta{color:#FC5FA3}.hljs-class .hljs-title,.hljs-type,.hljs-built_in,.hljs-builtin-name,.hljs-params{color:#D0A8FF}.hljs-attr{color:#BF8555}.hljs-subst{color:#FFF}.hljs-formula{font-style:italic}.hljs-selector-id,.hljs-selector-class{color:#9b703f}.hljs-doctag,.hljs-strong{font-weight:bold}.hljs-emphasis{font-style:italic}")
76+
}
77+
script(
78+
.src("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"),
79+
.defer
6780
)
68-
}
69-
/// Xcode Styling
70-
style { HTMLRaw(".xml .hljs-meta{color:#6C7986}.hljs-comment,.hljs-quote{color:#6C7986}.hljs-tag,.hljs-attribute,.hljs-keyword,.hljs-selector-tag,.hljs-literal,.hljs-name{color:#FC5FA3}.hljs-variable,.hljs-template-variable{color:#FC5FA3}.hljs-code,.hljs-string,.hljs-meta-string{color:#FC6A5D}.hljs-regexp,.hljs-link{color:#5482FF}.hljs-title,.hljs-symbol,.hljs-bullet,.hljs-number{color:#41A1C0}.hljs-section,.hljs-meta{color:#FC5FA3}.hljs-class .hljs-title,.hljs-type,.hljs-built_in,.hljs-builtin-name,.hljs-params{color:#D0A8FF}.hljs-attr{color:#BF8555}.hljs-subst{color:#FFF}.hljs-formula{font-style:italic}.hljs-selector-id,.hljs-selector-class{color:#9b703f}.hljs-doctag,.hljs-strong{font-weight:bold}.hljs-emphasis{font-style:italic}") }
71-
script(.src("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/highlight.min.js"), .defer) {}
72-
script(.src("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/swift.min.js"), .defer) {}
73-
script(.src("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/rust.min.js"), .defer) {}
74-
script(.src("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/javascript.min.js"), .defer) {}
75-
script(.src("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/typescript.min.js"), .defer) {}
76-
script(.type(.module)) { HTMLRaw("hljs.highlightAll();") }
77-
78-
document.head
79-
},
80-
body: HTMLGroup {
81-
document.body
82-
.inlineStyle("background-color", "#1c1c1c")
83-
.inlineStyle("color", "#fafafa")
84-
.inlineStyle("font-optical-sizing", "auto")
85-
.inlineStyle("font-size", "0.7em")
86-
.inlineStyle("font-size", "0.8em", media: .minWidth(390))
87-
.inlineStyle("font-size", "0.9em", media: .minWidth(480))
81+
script(
82+
.src("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/swift.min.js"),
83+
.defer
84+
)
85+
script(
86+
.src("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/rust.min.js"),
87+
.defer
88+
)
89+
script(
90+
.src("https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/javascript.min.js"),
91+
.defer
92+
)
93+
script(
94+
.src(
95+
"https://cdnjs.cloudflare.com/ajax/libs/highlight.js/11.9.0/languages/typescript.min.js"
96+
),
97+
.defer
98+
)
99+
script(.type(.module)) { HTMLRaw("hljs.highlightAll();") }
88100

89-
VueScript()
90-
}
91-
.attribute("lang", value: document.lang)
92-
),
93-
into: &output
94-
)
101+
document.head
102+
},
103+
body: {
104+
document.body
105+
.inlineStyle("background-color", "#1c1c1c")
106+
.inlineStyle("color", "#fafafa")
107+
.inlineStyle("font-optical-sizing", "auto")
108+
.inlineStyle("font-size", "0.7em")
109+
.inlineStyle("font-size", "0.8em", media: .minWidth(390))
110+
.inlineStyle("font-size", "0.9em", media: .minWidth(480))
111+
.attribute("lang", value: document.lang)
112+
}
113+
),
114+
into: &output
115+
)
95116
}
96117
}
97118
}
98119

99120
private struct BaseLayout<Head: HTML, Body: HTML>: HTMLDocument {
100121
var head: Head
101122
var body: Body
102-
}
123+
}

Sources/Pages/HomePage.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -192,10 +192,10 @@ private struct PostsView: HTML {
192192
code(.class("hljs language-swift")) {
193193
"logs[\(self.number)]"
194194
}
195-
.inlineStyle("font-size", "0.75em")
196-
.inlineStyle("color", "#777")
197-
.inlineStyle("font-weight", "500")
198195
}
196+
.inlineStyle("font-size", "0.75em")
197+
.inlineStyle("color", "#777")
198+
.inlineStyle("font-weight", "500")
199199
}
200200
}
201201
.inlineStyle("display", "flex")

Sources/Pages/Utils/Page+ResponseGenerator.swift

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import HTML
22
import Hummingbird
3+
import AsyncAlgorithms
34

45
extension Page {
56
public consuming func response(
@@ -18,15 +19,16 @@ extension Page {
1819

1920
extension ResponseBodyWriter {
2021
fileprivate mutating func write(_ page: consuming some Page, chunkSize: Int = 1024) async throws {
21-
for await bytes in page.render(chunkSize: chunkSize) {
22-
try await self.write(bytes)
22+
for await buffer in page.render(chunkSize: chunkSize) {
23+
try await self.write(buffer)
2324
}
2425

2526
try await self.finish(nil)
2627
}
2728
}
2829

2930
extension HTML {
31+
/// Switch to a more performant byte streaming sequence
3032
fileprivate consuming func render(chunkSize: Int) -> AsyncStream<ByteBuffer> {
3133
AsyncStream { [self] continuation in
3234
var writer = AsyncHTMLWriter(continuation: continuation, chunkSize: chunkSize)

0 commit comments

Comments
 (0)