import Foundation /** An element showing a selection of images one by one using navigation buttons. */ struct ImageGallery: HtmlProducer { /// The unique id to distinguish different galleries in HTML and JavaScript let id: String /// The images to display let images: [ImageSet] let standalone: Bool /// A version of the id that is safe to use in HTML and JavaScript private var htmlSafeId: String { ImageGallery.htmlSafe(id) } init(id: String, images: [ImageSet], standalone: Bool = false) { self.id = id self.images = images self.standalone = standalone } func populate(_ result: inout String) { guard !images.isEmpty else { return } result += "
" let needsPagination = images.count > 1 for image in images { let sizeText = image.image.getImageDimensions().map { " style='aspect-ratio: \(Int($0.width)) / \(Int($0.height))'"} result += "
" result += image.content if needsPagination { result += "
" } result += "
" // Close swiper-slide } result += "
" // Close swiper-wrapper if needsPagination { result += "
" result += "
" result += "
" } result += "
" // Close swiper } private static func htmlSafe(_ id: String) -> String { id.replacingOccurrences(of: "-", with: "_") } var javascriptInit: String { ImageGallery.swiperInit(id: id) } var standaloneFooter: String { "" } static func combinedFootor(ids: [String]) -> String { var result = ["") return result.joined(separator: "\n") } private static func swiperInit(id: String) -> String { let id = htmlSafe(id) return """ var swiper_\(id) = new Swiper("#\(id)", { loop: true, lazy: { loadPrevNext: false, }, slidesPerView: 1, spaceBetween: 30, centeredSlides: true, keyboard: { enabled: true }, pagination: { el: "#\(id) .swiper-pagination", clickable: true }, navigation: { nextEl: "#\(id) .swiper-button-next", prevEl: "#\(id) .swiper-button-prev" } }); """ } }