Skip to content

Commit

Permalink
Add Picture and Source. (#171)
Browse files Browse the repository at this point in the history
  • Loading branch information
jverkoey authored Aug 31, 2024
1 parent a41d40e commit 9046a19
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 5 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/package-test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ jobs:
runs-on: macos-latest
steps:
- name: Select Xcode
run: sudo xcode-select -s "/Applications/Xcode_16_beta_5.app"
run: sudo xcode-select -s "/Applications/Xcode_16.1_beta.app"
- name: Get swift version
run: swift --version
- uses: actions/checkout@v4
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/static.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
uses: actions/checkout@v4
- name: Set up Xcode
run: |
sudo xcode-select -s "/Applications/Xcode_16_beta_5.app"
sudo xcode-select -s "/Applications/Xcode_16.1_beta.app"
xcodebuild -version
- name: Run gendocs.sh script
run: ./gendocs.sh
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -137,8 +137,8 @@ provided below is an organized table of W3C HTML tags and their equivalent Slips

W3C tag | Slipstream view
:--------|:----------------
[`<picture>`](https://html.spec.whatwg.org/multipage/sections.html#the-picture-element) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/25)
[`<source>`](https://html.spec.whatwg.org/multipage/sections.html#the-source-element) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/25)
[`<picture>`](https://html.spec.whatwg.org/multipage/sections.html#the-picture-element) | ``Picture``
[`<source>`](https://html.spec.whatwg.org/multipage/sections.html#the-source-element) | ``Source``
[`<img>`](https://html.spec.whatwg.org/multipage/sections.html#the-img-element) | ``Image``
[`<iframe>`](https://html.spec.whatwg.org/multipage/sections.html#the-iframe-element) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/25)
[`<embed>`](https://html.spec.whatwg.org/multipage/sections.html#the-embed-element) | [Not implemented yet](https://github.com/jverkoey/slipstream/issues/25)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# ``Source``

## Topics

### Supporting types

- ``ColorScheme``
2 changes: 2 additions & 0 deletions Sources/Slipstream/Documentation.docc/W3C/W3CViews.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ The complete W3C HTML elements standard can be found [here](https://html.spec.wh

### Embedded content

- ``Picture``
- ``Source``
- ``Image``
- ``RawHTML``

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import SwiftSoup
/// - ``View/accessibilityLabel(_:)``
@available(iOS 17.0, macOS 14.0, *)
public struct Image: View {
/// Creates a Stylesheet view.
/// Creates an Image view.
///
/// - Parameters:
/// - url: The image will be loaded from this URL.
Expand Down
24 changes: 24 additions & 0 deletions Sources/Slipstream/W3C/Elements/EmbeddedContent/Picture.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import Foundation

import SwiftSoup

/// A container that provides multiple sources to its contained ``Image`` view.
///
/// Picture allow authors to declaratively control or give hints to the user agent about which
/// image resource to use, based on the screen pixel density, viewport size, image format,
/// and other factors
///
/// - SeeAlso: W3C [picture](https://html.spec.whatwg.org/multipage/embedded-content.html#the-picture-element) specification.
@available(iOS 17.0, macOS 14.0, *)
public struct Picture<Content>: W3CElement where Content: View {
@_documentation(visibility: private)
public let tagName: String = "picture"

@_documentation(visibility: private)
@ViewBuilder public let content: () -> Content

/// Creates a Picture view.
public init(@ViewBuilder content: @escaping () -> Content) {
self.content = content
}
}
47 changes: 47 additions & 0 deletions Sources/Slipstream/W3C/Elements/EmbeddedContent/Source.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import Foundation

import SwiftSoup

/// A media query representation of the user's selected color scheme.
@available(iOS 17.0, macOS 14.0, *)
public enum ColorScheme {
case light
case dark
}

/// A view that allows authors to specify multiple alternative source sets for ``Image``
/// views or multiple alternative media resources for media elements.
///
/// ``Source`` does not represent anything on its own.
///
/// - SeeAlso: W3C [source](https://html.spec.whatwg.org/multipage/embedded-content.html#the-source-element) specification.
@available(iOS 17.0, macOS 14.0, *)
public struct Source: View {
/// Creates a Source view.
///
/// - Parameters:
/// - url: The image will be loaded from this URL when the browser is using the given color scheme.
/// - colorScheme: The color scheme for which this image should be loaded.
public init(_ url: URL?, colorScheme: ColorScheme) {
self.url = url
self.colorScheme = colorScheme
}

@_documentation(visibility: private)
public func render(_ container: Element, environment: EnvironmentValues) throws {
guard let url else {
return
}
let element = try container.appendElement("source")
try element.attr("srcset", url.absoluteString)
switch colorScheme {
case .light:
try element.attr("media", "(prefers-color-scheme: light)")
case .dark:
try element.attr("media", "(prefers-color-scheme: dark)")
}
}

private let url: URL?
private let colorScheme: ColorScheme
}
10 changes: 10 additions & 0 deletions Tests/SlipstreamTests/W3C/PictureTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import Foundation
import Testing

import Slipstream

struct PictureTests {
@Test func emptyContent() throws {
try #expect(renderHTML(Picture { }) == "<picture></picture>")
}
}
15 changes: 15 additions & 0 deletions Tests/SlipstreamTests/W3C/SourceTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import Foundation
import Testing

import Slipstream

struct SourceTests {
@Test func nilURL() throws {
try #expect(renderHTML(Source(nil, colorScheme: .light)) == "")
}

@Test func colorSchemes() throws {
try #expect(renderHTML(Source(URL(string: "/logo.png"), colorScheme: .light)) == #"<source srcset="/logo.png" media="(prefers-color-scheme: light)" />"#)
try #expect(renderHTML(Source(URL(string: "/logo.png"), colorScheme: .dark)) == #"<source srcset="/logo.png" media="(prefers-color-scheme: dark)" />"#)
}
}

0 comments on commit 9046a19

Please sign in to comment.