1
1
import _CJavaScriptKit
2
2
3
+ public protocol JSBridgedType : JSValueCodable , CustomStringConvertible {
4
+ static var constructor : JSFunction ? { get }
5
+
6
+ var objectRef : JSObject { get }
7
+ init ( objectRef: JSObject )
8
+ }
9
+
10
+ extension JSBridgedType {
11
+ public var description : String {
12
+ return objectRef. toString!( ) . fromJSValue ( ) !
13
+ }
14
+ }
15
+
3
16
public protocol JSValueConvertible {
4
17
func jsValue( ) -> JSValue
5
18
}
6
19
7
- extension JSValue : JSValueConvertible {
20
+ public typealias JSValueCodable = JSValueConvertible & JSValueConstructible
21
+
22
+ extension JSBridgedType {
23
+ public static func canDecode( from jsValue: JSValue ) -> Bool {
24
+ if let constructor = Self . constructor {
25
+ return jsValue. isInstanceOf ( constructor)
26
+ } else {
27
+ return jsValue. isObject
28
+ }
29
+ }
30
+
31
+ public init ( jsValue: JSValue ) {
32
+ self . init ( objectRef: jsValue. object!)
33
+ }
34
+
35
+ public func jsValue( ) -> JSValue {
36
+ return JSValue . object ( objectRef)
37
+ }
38
+ }
39
+
40
+ extension JSValue : JSValueCodable {
41
+ public static func construct( from value: JSValue ) -> Self ? {
42
+ return value
43
+ }
44
+
8
45
public func jsValue( ) -> JSValue { self }
9
46
}
10
47
@@ -16,20 +53,20 @@ extension Int: JSValueConvertible {
16
53
public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
17
54
}
18
55
19
- extension Int8 : JSValueConvertible {
56
+ extension UInt : JSValueConvertible {
20
57
public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
21
58
}
22
59
23
- extension Int16 : JSValueConvertible {
60
+ extension Float : JSValueConvertible {
24
61
public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
25
62
}
26
63
27
- extension Int32 : JSValueConvertible {
28
- public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
64
+ extension Double : JSValueConvertible {
65
+ public func jsValue( ) -> JSValue { . number( self ) }
29
66
}
30
67
31
- extension UInt : JSValueConvertible {
32
- public func jsValue( ) -> JSValue { . number ( Double ( self ) ) }
68
+ extension String : JSValueConvertible {
69
+ public func jsValue( ) -> JSValue { . string ( self ) }
33
70
}
34
71
35
72
extension UInt8 : JSValueConvertible {
@@ -41,22 +78,30 @@ extension UInt16: JSValueConvertible {
41
78
}
42
79
43
80
extension UInt32 : JSValueConvertible {
44
- public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
81
+ public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
45
82
}
46
83
47
- extension Float : JSValueConvertible {
84
+ extension UInt64 : JSValueConvertible {
48
85
public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
49
86
}
50
87
51
- extension Double : JSValueConvertible {
52
- public func jsValue( ) -> JSValue { . number( self ) }
88
+ extension Int8 : JSValueConvertible {
89
+ public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
53
90
}
54
91
55
- extension String : JSValueConvertible {
56
- public func jsValue( ) -> JSValue { . string( self ) }
92
+ extension Int16 : JSValueConvertible {
93
+ public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
94
+ }
95
+
96
+ extension Int32 : JSValueConvertible {
97
+ public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
57
98
}
58
99
59
- extension JSObject : JSValueConvertible {
100
+ extension Int64 : JSValueConvertible {
101
+ public func jsValue( ) -> JSValue { . number( Double ( self ) ) }
102
+ }
103
+
104
+ extension JSObject : JSValueCodable {
60
105
// `JSObject.jsValue` is defined in JSObject.swift to be able to overridden
61
106
// from `JSFunction`
62
107
}
@@ -79,24 +124,80 @@ extension Dictionary: JSValueConvertible where Value == JSValueConvertible, Key
79
124
}
80
125
}
81
126
82
- private let Array = JSObject . global. Array. function!
127
+ private let NativeJSArray = JSObject . global. Array. function!
128
+ extension Dictionary : JSValueConstructible where Value: JSValueConstructible , Key == String {
129
+ public static func construct( from value: JSValue ) -> Self ? {
130
+ if let objectRef = value. object,
131
+ let keys: [ String ] = Object . keys!( objectRef. jsValue ( ) ) . fromJSValue ( ) {
132
+ var entries = [ ( String, Value) ] ( )
133
+ entries. reserveCapacity ( keys. count)
134
+ for key in keys {
135
+ guard let value: Value = objectRef [ key] . fromJSValue ( ) else {
136
+ return nil
137
+ }
138
+ entries. append ( ( key, value) )
139
+ }
140
+ return Dictionary ( uniqueKeysWithValues: entries)
141
+ }
142
+ return nil
143
+ }
144
+ }
145
+
146
+ extension Optional : JSValueConstructible where Wrapped: JSValueConstructible {
147
+ public static func construct( from value: JSValue ) -> Self ? {
148
+ switch value {
149
+ case . null, . undefined:
150
+ return nil
151
+ default :
152
+ return Wrapped . construct ( from: value)
153
+ }
154
+ }
155
+ }
156
+
157
+ extension Optional : JSValueConvertible where Wrapped: JSValueConvertible {
158
+ public func jsValue( ) -> JSValue {
159
+ switch self {
160
+ case . none: return . null
161
+ case let . some( wrapped) : return wrapped. jsValue ( )
162
+ }
163
+ }
164
+ }
83
165
84
166
extension Array where Element: JSValueConvertible {
85
167
public func jsValue( ) -> JSValue {
86
- Swift . Array < JSValueConvertible > . jsValue ( self ) ( )
168
+ Array < JSValueConvertible > . jsValue ( self ) ( )
87
169
}
88
170
}
89
171
90
172
extension Array : JSValueConvertible where Element == JSValueConvertible {
91
173
public func jsValue( ) -> JSValue {
92
- let array = Array . new ( count)
174
+ let array = NativeJSArray . new ( count)
93
175
for (index, element) in enumerated ( ) {
94
176
array [ index] = element. jsValue ( )
95
177
}
96
178
return . object( array)
97
179
}
98
180
}
99
181
182
+ extension Array : JSValueConstructible where Element: JSValueConstructible {
183
+ public static func construct( from value: JSValue ) -> [ Element ] ? {
184
+ if let objectRef = value. object,
185
+ objectRef. isInstanceOf ( JSObject . global. Array. function!) {
186
+ let count : Int = objectRef. length. fromJSValue ( ) !
187
+ var array = [ Element] ( )
188
+ array. reserveCapacity ( count)
189
+
190
+ for i in 0 ..< count {
191
+ guard let value: Element = objectRef [ i] . fromJSValue ( ) else { return nil }
192
+ array. append ( value)
193
+ }
194
+
195
+ return array
196
+ }
197
+ return nil
198
+ }
199
+ }
200
+
100
201
extension RawJSValue : JSValueConvertible {
101
202
public func jsValue( ) -> JSValue {
102
203
switch kind {
@@ -192,6 +293,6 @@ extension Array where Element == JSValueConvertible {
192
293
193
294
extension Array where Element: JSValueConvertible {
194
295
func withRawJSValues< T> ( _ body: ( [ RawJSValue ] ) -> T ) -> T {
195
- Swift . Array < JSValueConvertible > . withRawJSValues ( self ) ( body)
296
+ Array < JSValueConvertible > . withRawJSValues ( self ) ( body)
196
297
}
197
298
}
0 commit comments