From bc3f53b9ff0ac01aace52f75d8ea11f20dfe61f9 Mon Sep 17 00:00:00 2001 From: Carmi Weinzweig Date: Tue, 21 Feb 2023 12:11:29 -0800 Subject: [PATCH 1/5] Added `sizes`, `height` and `width` `Attributes` to the PictureSourceContext. --- Sources/Plot/API/HTMLAttributes.swift | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/Sources/Plot/API/HTMLAttributes.swift b/Sources/Plot/API/HTMLAttributes.swift index 9c9b8f6..79a5c19 100644 --- a/Sources/Plot/API/HTMLAttributes.swift +++ b/Sources/Plot/API/HTMLAttributes.swift @@ -261,6 +261,24 @@ public extension Attribute where Context == HTML.PictureSourceContext { static func type(_ type: String) -> Attribute { Attribute(name: "type", value: type) } + + /// A string with a media query describing which image from the `srcset` attribute should be used. + /// - parameter sizes: The sizes used for the of sources that this element should point to. + static func sizes(_ sizes: String) -> Attribute { + Attribute(name: "sizes", value: sizes) + } + + /// Assign an integer giving the intinsic height of the `srcset` image in pixels. + /// - parameter height: The height of the image in the source. + static func height(_ height: Int) -> Attribute { + Attribute(name: "height", value: String(height)) + } + + /// Assign an integer giving the intrinsic width of the `srcset` image in pixels. + /// - parameter width: The width of the image in the source. + static func width(_ width: Int) -> Attribute { + Attribute(name: "width", value: String(width)) + } } // MARK: - Forms, input and options From f322c98688ae452ef98540a8b34d4badf45adf35 Mon Sep 17 00:00:00 2001 From: Carmi Weinzweig Date: Tue, 21 Feb 2023 12:18:06 -0800 Subject: [PATCH 2/5] Added a `Picture` component for use with `Node.picture`. It creates a set of `.sources` using all the supplied `Attribute`s relying the behavior of `Attribute` to not render null strings and/or `.empty` nodes. I tried to use the `.if` syntax, but got a compiler error. I am leaving the commented code in case there is a better way to implement this. --- Sources/Plot/API/HTMLComponents.swift | 90 +++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) diff --git a/Sources/Plot/API/HTMLComponents.swift b/Sources/Plot/API/HTMLComponents.swift index 87ef29e..3c72600 100644 --- a/Sources/Plot/API/HTMLComponents.swift +++ b/Sources/Plot/API/HTMLComponents.swift @@ -579,6 +579,96 @@ extension List: ComponentContainer where Items == ComponentGroup { } } +// Component used to render an `` element for responsive image support. +public struct Picture: Component { + /// Type used to define an Picture source, which points to an image file (or set of them) and associated media queries (and other paramaters). + public struct Source { + /// image or images to use - can have parameters + public var srcset: String + /// sizes for the `srcset` to use - can have parameters + public var sizes: String? + /// Media querry (optional) + public var media: String? + /// Media type (optional) + public var type: String? + /// Intrinsic height of image in pixels - integer with no unit (optional) + public var height: Int? + /// Intrinsic width of image in pixels - integer with no unit (optional) + public var width: Int? + + /// Initialize a new source. + /// - parameter srcset: The set of sources to which this element should point. + /// - parameter sizes: Comma separated list of media queries for the `srcset` images. + /// - parameter media: Media query for the resources intended media. + /// - parameter type: MIME type of the image, with optional `codecs` paramater. + /// - parameter height: Intrinsic height of image in pixels - integer with no unit. + /// - parameter width: Intrinsic width of image in pixels - integer with no unit. + + internal init(srcset: String, sizes: String? = nil, media: String? = nil, type: String? = nil, height: Int? = nil, width: Int? = nil) { + self.srcset = srcset + self.sizes = sizes + self.media = media + self.type = type + self.height = height + self.width = width + } + } + + /// Initialize a `Picture` component with multiple `source` elements. + /// Image to use as fallback. + public var image: Plot.Image + /// A set of `source` elments from which a user agent will chose based on its requirements. + public var sources: [Source]? + + internal init(image: Plot.Image, sources: [Picture.Source]? = nil) { + self.image = image + self.sources = sources + } + + /// Initialize a `Picture` component with a single `source` element. + /// Image to use as fallback. + /// A set of `source` elments from which a user agent will chose based on its requirements. + public init(image: Plot.Image, source: Source) { + self.init(image: image, sources: [source]) + } + + @ComponentBuilder + public var body: Component { + if let sources { + Node.picture( + .forEach(sources) { source in + // This creates a source that has null strings for those strings that have `nil` values, and `.empty` nodes for those `Integer`s with nil values. + // Null strings are not rendered, so nothing is generated for them. + + .source( + .srcset(source.srcset), + .media(source.media ?? ""), + .type(source.type ?? ""), + .sizes(source.sizes ?? ""), + source.height == nil ? .empty : .height(source.height!), + source.width == nil ? .empty : .width(source.width!) + ) + // Tried to use `.if` but it says it takes too long for the compiler to figure out the types. + // leaving it here to see if there is a better solution betwen this option and the one above. + +// .source( +// .srcset(source.srcset), +// .media(source.media ?? ""), +// .type(source.type ?? ""), +// .sizes(source.sizes ?? ""), +// .if(source.height != nil, .height(source.height!)), .if(source.width != nil, .width(source.width!)) +// ) + }, + .component(image) + ) + } + else { + Node.picture(.component(image)) + } + } +} + + /// Convenience type that can be used to create an `Input` component /// for submitting an HTML form. public struct SubmitButton: Component { From 6da39268b2b91311cf7ca0130e13cc71bd11c5e8 Mon Sep 17 00:00:00 2001 From: Carmi Weinzweig Date: Fri, 24 Feb 2023 14:38:39 -0800 Subject: [PATCH 3/5] Switched to old syntax for unwrapping optionals. --- Sources/Plot/API/HTMLComponents.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/Plot/API/HTMLComponents.swift b/Sources/Plot/API/HTMLComponents.swift index 3c72600..1bafbc4 100644 --- a/Sources/Plot/API/HTMLComponents.swift +++ b/Sources/Plot/API/HTMLComponents.swift @@ -634,7 +634,7 @@ public struct Picture: Component { @ComponentBuilder public var body: Component { - if let sources { + if let sources = sources { Node.picture( .forEach(sources) { source in // This creates a source that has null strings for those strings that have `nil` values, and `.empty` nodes for those `Integer`s with nil values. From efa1f66d9686faf506e45dbf6c3661a603d539c8 Mon Sep 17 00:00:00 2001 From: Carmi Weinzweig Date: Sat, 1 Apr 2023 10:34:48 -0700 Subject: [PATCH 4/5] Corrected several typos. Changed Plot.Image to Image (this was developed in a separate repo and then pulled into this fork, it was needed there, but is not needed here). Replaced two ternary ops with `.unwrap` in the `Picture` `body`. --- Sources/Plot/API/HTMLComponents.swift | 86 ++++++++++----------------- 1 file changed, 31 insertions(+), 55 deletions(-) diff --git a/Sources/Plot/API/HTMLComponents.swift b/Sources/Plot/API/HTMLComponents.swift index 1bafbc4..a4bd727 100644 --- a/Sources/Plot/API/HTMLComponents.swift +++ b/Sources/Plot/API/HTMLComponents.swift @@ -579,48 +579,16 @@ extension List: ComponentContainer where Items == ComponentGroup { } } -// Component used to render an `` element for responsive image support. +// Component used to render a `` element for responsive image support. public struct Picture: Component { - /// Type used to define an Picture source, which points to an image file (or set of them) and associated media queries (and other paramaters). - public struct Source { - /// image or images to use - can have parameters - public var srcset: String - /// sizes for the `srcset` to use - can have parameters - public var sizes: String? - /// Media querry (optional) - public var media: String? - /// Media type (optional) - public var type: String? - /// Intrinsic height of image in pixels - integer with no unit (optional) - public var height: Int? - /// Intrinsic width of image in pixels - integer with no unit (optional) - public var width: Int? - /// Initialize a new source. - /// - parameter srcset: The set of sources to which this element should point. - /// - parameter sizes: Comma separated list of media queries for the `srcset` images. - /// - parameter media: Media query for the resources intended media. - /// - parameter type: MIME type of the image, with optional `codecs` paramater. - /// - parameter height: Intrinsic height of image in pixels - integer with no unit. - /// - parameter width: Intrinsic width of image in pixels - integer with no unit. - - internal init(srcset: String, sizes: String? = nil, media: String? = nil, type: String? = nil, height: Int? = nil, width: Int? = nil) { - self.srcset = srcset - self.sizes = sizes - self.media = media - self.type = type - self.height = height - self.width = width - } - } - - /// Initialize a `Picture` component with multiple `source` elements. /// Image to use as fallback. - public var image: Plot.Image + public var image: Image /// A set of `source` elments from which a user agent will chose based on its requirements. - public var sources: [Source]? + public var sources: [Source] - internal init(image: Plot.Image, sources: [Picture.Source]? = nil) { + /// Initialize a `Picture` component with multiple `source` elements. + internal init(image: Image, sources: [Picture.Source] = []) { self.image = image self.sources = sources } @@ -634,40 +602,48 @@ public struct Picture: Component { @ComponentBuilder public var body: Component { - if let sources = sources { +// if let sources = sources { Node.picture( .forEach(sources) { source in // This creates a source that has null strings for those strings that have `nil` values, and `.empty` nodes for those `Integer`s with nil values. // Null strings are not rendered, so nothing is generated for them. .source( - .srcset(source.srcset), + .srcset(source.sourceSet), .media(source.media ?? ""), .type(source.type ?? ""), .sizes(source.sizes ?? ""), - source.height == nil ? .empty : .height(source.height!), - source.width == nil ? .empty : .width(source.width!) + .unwrap(source.height, Attribute.height), + .unwrap(source.width, Attribute.width) ) - // Tried to use `.if` but it says it takes too long for the compiler to figure out the types. - // leaving it here to see if there is a better solution betwen this option and the one above. - -// .source( -// .srcset(source.srcset), -// .media(source.media ?? ""), -// .type(source.type ?? ""), -// .sizes(source.sizes ?? ""), -// .if(source.height != nil, .height(source.height!)), .if(source.width != nil, .width(source.width!)) -// ) }, .component(image) ) } - else { - Node.picture(.component(image)) - } - } +// else { +// Node.picture(.component(image)) +// } +// } } +public extension Picture { + /// Type used to define a Picture source, which points to an image file (or set of them) and associated media queries (and other paramaters). + struct Source { + /// Image or images to use - can have parameters + public var sourceSet: String + /// Sizes for the `srcset` to use - can have parameters + public var sizes: String? + /// Media querry (optional) + public var media: String? + /// Media type (optional) + public var type: String? + /// Intrinsic height of image in pixels - integer with no unit (optional) + public var height: Int? + /// Intrinsic width of image in pixels - integer with no unit (optional) + public var width: Int? + } + +} /// Convenience type that can be used to create an `Input` component /// for submitting an HTML form. From 4a0924a1fb2b5a871a307d4d2d52923c0affb1aa Mon Sep 17 00:00:00 2001 From: Carmi Weinzweig Date: Sun, 2 Apr 2023 14:32:57 -0700 Subject: [PATCH 5/5] Removed unused code that had been commented out. Changed one final `Plot.Image` to `Image` Cleaned up some formatting and black lines. :-) --- Sources/Plot/API/HTMLComponents.swift | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/Sources/Plot/API/HTMLComponents.swift b/Sources/Plot/API/HTMLComponents.swift index a4bd727..5dadc3c 100644 --- a/Sources/Plot/API/HTMLComponents.swift +++ b/Sources/Plot/API/HTMLComponents.swift @@ -578,7 +578,6 @@ extension List: ComponentContainer where Items == ComponentGroup { self.init(content()) { $0 } } } - // Component used to render a `` element for responsive image support. public struct Picture: Component { @@ -596,18 +595,13 @@ public struct Picture: Component { /// Initialize a `Picture` component with a single `source` element. /// Image to use as fallback. /// A set of `source` elments from which a user agent will chose based on its requirements. - public init(image: Plot.Image, source: Source) { + public init(image: Image, source: Source) { self.init(image: image, sources: [source]) } - @ComponentBuilder public var body: Component { -// if let sources = sources { Node.picture( .forEach(sources) { source in - // This creates a source that has null strings for those strings that have `nil` values, and `.empty` nodes for those `Integer`s with nil values. - // Null strings are not rendered, so nothing is generated for them. - .source( .srcset(source.sourceSet), .media(source.media ?? ""), @@ -620,10 +614,6 @@ public struct Picture: Component { .component(image) ) } -// else { -// Node.picture(.component(image)) -// } -// } } public extension Picture {