Skip to content

Fixes for compatibility with Embedded Swift #61

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jun 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 25 additions & 33 deletions Patches/CSSOM.patch
Original file line number Diff line number Diff line change
@@ -1,41 +1,42 @@
diff --git a/Sources/CSSOM/Generated.swift b/Sources/CSSOM/Generated.swift
index 9cd2fb3..7aec5a8 100644
--- a/Sources/CSSOM/Generated.swift
+++ b/Sources/CSSOM/Generated.swift
@@ -379,7 +379,8 @@ public class CSSColorValue: CSSStyleValue {
super.init(unsafelyWrapping: jsObject)
}

@@ -411,7 +411,7 @@ public class CSSColorValue: CSSStyleValue {

public required init(unsafelyWrapping jsObject: JSObject) { super.init(unsafelyWrapping: jsObject) }
- @inlinable override public class func parse(cssText: String) -> CSSColorValue_or_CSSStyleValue {
+ // returns CSSStyleValue | CSSColorValue
+ @inlinable public class func parse(cssText: String) -> CSSStyleValue {
+ @inlinable public class func parse(cssText: String) -> CSSColorValue {
let this = constructor!
return this[Strings.parse].function!(this: this, arguments: [_toJSValue(cssText)]).fromJSValue()!
}
@@ -944,7 +945,7 @@ public class CSSNumericValue: CSSStyleValue {
@@ -947,7 +947,7 @@ public class CSSNumericValue: CSSStyleValue {
return this[Strings.type].function!(this: this, arguments: []).fromJSValue()!
}

- @inlinable override public class func parse(cssText: String) -> Self {
+ @inlinable public class func parse(cssText: String) -> Self {
- @inlinable override public class func parse(cssText: String) -> CSSNumericValue {
+ @inlinable public class func parse(cssText: String) -> CSSNumericValue {
let this = constructor!
return this[Strings.parse].function!(this: this, arguments: [_toJSValue(cssText)]).fromJSValue()!
}
@@ -1974,9 +1975,10 @@ public class StylePropertyMapReadOnly: JSBridgedClass, Sequence {
@@ -2072,9 +2072,10 @@ public class StylePropertyMapReadOnly: JSBridgedClass, Sequence {
ValueIterableIterator(sequence: self)
}

- @inlinable public func get(property: String) -> CSSStyleValue_or_Void {
- @inlinable final public func get(property: String) -> CSSStyleValue_or_Void {
+ // TODO: remove patch once https://github.com/w3c/css-houdini-drafts/issues/1095 is fixed
+ @inlinable public func get(property: String) -> CSSStyleValue? {
+ @inlinable final public func get(property: String) -> CSSStyleValue? {
let this = jsObject
- return this[Strings.get].function!(this: this, arguments: [_toJSValue(property)]).fromJSValue()!
+ return this[Strings.get].function!(this: this, arguments: [_toJSValue(property)]).fromJSValue()
}

@inlinable public func getAll(property: String) -> [CSSStyleValue] {
@@ -2646,58 +2648,6 @@ public enum CSSStyleValue_or_String: JSValueCompatible, Any_CSSStyleValue_or_Str

@inlinable final public func getAll(property: String) -> [CSSStyleValue] {
@@ -2706,49 +2707,6 @@ public enum CSSStyleValue_or_String: JSValueCompatible, Any_CSSStyleValue_or_Str
}
}
}

-public protocol Any_CSSStyleValue_or_Void: ConvertibleToJSValue {}
-extension CSSStyleValue: Any_CSSStyleValue_or_Void {}
-extension Void: Any_CSSStyleValue_or_Void {}
Expand All @@ -44,12 +45,11 @@
- case cssStyleValue(CSSStyleValue)
- case void(Void)
-
- init(_ cssStyleValue: CSSStyleValue) {
- public init(_ cssStyleValue: CSSStyleValue) {
- let val: CSSStyleValue_or_Void = .cssStyleValue(cssStyleValue)
- self = val
- }
-
- init(_ void: Void) {
- public init(_ void: Void) {
- let val: CSSStyleValue_or_Void = .void(void)
- self = val
- }
Expand All @@ -60,7 +60,6 @@
- default: return nil
- }
- }
-
- public var void: Void? {
- switch self {
- case let .void(void): return void
Expand All @@ -69,25 +68,18 @@
- }
-
- public static func construct(from value: JSValue) -> Self? {
- if let cssStyleValue: CSSStyleValue = value.fromJSValue() {
- return .cssStyleValue(cssStyleValue)
- }
- if let void: Void = value.fromJSValue() {
- return .void(void)
- }
- if let cssStyleValue: CSSStyleValue = value.fromJSValue() { return .cssStyleValue(cssStyleValue) }
- if let void: Void = value.fromJSValue() { return .void(void) }
- return nil
- }
-
- public var jsValue: JSValue {
- switch self {
- case let .cssStyleValue(cssStyleValue):
- return cssStyleValue.jsValue
- case let .void(void):
- return void.jsValue
- case let .cssStyleValue(cssStyleValue): return cssStyleValue.jsValue
- case let .void(void): return void.jsValue
- }
- }
-}
-
public protocol Any_CSSUnparsedSegment: ConvertibleToJSValue {}
extension CSSVariableReferenceValue: Any_CSSUnparsedSegment {}
extension String: Any_CSSUnparsedSegment {}
94 changes: 28 additions & 66 deletions Patches/DOM.patch
Original file line number Diff line number Diff line change
@@ -1,90 +1,52 @@
diff --git a/Sources/DOM/Generated.swift b/Sources/DOM/Generated.swift
index 9fa75ba..0339568 100644
--- a/Sources/DOM/Generated.swift
+++ b/Sources/DOM/Generated.swift
@@ -1007,8 +1007,15 @@ public class BeforeUnloadEvent: Event {
super.init(unsafelyWrapping: jsObject)
}

@@ -1094,6 +1094,17 @@ public class BeforeUnloadEvent: Event {

public required init(unsafelyWrapping jsObject: JSObject) { super.init(unsafelyWrapping: jsObject) }
+ @available(*, unavailable)
+ override public var returnValue: Bool {
+ get { !_returnValue.wrappedValue.isEmpty }
+ get { !self.returnValueAsString.isEmpty }
+ set {}
+ }
+
@usableFromInline let _returnValue: ReadWriteAttribute<String>
- @inlinable override public var returnValue: String {
+ // renamed because `String` is not compatible with `Bool`
+ @inlinable public var returnValueAsString: String {
get { _returnValue.wrappedValue }
set { _returnValue.wrappedValue = newValue }
}
@@ -7095,7 +7102,8 @@ public class HTMLFormControlsCollection: HTMLCollection {
jsObject[key].fromJSValue()
}

- @inlinable override public func namedItem(name: String) -> Element_or_RadioNodeList? {
+ // `override` removed since the superclass returns a more constrained type `Element`
+ @inlinable func namedItem(name: String) -> Element_or_RadioNodeList? {
let this = jsObject
return this[Strings.namedItem].function!(this: this, arguments: [_toJSValue(name)]).fromJSValue()
}
@@ -17153,7 +17161,6 @@ public class VisibilityStateEntry: PerformanceEntry {
_name = ReadonlyAttribute(jsObject: jsObject, name: Strings.name)
_entryType = ReadonlyAttribute(jsObject: jsObject, name: Strings.entryType)
_startTime = ReadonlyAttribute(jsObject: jsObject, name: Strings.startTime)
- _duration = ReadonlyAttribute(jsObject: jsObject, name: Strings.duration)
super.init(unsafelyWrapping: jsObject)
}

@@ -17166,8 +17173,8 @@ public class VisibilityStateEntry: PerformanceEntry {
@usableFromInline let _startTime: ReadonlyAttribute<DOMHighResTimeStamp>
@inlinable override public var startTime: DOMHighResTimeStamp { _startTime.wrappedValue }

- @usableFromInline let _duration: ReadonlyAttribute<UInt32>
- @inlinable override public var duration: UInt32 { _duration.wrappedValue }
+ // XXX: override of property `duration` removed because the type here is UInt32 but the
+ // type in the superclass is DOMHighResTimestamp (Double).
+ get { self.jsObject[Strings.returnValue].string! }
+ set { self.jsObject[Strings.returnValue] = .string(newValue) }
+ }
}

public class VisualViewport: EventTarget {
@@ -20687,19 +20694,9 @@ public enum CanvasImageSource: JSValueCompatible, Any_CanvasImageSource {

public enum BitrateMode: JSString, JSValueCompatible {
@@ -24231,14 +24242,6 @@ public enum CanvasImageSource: JSValueCompatible, Any_CanvasImageSource {
let val: CanvasImageSource = .htmlOrSVGImageElement(htmlOrSVGImageElement)
self = val
}

- init(_ htmlOrSVGImageElement: HTMLOrSVGImageElement) {
- let val: CanvasImageSource = .htmlOrSVGImageElement(htmlOrSVGImageElement)
- self = val
- }
-
init(_ htmlImageElement: HTMLImageElement) {
- public init(_ htmlImageElement: HTMLImageElement) {
- let val: HTMLOrSVGImageElement = .htmlImageElement(htmlImageElement)
- self = .init(val)
- }
-
- init(_ svgImageElement: SVGImageElement) {
- public init(_ svgImageElement: SVGImageElement) {
- let val: HTMLOrSVGImageElement = .svgImageElement(svgImageElement)
- self = .init(val)
+ let val: CanvasImageSource = .htmlOrSVGImageElement(htmlImageElement)
+ self = val
}

init(_ htmlVideoElement: HTMLVideoElement) {
@@ -21947,18 +21944,8 @@ public enum ImageBitmapSource: JSValueCompatible, Any_ImageBitmapSource {
- }
public init(_ htmlVideoElement: HTMLVideoElement) {
let val: CanvasImageSource = .htmlVideoElement(htmlVideoElement)
self = val
@@ -25289,14 +25292,6 @@ public enum ImageBitmapSource: JSValueCompatible, Any_ImageBitmapSource {
let val: CanvasImageSource = .htmlOrSVGImageElement(htmlOrSVGImageElement)
self = .init(val)
}

- init(_ htmlOrSVGImageElement: HTMLOrSVGImageElement) {
- let val: CanvasImageSource = .htmlOrSVGImageElement(htmlOrSVGImageElement)
- self = .init(val)
- }
-
init(_ htmlImageElement: HTMLImageElement) {
- public init(_ htmlImageElement: HTMLImageElement) {
- let val: HTMLOrSVGImageElement = .htmlImageElement(htmlImageElement)
- self = .init(val)
- }
-
- init(_ svgImageElement: SVGImageElement) {
- public init(_ svgImageElement: SVGImageElement) {
- let val: HTMLOrSVGImageElement = .svgImageElement(svgImageElement)
+ let val: CanvasImageSource = .htmlOrSVGImageElement(htmlImageElement)
- self = .init(val)
- }
public init(_ htmlVideoElement: HTMLVideoElement) {
let val: CanvasImageSource = .htmlVideoElement(htmlVideoElement)
self = .init(val)
}

22 changes: 8 additions & 14 deletions Patches/SVG.patch
Original file line number Diff line number Diff line change
@@ -1,21 +1,15 @@
diff --git a/Sources/SVG/Generated.swift b/Sources/SVG/Generated.swift
index 176385b..bf8f1dd 100644
--- a/Sources/SVG/Generated.swift
+++ b/Sources/SVG/Generated.swift
@@ -544,14 +544,16 @@ public class SVGElement: Element, GlobalEventHandlers, DocumentAndElementEventHa
@inlinable override public class var constructor: JSFunction? { JSObject.global[Strings.SVGElement].function }
@@ -524,7 +524,9 @@ public class SVGElement: Element, GlobalEventHandlers, SVGElementInstance, HTMLO

public required init(unsafelyWrapping jsObject: JSObject) {
- _className = ReadonlyAttribute(jsObject: jsObject, name: Strings.className)
+ _svgClassName = ReadonlyAttribute(jsObject: jsObject, name: Strings.className)
_ownerSVGElement = ReadonlyAttribute(jsObject: jsObject, name: Strings.ownerSVGElement)
_viewportElement = ReadonlyAttribute(jsObject: jsObject, name: Strings.viewportElement)
super.init(unsafelyWrapping: jsObject)
}
public required init(unsafelyWrapping jsObject: JSObject) { super.init(unsafelyWrapping: jsObject) }

- @inlinable public var className: SVGAnimatedString { jsObject[Strings.className].fromJSValue()! }
+ // Renamed because superclass has a `className` property of type `String`
+ // NOTE! Accessing `className` on an SVGElement will crash your app
@ReadonlyAttribute
- public var className: SVGAnimatedString
+ public var svgClassName: SVGAnimatedString
+ @inlinable public var svgClassName: SVGAnimatedString { jsObject[Strings.className].fromJSValue()! }
@inlinable public var ownerSVGElement: SVGSVGElement? { jsObject[Strings.ownerSVGElement].fromJSValue() }

@ReadonlyAttribute
public var ownerSVGElement: SVGSVGElement?
30 changes: 14 additions & 16 deletions Patches/WebAudio.patch
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
diff --git a/Sources/WebAudio/Generated.swift b/Sources/WebAudio/Generated.swift
index fff1563..d672d8c 100644
--- a/Sources/WebAudio/Generated.swift
+++ b/Sources/WebAudio/Generated.swift
@@ -195,7 +195,8 @@ public class AudioBufferSourceNode: AudioScheduledSourceNode {
@ReadWriteAttribute
public var loopEnd: Double
@@ -535,11 +535,11 @@ public class AudioNode: EventTarget {

- @inlinable override public func start(when: Double? = nil, offset: Double? = nil, duration: Double? = nil) {
+ // `override` removed since the superclass function has fewer parameters
+ @inlinable func start(when: Double? = nil, offset: Double? = nil, duration: Double? = nil) {
let this = jsObject
_ = this[Strings.start].function!(this: this, arguments: [_toJSValue(when), _toJSValue(offset), _toJSValue(duration)])
}
@@ -492,7 +493,7 @@ public class AudioNode: EventTarget {
super.init(unsafelyWrapping: jsObject)
}
public required init(unsafelyWrapping jsObject: JSObject) { super.init(unsafelyWrapping: jsObject) }

- @inlinable public func connect(destinationNode: AudioNode, output: UInt32? = nil, input: UInt32? = nil) -> Self {
+ @discardableResult @inlinable public func connect<NodeType: AudioNode>(destinationNode: NodeType, output: UInt32? = nil, input: UInt32? = nil) -> NodeType {
- @inlinable final public func connect(
- destinationNode: AudioNode,
+ @discardableResult @inlinable public final func connect<NodeType: AudioNode>(
+ destinationNode: NodeType,
output: UInt32? = nil,
input: UInt32? = nil
- ) -> AudioNode {
+ ) -> NodeType {
let this = jsObject
return this[Strings.connect].function!(this: this, arguments: [_toJSValue(destinationNode), _toJSValue(output), _toJSValue(input)]).fromJSValue()!
}
return this[Strings.connect].function!(
this: this,
4 changes: 2 additions & 2 deletions Sources/WebIDLToSwift/IDLBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import WebIDL

enum IDLBuilder {
static let basicDependencies = ["ECMAScript", "JavaScriptKit"]
static let optionalDependencies = ["JavaScriptEventLoop"]
static let optionalDependencies = ["JavaScriptEventLoop", "_Concurrency"]

static let preamble = """
// This file was auto-generated by WebIDLToSwift. DO NOT EDIT!
Expand Down Expand Up @@ -44,7 +44,7 @@ enum IDLBuilder {
}

let formedPreamble = preamble + (optionalDependencies.map { """
#if canImport\($0)
#if canImport(\($0))
import \($0)
#endif
""" } + dependencies.map { "import \($0)" }).joined(separator: "\n")
Expand Down
3 changes: 3 additions & 0 deletions Sources/WebIDLToSwift/Module.swift
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ let domModule = Module(
"css-pseudo",
"geometry",
"cssom-view",
"css-view-transitions",
"hr-time",
"FileAPI",
"xhr",
Expand All @@ -42,6 +43,8 @@ let domModule = Module(
"performance-timeline",
"permissions",
"mathml-core",
"trusted-types",
"urlpattern",
],
dependencies: ["WebAPIBase"]
)
Expand Down
9 changes: 5 additions & 4 deletions Sources/WebIDLToSwift/PackageManifest.swift
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
// swiftlint:disable function_body_length
func generateManifest(_ modules: [Module]) -> String {
#"""
// swift-tools-version:5.5
// swift-tools-version: 6.1
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "WebAPIKit",
platforms: [.macOS(.v10_13)],
platforms: [.macOS(.v10_15)],
products: [
.executable(
name: "WebAPIKitDemo",
Expand All @@ -29,7 +29,7 @@ func generateManifest(_ modules: [Module]) -> String {
dependencies: [
.package(
url: "https://github.com/swiftwasm/JavaScriptKit.git",
.upToNextMajor(from: "0.16.0")
.upToNextMajor(from: "0.29.0")
),
],
targets: [
Expand Down Expand Up @@ -62,7 +62,8 @@ func generateManifest(_ modules: [Module]) -> String {
name: "WebAPIKitTests",
dependencies: ["DOM"]
),
]
],
swiftLanguageModes: [.v5]
)
"""#
}
2 changes: 1 addition & 1 deletion Sources/WebIDLToSwift/Shell.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Foundation
enum Shell {
static func format(source: String) {
print("Formatting generated Swift files...")
run(executable: "swiftformat", arguments: ["--swiftversion", "5.5", source])
run(executable: "swift", arguments: ["format", "format", "--parallel", "--in-place", source])
}

private static let projectRoot = URL(fileURLWithPath: #file)
Expand Down
Loading
Loading