Skip to content

Commit 9e0c094

Browse files
committed
New media query type
1 parent 219d5fd commit 9e0c094

File tree

10 files changed

+116
-27
lines changed

10 files changed

+116
-27
lines changed

Sources/SwiftHtml/MediaQuery.swift

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
//
2+
// MediaQuery.swift
3+
// SwiftHtml
4+
//
5+
// Created by Tibor Bodecs on 2022. 01. 24..
6+
//
7+
8+
public struct MediaQuery {
9+
10+
public enum Orientation: String {
11+
case portrait
12+
case landscape
13+
}
14+
15+
public enum ColorScheme: String {
16+
case light
17+
case dark
18+
}
19+
20+
var value: String
21+
22+
}
23+
24+
public extension MediaQuery {
25+
26+
static let screen = MediaQuery(value: "screen")
27+
28+
static func deviceWidth(px: Int) -> MediaQuery {
29+
.init(value: "(device-width: \(px)px)")
30+
}
31+
32+
static func deviceHeight(px: Int) -> MediaQuery {
33+
.init(value: "(device-height: \(px)px)")
34+
}
35+
36+
static func webkitDevicePixelRatio(_ value: Int) -> MediaQuery {
37+
.init(value: "(-webkit-device-pixel-ratio: \(value))")
38+
}
39+
40+
static func orientation(_ value: Orientation) -> MediaQuery {
41+
.init(value: "(orientation: \(value.rawValue))")
42+
}
43+
44+
static func prefersColorScheme(_ value: ColorScheme) -> MediaQuery {
45+
.init(value: "(prefers-color-scheme: \(value.rawValue))")
46+
}
47+
}

Sources/SwiftHtml/Tags/A.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,10 @@ public extension A {
7777
attribute("media", value)
7878
}
7979

80+
func media(_ queries: [MediaQuery]) -> Self {
81+
return media(queries.map(\.value).joined(separator: " and "))
82+
}
83+
8084
/// Specifies a space-separated list of URLs to which, when the link is followed, post requests with the body ping will be sent by the browser (in the background).
8185
///
8286
/// Typically used for tracking.

Sources/SwiftHtml/Tags/Area.swift

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -54,60 +54,65 @@ open class Area: Tag {
5454
public init() {
5555
super.init(Node(type: .empty, name: "area"))
5656
}
57-
57+
}
58+
59+
public extension Area {
5860
/// Specifies an alternate text for the area. Required if the href attribute is present
59-
public func alt(_ value: String) -> Self {
61+
func alt(_ value: String) -> Self {
6062
attribute("alt", value)
6163
}
6264

6365
/// Specifies the coordinates of the area
64-
public func coords(_ values: Double...) -> Self {
66+
func coords(_ values: Double...) -> Self {
6567
attribute("coords", values.map {String($0) }.joined(separator: ","))
6668
}
6769

6870
/// Specifies that the target will be downloaded when a user clicks on the hyperlink
69-
public func download(_ value: String) -> Self {
71+
func download(_ value: String) -> Self {
7072
attribute("download", value)
7173
}
7274

7375
/// Specifies the hyperlink target for the area
74-
public func href(_ value: String) -> Self {
76+
func href(_ value: String) -> Self {
7577
attribute("href", value)
7678
}
7779

7880
/// Specifies the language of the target URL
79-
public func hreflang(_ value: String) -> Self {
81+
func hreflang(_ value: String) -> Self {
8082
attribute("hreflang", value)
8183
}
8284

8385
/// Specifies what media/device the target URL is optimized for
84-
public func media(_ value: String) -> Self {
86+
func media(_ value: String) -> Self {
8587
attribute("media", value)
8688
}
8789

90+
func media(_ queries: [MediaQuery]) -> Self {
91+
return media(queries.map(\.value).joined(separator: " and "))
92+
}
93+
8894
/// Specifies which referrer information to send with the link
89-
public func refererPolicy(_ value: RefererPolicy = .origin) -> Self {
95+
func refererPolicy(_ value: RefererPolicy = .origin) -> Self {
9096
attribute("referrerpolicy", value.rawValue)
9197
}
9298

9399
/// Specifies the relationship between the current document and the target URL
94-
public func rel(_ value: Rel) -> Self {
100+
func rel(_ value: Rel) -> Self {
95101
attribute("rel", value.rawValue)
96102
}
97103

98104
/// Specifies the shape of the area
99-
public func shape(_ value: Shape) -> Self {
105+
func shape(_ value: Shape) -> Self {
100106
attribute("shape", value.rawValue)
101107
}
102108

103109
/// Specifies where to open the target URL
104-
public func target(_ value: TargetFrame) -> Self {
110+
func target(_ value: TargetFrame) -> Self {
105111
attribute("target", value.rawValue)
106112
}
107113

108114
/// Specifies the media type of the target URL
109-
public func type(_ value: String) -> Self {
115+
func type(_ value: String) -> Self {
110116
attribute("type", value)
111117
}
112118
}
113-

Sources/SwiftHtml/Tags/Link.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,10 @@ public extension Link {
9393
attribute("media", value)
9494
}
9595

96+
func media(_ queries: [MediaQuery]) -> Self {
97+
return media(queries.map(\.value).joined(separator: " and "))
98+
}
99+
96100
/// Specifies which referrer to use when fetching the resource
97101
func refererPolicy(_ value: RefererPolicy = .origin) -> Self {
98102
attribute("referrerpolicy", value.rawValue)
@@ -122,4 +126,7 @@ public extension Link {
122126
func type(_ value: String) -> Self {
123127
attribute("type", value)
124128
}
129+
130+
125131
}
132+

Sources/SwiftHtml/Tags/Meta.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,7 @@ public extension Meta {
8787
attribute("media", value)
8888
}
8989

90-
func mediaPrefersColorSchemeLight() -> Self {
91-
media("(prefers-color-scheme: light)")
92-
}
93-
94-
func mediaPrefersColorSchemeDark() -> Self {
95-
media("(prefers-color-scheme: dark)")
90+
func media(_ queries: [MediaQuery]) -> Self {
91+
return media(queries.map(\.value).joined(separator: " and "))
9692
}
9793
}

Sources/SwiftHtml/Tags/Source.swift

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,8 @@ public extension Source {
2424
attribute("media", value)
2525
}
2626

27-
func mediaPrefersColorSchemeLight() -> Self {
28-
media("(prefers-color-scheme: light)")
29-
}
30-
31-
func mediaPrefersColorSchemeDark() -> Self {
32-
media("(prefers-color-scheme: dark)")
27+
func media(_ queries: [MediaQuery]) -> Self {
28+
return media(queries.map(\.value).joined(separator: " and "))
3329
}
3430

3531
/// Specifies image sizes for different page layouts

Sources/SwiftHtml/Tags/Style.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,10 @@ public extension Style {
2222
func media(_ value: String) -> Self {
2323
attribute("media", value)
2424
}
25+
26+
func media(_ queries: [MediaQuery]) -> Self {
27+
return media(queries.map(\.value).joined(separator: " and "))
28+
}
2529

2630
/// Specifies the media type (text/css) of the `<style>` tag
2731
func css() -> Self {
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
//
2+
// File.swift
3+
//
4+
//
5+
// Created by Tibor Bodecs on 2022. 01. 24..
6+
//
7+
8+
import XCTest
9+
@testable import SwiftHtml
10+
11+
final class LinkTagTests: XCTestCase {
12+
13+
func testMediaQuery() {
14+
let doc = Document {
15+
Link(rel: .appleTouchStartupImage)
16+
.media([
17+
.screen,
18+
.deviceWidth(px: 320),
19+
.deviceHeight(px: 568),
20+
.webkitDevicePixelRatio(2),
21+
.orientation(.portrait)
22+
])
23+
.href("/img/apple/splash/1136x640.png")
24+
}
25+
let html = DocumentRenderer(minify: true).render(doc)
26+
XCTAssertEqual(#"<link rel="apple-touch-startup-image" media="screen and (device-width: 320px) and (device-height: 568px) and (-webkit-device-pixel-ratio: 2) and (orientation: portrait)" href="/img/apple/splash/1136x640.png">"#, html)
27+
}
28+
29+
30+
}

Tests/SwiftHtmlTests/Tags/MetaTagTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ final class MetaTagTests: XCTestCase {
2525
Meta()
2626
.name(.themeColor)
2727
.content("#fff")
28-
.mediaPrefersColorSchemeLight()
28+
.media([.prefersColorScheme(.light)])
2929
}
3030
let html = DocumentRenderer(minify: true).render(doc)
3131
XCTAssertEqual(##"<meta name="theme-color" content="#fff" media="(prefers-color-scheme: light)">"##, html)

Tests/SwiftHtmlTests/Tags/SourceTagTests.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ final class SourceTagTests: XCTestCase {
1515
let doc = Document {
1616
Source()
1717
.srcset("img.png")
18-
.mediaPrefersColorSchemeDark()
18+
.media([.prefersColorScheme(.dark)])
1919
}
2020
let html = DocumentRenderer(minify: true).render(doc)
2121
XCTAssertEqual(#"<source srcset="img.png" media="(prefers-color-scheme: dark)">"#, html)

0 commit comments

Comments
 (0)