Skip to content

Commit e919e51

Browse files
authored
Upgrade the package (#122)
* Add the namespace attribute for the vector element * Add tests for the vector attributes * Revise some of the vector attributes * Revise the converter * Remove the toggle component * Revise the link component * Revise and improve the css It's better to use logical properties for control the layout. Also, a different color scheme depending on the users default appearance. * Add a custom select * Add the points attribute for the vector elements polygon and polyline * Add a custom datepicker * Add the javascript for the dropdown * Add the slot element for web component technology * Add the shadow root mode attribute for the template element * Add a css minifier * Add a javascript minifier * Revise the css minifier and add it as an internal target As a target it becomes testable. * Combine the tokenizer all together into one minifier * Add some minification tests and also revise the minifier * Revise the javascript tokenizer and minifier * Revise the stylesheet tokenizer and minifier * Revise the minifier and clean up the stylesheets and javascript files * Add the minifier to the deploy command * Fix some grammar for the javascript tokenizer * Change the dark mode behaviour * Fix the tokenizing of an attribute selector * Fix the tokenizing of a comma character * Add css resets * Rework all of the css * Fix failing tests * Fix the minification of arguments in a css function * Fix the minification of a css selector on top layer * Fix the minification of a string value * Fix the minification of a selector * Separate the javascript for the interactions The javascript for the interactions needs to be declared in an other way, therefore it should be its own file, when it gets bundled. * Improve the property and selector distinction * Revise some components css and js
1 parent b160413 commit e919e51

File tree

89 files changed

+7649
-2287
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+7649
-2287
lines changed

Package.swift

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,10 @@ let package = Package(
5656
.product(name: "Vapor", package: "vapor"),
5757
]
5858
),
59+
.target(
60+
name: "Minifier",
61+
path: "Sources/Utilities"
62+
),
5963
.testTarget(
6064
name: "HTMLKitTests",
6165
dependencies: [
@@ -92,6 +96,12 @@ let package = Package(
9296
.copy("Localization")
9397
]
9498
),
99+
.testTarget(
100+
name: "UtilitiesTests",
101+
dependencies: [
102+
.target(name: "Minifier"),
103+
]
104+
),
95105
.executableTarget(
96106
name: "ConvertCommand",
97107
dependencies: [
@@ -102,7 +112,8 @@ let package = Package(
102112
.executableTarget(
103113
name: "DeployCommand",
104114
dependencies: [
105-
.target(name: "HTMLKitComponents")
115+
.target(name: "HTMLKitComponents"),
116+
.target(name: "Minifier")
106117
],
107118
path: "Sources/Commands/Components"
108119
),

Sources/Commands/Components/DeployCommand.swift

Lines changed: 79 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,15 @@
11
import Foundation
2+
import Minifier
23

34
@main
45
internal struct DeployCommand {
56

7+
internal enum BundleOption {
8+
9+
case minified
10+
case detailed
11+
}
12+
613
private static var sourcePath: String {
714
return CommandLine.arguments[1]
815
}
@@ -22,23 +29,30 @@ internal struct DeployCommand {
2229

2330
} else {
2431

25-
try compose(source: sourcePath + "/Resources/css/", to: targetPath + "/htmlkit/", with: "all.css")
32+
try bundle(css: sourcePath + "/Resources/css/", to: targetPath + "/htmlkit/", with: "all.css")
2633

27-
try compose(source: sourcePath + "/Resources/js/", to: targetPath + "/htmlkit/", with: "all.js")
34+
try bundle(js: sourcePath + "/Resources/js/components/", to: targetPath + "/htmlkit/", with: "all.js")
35+
36+
try bundle(js: sourcePath + "/Resources/js/interactions/", to: targetPath + "/htmlkit/", with: "query.js")
2837

2938
exit(0)
3039
}
3140
}
3241

3342
/// Iterates through the directory and collects data to create a single file
34-
private static func compose(source: String, to target: String, with filename: String) throws {
43+
private static func bundle(css source: String, to target: String, with filename: String, option: BundleOption = .minified) throws {
44+
45+
let template = """
46+
@charset "utf-8";
47+
/* Copyright (c) 2019 - 2023 Vapor Community - Licensed under MIT (https://github.com/vapor-community/HTMLKit/blob/main/LICENSE) */
48+
"""
3549

3650
if !manager.fileExists(atPath: target) {
3751
try manager.createDirectory(atPath: target, withIntermediateDirectories: true)
3852
}
3953

4054
if !manager.fileExists(atPath: target + filename) {
41-
manager.createFile(atPath: target + filename, contents: nil)
55+
manager.createFile(atPath: target + filename, contents: template.data(using: .utf8))
4256
}
4357

4458
if let enumerator = manager.enumerator(at: URL(fileURLWithPath: source), includingPropertiesForKeys: nil, options: [.skipsHiddenFiles]) {
@@ -56,7 +70,67 @@ internal struct DeployCommand {
5670

5771
handle.seekToEndOfFile()
5872

59-
handle.write(try Data(contentsOf: path))
73+
if case .minified = option {
74+
75+
let minifier = Minifier(compression: [.stripComments, .removeWhitespaces])
76+
77+
if let data = minifier.minify(css: try String(contentsOf: path)).data(using: .utf8) {
78+
handle.write(data)
79+
}
80+
81+
} else {
82+
handle.write(try Data(contentsOf: path))
83+
}
84+
85+
handle.closeFile()
86+
}
87+
}
88+
}
89+
}
90+
}
91+
}
92+
93+
/// Iterates through the directory and collects data to create a single file
94+
private static func bundle(js source: String, to target: String, with filename: String, option: BundleOption = .minified) throws {
95+
96+
let template = """
97+
/* Copyright (c) 2019 - 2023 Vapor Community - Licensed under MIT (https://github.com/vapor-community/HTMLKit/blob/main/LICENSE) */
98+
"""
99+
100+
if !manager.fileExists(atPath: target) {
101+
try manager.createDirectory(atPath: target, withIntermediateDirectories: true)
102+
}
103+
104+
if !manager.fileExists(atPath: target + filename) {
105+
manager.createFile(atPath: target + filename, contents: template.data(using: .utf8))
106+
}
107+
108+
if let enumerator = manager.enumerator(at: URL(fileURLWithPath: source), includingPropertiesForKeys: nil, options: [.skipsHiddenFiles]) {
109+
110+
for case let path as URL in enumerator {
111+
112+
if !path.hasDirectoryPath {
113+
114+
if !path.isFileURL {
115+
enumerator.skipDescendants()
116+
117+
} else {
118+
119+
if let handle = FileHandle(forWritingAtPath: target + filename) {
120+
121+
handle.seekToEndOfFile()
122+
123+
if case .minified = option {
124+
125+
let minifier = Minifier(compression: [.stripComments, .removeWhitespaces])
126+
127+
if let data = minifier.minify(js: try String(contentsOf: path)).data(using: .utf8) {
128+
handle.write(data)
129+
}
130+
131+
} else {
132+
handle.write(try Data(contentsOf: path))
133+
}
60134

61135
handle.closeFile()
62136
}

Sources/HTMLKit/Abstraction/Attributes/BasicAttributes.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2622,3 +2622,21 @@ extension SelectedAttribute where Self: EmptyNode {
26222622
return self.mutate(key: "selected", value: value)
26232623
}
26242624
}
2625+
2626+
/// The protocol provides the element with the shadowrootmode handler.
2627+
public protocol ShadowRootModeAttribute: Attribute {
2628+
2629+
/// The function represents the html-attribute 'shadowrootmode'.
2630+
///
2631+
/// ```html
2632+
/// <tag shadowrootmode="" />
2633+
/// ```
2634+
func shadowRootMode(_ value: Values.Shadow.Mode) -> Self
2635+
}
2636+
2637+
extension ShadowRootModeAttribute where Self: ContentNode {
2638+
2639+
internal func mutate(shadowrootmode value: String) -> Self {
2640+
return self.mutate(key: "shadowrootmode", value: value)
2641+
}
2642+
}

Sources/HTMLKit/Abstraction/Attributes/VectorAttributes.swift

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -182,24 +182,24 @@ public protocol PositionPointAttribute: Attribute {
182182
/// ```html
183183
/// <tag x="" y="" />
184184
/// ```
185-
func positionPoint(_ point: Geometrics.Point) -> Self
185+
func positionPoint(_ point: (Int, Int)) -> Self
186186
}
187187

188188
extension PositionPointAttribute where Self: ContentNode {
189189

190-
internal func mutate(radius: Geometrics.Point) -> Self {
190+
internal func mutate(positionpoint: (Int, Int)) -> Self {
191191

192192
guard var attributes = self.attributes else {
193193

194194
var attributes = OrderedDictionary<String, Any>()
195-
attributes["x"] = radius.x
196-
attributes["y"] = radius.y
195+
attributes["x"] = positionpoint.0
196+
attributes["y"] = positionpoint.1
197197

198198
return .init(attributes: attributes, content: content)
199199
}
200200

201-
attributes["x"] = radius.x
202-
attributes["y"] = radius.y
201+
attributes["x"] = positionpoint.0
202+
attributes["y"] = positionpoint.1
203203

204204
return .init(attributes: attributes, content: content)
205205
}
@@ -213,24 +213,24 @@ public protocol RadiusPointAttribute: Attribute {
213213
/// ```html
214214
/// <tag rx="" ry="" />
215215
/// ```
216-
func radiusPoint(_ point: Geometrics.Point) -> Self
216+
func radiusPoint(_ point: (Int, Int)) -> Self
217217
}
218218

219219
extension RadiusPointAttribute where Self: ContentNode {
220220

221-
internal func mutate(radius: Geometrics.Point) -> Self {
221+
internal func mutate(radiuspoint: (Int, Int)) -> Self {
222222

223223
guard var attributes = self.attributes else {
224224

225225
var attributes = OrderedDictionary<String, Any>()
226-
attributes["rx"] = radius.x
227-
attributes["ry"] = radius.y
226+
attributes["rx"] = radiuspoint.0
227+
attributes["ry"] = radiuspoint.1
228228

229229
return .init(attributes: attributes, content: content)
230230
}
231231

232-
attributes["rx"] = radius.x
233-
attributes["ry"] = radius.y
232+
attributes["rx"] = radiuspoint.0
233+
attributes["ry"] = radiuspoint.1
234234

235235
return .init(attributes: attributes, content: content)
236236
}
@@ -244,24 +244,24 @@ public protocol CenterPointAttribute: Attribute {
244244
/// ```html
245245
/// <tag cx="" cy="" />
246246
/// ```
247-
func centerPoint(_ point: Geometrics.Point) -> Self
247+
func centerPoint(_ point: (Int, Int)) -> Self
248248
}
249249

250250
extension CenterPointAttribute where Self: ContentNode {
251251

252-
internal func mutate(centerpoint: Geometrics.Point) -> Self {
252+
internal func mutate(centerpoint: (Int, Int)) -> Self {
253253

254254
guard var attributes = self.attributes else {
255255

256256
var attributes = OrderedDictionary<String, Any>()
257-
attributes["cx"] = centerpoint.x
258-
attributes["cy"] = centerpoint.y
257+
attributes["cx"] = centerpoint.0
258+
attributes["cy"] = centerpoint.1
259259

260260
return .init(attributes: attributes, content: content)
261261
}
262262

263-
attributes["cx"] = centerpoint.x
264-
attributes["cy"] = centerpoint.y
263+
attributes["cx"] = centerpoint.0
264+
attributes["cy"] = centerpoint.1
265265

266266
return .init(attributes: attributes, content: content)
267267
}
@@ -284,3 +284,39 @@ extension ViewBoxAttribute where Self: ContentNode {
284284
return self.mutate(key: "viewbox", value: value)
285285
}
286286
}
287+
288+
/// The protocol provides the element with the viewbox handler.
289+
public protocol NamespaceAttribute: Attribute {
290+
291+
/// The function represents the html-attribute 'viewbox'.
292+
///
293+
/// ```html
294+
/// <tag viewbox="" />
295+
/// ```
296+
func namespace(_ value: String) -> Self
297+
}
298+
299+
extension NamespaceAttribute where Self: ContentNode {
300+
301+
internal func mutate(namespace value: String) -> Self {
302+
return self.mutate(key: "xmlns", value: value)
303+
}
304+
}
305+
306+
/// The protocol provides the element with the viewbox handler.
307+
public protocol PointsAttribute: Attribute {
308+
309+
/// The function represents the html-attribute 'viewbox'.
310+
///
311+
/// ```html
312+
/// <tag viewbox="" />
313+
/// ```
314+
func points(_ value: String) -> Self
315+
}
316+
317+
extension PointsAttribute where Self: ContentNode {
318+
319+
internal func mutate(points value: String) -> Self {
320+
return self.mutate(key: "points", value: value)
321+
}
322+
}

0 commit comments

Comments
 (0)