From 40bef1c92913ae12e23245f8de2ddcd15b01cc42 Mon Sep 17 00:00:00 2001 From: Simon Whitty Date: Wed, 26 Aug 2026 08:25:12 +1000 Subject: [PATCH] viewBox now accepts comma delimited values --- DOM/Sources/Parser.XML.SVG.swift | 22 +++++++++++++++++++--- DOM/Tests/Parser.SVGTests.swift | 19 +++++++++++++++++++ Samples.bundle/spider.svg | 2 +- 3 files changed, 39 insertions(+), 4 deletions(-) diff --git a/DOM/Sources/Parser.XML.SVG.swift b/DOM/Sources/Parser.XML.SVG.swift index 910beb70..4d76207c 100644 --- a/DOM/Sources/Parser.XML.SVG.swift +++ b/DOM/Sources/Parser.XML.SVG.swift @@ -29,6 +29,8 @@ // 3. This notice may not be removed or altered from any source distribution. // +import Foundation + package extension XMLParser { func parseSVG(_ e: XML.Element) throws -> DOM.SVG { @@ -72,9 +74,9 @@ package extension XMLParser { guard let data = data else { return nil } var scanner = XMLParser.Scanner(text: data) - let x = try scanner.scanCoordinate() - let y = try scanner.scanCoordinate() - let width = try scanner.scanCoordinate() + let x = try scanner.scanViewBoxCoordinate() + let y = try scanner.scanViewBoxCoordinate() + let width = try scanner.scanViewBoxCoordinate() let height = try scanner.scanCoordinate() guard scanner.isEOF else { @@ -247,3 +249,17 @@ package extension XMLParser { return pattern } } + +private extension XMLParser.Scanner { + + mutating func scanViewBoxCoordinate() throws -> DOM.Coordinate { + let coordinate = try scanCoordinate() + _ = try? scanCharacter(matchingAny: .viewBoxSeparator) + return coordinate + } +} + +private extension Foundation.CharacterSet { + + static let viewBoxSeparator = Foundation.CharacterSet(charactersIn: ",") +} diff --git a/DOM/Tests/Parser.SVGTests.swift b/DOM/Tests/Parser.SVGTests.swift index 35774b22..13c017f9 100644 --- a/DOM/Tests/Parser.SVGTests.swift +++ b/DOM/Tests/Parser.SVGTests.swift @@ -199,6 +199,25 @@ struct ParserSVGTests { } } + @Test + func viewBoxWithCommaDelimiters() throws { + let parsed = try #require(try XMLParser().parseViewBox("0,0,150,50")) + #expect(parsed.x == 0) + #expect(parsed.y == 0) + #expect(parsed.width == 150) + #expect(parsed.height == 50) + } + + @Test + func invalidViewBoxWithCommaDelimiters() { + #expect(throws: (any Error).self) { + try XMLParser().parseViewBox("10,,,10,10,10") + } + #expect(throws: (any Error).self) { + try XMLParser().parseViewBox("10,10,10") + } + } + @Test func clipPath() throws { let node = XML.Element(name: "clipPath", attributes: ["id": "hello"]) diff --git a/Samples.bundle/spider.svg b/Samples.bundle/spider.svg index cbec5d68..c1178ccd 100644 --- a/Samples.bundle/spider.svg +++ b/Samples.bundle/spider.svg @@ -1,4 +1,4 @@ - +