10
10
//! [spec]: https://url.spec.whatwg.org/
11
11
//! [mdn]: https://developer.mozilla.org/en-US/docs/Web/API/URL
12
12
#![ cfg( feature = "url" ) ]
13
+ #![ allow( clippy:: needless_pass_by_value) ]
13
14
14
15
#[ cfg( test) ]
15
16
mod tests;
16
17
18
+ use boa_engine:: class:: Class ;
17
19
use boa_engine:: value:: Convert ;
18
- use boa_engine:: {
19
- js_error, js_string, Context , Finalize , JsData , JsResult , JsString , JsValue , Trace ,
20
- } ;
21
- use boa_interop:: { js_class, IntoJsFunctionCopied , JsClass } ;
20
+ use boa_engine:: { js_error, Context , Finalize , JsData , JsResult , JsString , JsValue , Trace } ;
21
+ use boa_interop:: boa_macros:: boa_class;
22
22
use std:: fmt:: Display ;
23
23
24
24
/// The `URL` class represents a (properly parsed) Uniform Resource Locator.
@@ -35,13 +35,36 @@ impl Url {
35
35
context. register_global_class :: < Self > ( ) ?;
36
36
Ok ( ( ) )
37
37
}
38
+ }
39
+
40
+ impl Display for Url {
41
+ fn fmt ( & self , f : & mut std:: fmt:: Formatter < ' _ > ) -> std:: fmt:: Result {
42
+ write ! ( f, "{}" , self . 0 )
43
+ }
44
+ }
45
+
46
+ impl From < url:: Url > for Url {
47
+ fn from ( url : url:: Url ) -> Self {
48
+ Self ( url)
49
+ }
50
+ }
51
+
52
+ impl From < Url > for url:: Url {
53
+ fn from ( url : Url ) -> url:: Url {
54
+ url. 0
55
+ }
56
+ }
38
57
58
+ #[ boa_class( rename = "URL" ) ]
59
+ #[ boa( rename_all = "camelCase" ) ]
60
+ impl Url {
39
61
/// Create a new `URL` object. Meant to be called from the JavaScript constructor.
40
62
///
41
63
/// # Errors
42
64
/// Any errors that might occur during URL parsing.
43
- fn js_new ( Convert ( ref url) : Convert < String > , base : Option < & Convert < String > > ) -> JsResult < Self > {
44
- if let Some ( Convert ( base) ) = base {
65
+ #[ boa( constructor) ]
66
+ pub fn new ( Convert ( ref url) : Convert < String > , base : Option < Convert < String > > ) -> JsResult < Self > {
67
+ if let Some ( Convert ( ref base) ) = base {
45
68
let base_url = url:: Url :: parse ( base)
46
69
. map_err ( |e| js_error ! ( TypeError : "Failed to parse base URL: {}" , e) ) ?;
47
70
if base_url. cannot_be_a_base ( ) {
@@ -58,179 +81,159 @@ impl Url {
58
81
Ok ( Self ( url) )
59
82
}
60
83
}
61
- }
62
84
63
- impl Display for Url {
64
- fn fmt ( & self , f : & mut std :: fmt :: Formatter < ' _ > ) -> std :: fmt :: Result {
65
- write ! ( f , "{}" , self . 0 )
85
+ # [ boa ( getter ) ]
86
+ fn hash ( & self ) -> JsString {
87
+ JsString :: from ( url :: quirks :: hash ( & self . 0 ) )
66
88
}
67
- }
68
89
69
- impl From < url:: Url > for Url {
70
- fn from ( url : url:: Url ) -> Self {
71
- Self ( url)
90
+ #[ boa( setter) ]
91
+ #[ boa( rename = "hash" ) ]
92
+ fn set_hash ( & mut self , value : Convert < String > ) {
93
+ url:: quirks:: set_hash ( & mut self . 0 , & value. 0 ) ;
72
94
}
73
- }
74
95
75
- impl From < Url > for url :: Url {
76
- fn from ( url : Url ) -> url :: Url {
77
- url. 0
96
+ # [ boa ( getter ) ]
97
+ fn hostname ( & self ) -> JsString {
98
+ JsString :: from ( url:: quirks :: hostname ( & self . 0 ) )
78
99
}
79
- }
80
100
81
- js_class ! {
82
- class Url as "URL" {
83
- property hash {
84
- fn get( this: JsClass <Url >) -> JsString {
85
- JsString :: from( url:: quirks:: hash( & this. borrow( ) . 0 ) )
86
- }
87
-
88
- fn set( this: JsClass <Url >, value: Convert <String >) {
89
- url:: quirks:: set_hash( & mut this. borrow_mut( ) . 0 , & value. 0 ) ;
90
- }
91
- }
101
+ #[ boa( setter) ]
102
+ #[ boa( rename = "hostname" ) ]
103
+ fn set_hostname ( & mut self , value : Convert < String > ) {
104
+ let _ = url:: quirks:: set_hostname ( & mut self . 0 , & value. 0 ) ;
105
+ }
92
106
93
- property hostname {
94
- fn get ( this : JsClass < Url > ) -> JsString {
95
- JsString :: from( url:: quirks:: hostname ( & this . borrow ( ) . 0 ) )
96
- }
107
+ # [ boa ( getter ) ]
108
+ fn host ( & self ) -> JsString {
109
+ JsString :: from ( url:: quirks:: host ( & self . 0 ) )
110
+ }
97
111
98
- fn set( this: JsClass <Url >, value: Convert <String >) {
99
- let _ = url:: quirks:: set_hostname( & mut this. borrow_mut( ) . 0 , & value. 0 ) ;
100
- }
101
- }
112
+ #[ boa( setter) ]
113
+ #[ boa( rename = "host" ) ]
114
+ fn set_host ( & mut self , value : Convert < String > ) {
115
+ let _ = url:: quirks:: set_host ( & mut self . 0 , & value. 0 ) ;
116
+ }
102
117
103
- property host {
104
- fn get ( this : JsClass < Url > ) -> JsString {
105
- JsString :: from( url:: quirks:: host ( & this . borrow ( ) . 0 ) )
106
- }
118
+ # [ boa ( getter ) ]
119
+ fn href ( & self ) -> JsString {
120
+ JsString :: from ( url:: quirks:: href ( & self . 0 ) )
121
+ }
107
122
108
- fn set( this: JsClass <Url >, value: Convert <String >) {
109
- let _ = url:: quirks:: set_host( & mut this. borrow_mut( ) . 0 , & value. 0 ) ;
110
- }
111
- }
123
+ #[ boa( setter) ]
124
+ #[ boa( rename = "href" ) ]
125
+ fn set_href ( & mut self , value : Convert < String > ) -> JsResult < ( ) > {
126
+ url:: quirks:: set_href ( & mut self . 0 , & value. 0 )
127
+ . map_err ( |e| js_error ! ( TypeError : "Failed to set href: {}" , e) )
128
+ }
112
129
113
- property href {
114
- fn get ( this : JsClass < Url > ) -> JsString {
115
- JsString :: from( url:: quirks:: href ( & this . borrow ( ) . 0 ) )
116
- }
130
+ # [ boa ( getter ) ]
131
+ fn origin ( & self ) -> JsString {
132
+ JsString :: from ( url:: quirks:: origin ( & self . 0 ) )
133
+ }
117
134
118
- fn set( this: JsClass <Url >, value: Convert <String >) -> JsResult <( ) > {
119
- url:: quirks:: set_href( & mut this. borrow_mut( ) . 0 , & value. 0 )
120
- . map_err( |e| js_error!( TypeError : "Failed to set href: {}" , e) )
121
- }
122
- }
135
+ #[ boa( getter) ]
136
+ fn password ( & self ) -> JsString {
137
+ JsString :: from ( url:: quirks:: password ( & self . 0 ) )
138
+ }
123
139
124
- property origin {
125
- fn get ( this : JsClass < Url > ) -> JsString {
126
- JsString :: from ( url :: quirks :: origin ( & this . borrow ( ) . 0 ) )
127
- }
128
- }
140
+ # [ boa ( setter ) ]
141
+ # [ boa ( rename = "password" ) ]
142
+ fn set_password ( & mut self , value : Convert < String > ) {
143
+ let _ = url :: quirks :: set_password ( & mut self . 0 , & value . 0 ) ;
144
+ }
129
145
130
- property password {
131
- fn get ( this : JsClass < Url > ) -> JsString {
132
- JsString :: from( url:: quirks:: password ( & this . borrow ( ) . 0 ) )
133
- }
146
+ # [ boa ( getter ) ]
147
+ fn pathname ( & self ) -> JsString {
148
+ JsString :: from ( url:: quirks:: pathname ( & self . 0 ) )
149
+ }
134
150
135
- fn set( this: JsClass <Url >, value: Convert <String >) {
136
- let _ = url:: quirks:: set_password( & mut this. borrow_mut( ) . 0 , & value. 0 ) ;
137
- }
138
- }
151
+ #[ boa( setter) ]
152
+ #[ boa( rename = "pathname" ) ]
153
+ fn set_pathname ( & mut self , value : Convert < String > ) {
154
+ let ( ) = url:: quirks:: set_pathname ( & mut self . 0 , & value. 0 ) ;
155
+ }
139
156
140
- property pathname {
141
- fn get ( this : JsClass < Url > ) -> JsString {
142
- JsString :: from( url:: quirks:: pathname ( & this . borrow ( ) . 0 ) )
143
- }
157
+ # [ boa ( getter ) ]
158
+ fn port ( & self ) -> JsString {
159
+ JsString :: from ( url:: quirks:: port ( & self . 0 ) )
160
+ }
144
161
145
- fn set( this: JsClass <Url >, value: Convert <String >) {
146
- let ( ) = url:: quirks:: set_pathname( & mut this. borrow_mut( ) . 0 , & value. 0 ) ;
147
- }
148
- }
162
+ #[ boa( setter) ]
163
+ #[ boa( rename = "port" ) ]
164
+ fn set_port ( & mut self , value : Convert < JsString > ) {
165
+ let _ = url:: quirks:: set_port ( & mut self . 0 , & value. 0 . to_std_string_lossy ( ) ) ;
166
+ }
149
167
150
- property port {
151
- fn get ( this : JsClass < Url > ) -> JsString {
152
- JsString :: from( url:: quirks:: port ( & this . borrow ( ) . 0 ) )
153
- }
168
+ # [ boa ( getter ) ]
169
+ fn protocol ( & self ) -> JsString {
170
+ JsString :: from ( url:: quirks:: protocol ( & self . 0 ) )
171
+ }
154
172
155
- fn set( this: JsClass <Url >, value: Convert <JsString >) {
156
- let _ = url:: quirks:: set_port( & mut this. borrow_mut( ) . 0 , & value. 0 . to_std_string_lossy( ) ) ;
157
- }
158
- }
173
+ #[ boa( setter) ]
174
+ #[ boa( rename = "protocol" ) ]
175
+ fn set_protocol ( & mut self , value : Convert < String > ) {
176
+ let _ = url:: quirks:: set_protocol ( & mut self . 0 , & value. 0 ) ;
177
+ }
159
178
160
- property protocol {
161
- fn get ( this : JsClass < Url > ) -> JsString {
162
- JsString :: from( url:: quirks:: protocol ( & this . borrow ( ) . 0 ) )
163
- }
179
+ # [ boa ( getter ) ]
180
+ fn search ( & self ) -> JsString {
181
+ JsString :: from ( url:: quirks:: search ( & self . 0 ) )
182
+ }
164
183
165
- fn set( this: JsClass <Url >, value: Convert <String >) {
166
- let _ = url:: quirks:: set_protocol( & mut this. borrow_mut( ) . 0 , & value. 0 ) ;
167
- }
168
- }
184
+ #[ boa( setter) ]
185
+ #[ boa( rename = "search" ) ]
186
+ fn set_search ( & mut self , value : Convert < String > ) {
187
+ url:: quirks:: set_search ( & mut self . 0 , & value. 0 ) ;
188
+ }
169
189
170
- property search {
171
- fn get ( this : JsClass < Url > ) -> JsString {
172
- JsString :: from ( url :: quirks :: search ( & this . borrow ( ) . 0 ) )
173
- }
190
+ # [ boa ( getter ) ]
191
+ fn search_params ( ) -> JsResult < ( ) > {
192
+ Err ( js_error ! ( Error : "URL.searchParams is not implemented" ) )
193
+ }
174
194
175
- fn set ( this : JsClass < Url > , value : Convert < String > ) {
176
- url :: quirks :: set_search ( & mut this . borrow_mut ( ) . 0 , & value . 0 ) ;
177
- }
178
- }
195
+ # [ boa ( getter ) ]
196
+ fn username ( & self ) -> JsString {
197
+ JsString :: from ( self . 0 . username ( ) )
198
+ }
179
199
180
- property search_params as "searchParams" {
181
- fn get ( ) -> JsResult < ( ) > {
182
- Err ( js_error! ( Error : "URL.searchParams is not implemented" ) )
183
- }
184
- }
200
+ # [ boa ( setter ) ]
201
+ # [ boa ( rename = "username" ) ]
202
+ fn set_username ( & mut self , value : Convert < String > ) {
203
+ let _ = self . 0 . set_username ( & value . 0 ) ;
204
+ }
185
205
186
- property username {
187
- fn get( this: JsClass <Url >) -> JsString {
188
- JsString :: from( this. borrow( ) . 0 . username( ) )
189
- }
206
+ fn to_string ( & self ) -> JsString {
207
+ JsString :: from ( format ! ( "{}" , self . 0 ) )
208
+ }
190
209
191
- fn set( this: JsClass <Url >, value: Convert <String >) {
192
- let _ = this. borrow_mut( ) . 0 . set_username( & value. 0 ) ;
193
- }
194
- }
210
+ fn to_json ( & self ) -> JsString {
211
+ JsString :: from ( format ! ( "{}" , self . 0 ) )
212
+ }
195
213
196
- constructor( url: Convert <String >, base: Option <Convert <String >>) {
197
- Self :: js_new( url, base. as_ref( ) )
198
- }
214
+ #[ boa( static ) ]
215
+ fn create_object_url ( ) -> JsResult < ( ) > {
216
+ Err ( js_error ! ( Error : "URL.createObjectURL is not implemented" ) )
217
+ }
199
218
200
- init( class: & mut ClassBuilder ) -> JsResult <( ) > {
201
- let create_object_url = ( || -> JsResult <( ) > {
202
- Err ( js_error!( Error : "URL.createObjectURL is not implemented" ) )
203
- } )
204
- . into_js_function_copied( class. context( ) ) ;
205
- let can_parse = ( |url: Convert <String >, base: Option <Convert <String >>| {
206
- Url :: js_new( url, base. as_ref( ) ) . is_ok( )
207
- } )
208
- . into_js_function_copied( class. context( ) ) ;
209
- let parse = ( |url: Convert <String >, base: Option <Convert <String >>, context: & mut Context | {
210
- Url :: js_new( url, base. as_ref( ) )
211
- . map_or( Ok ( JsValue :: null( ) ) , |u| Url :: from_data( u, context) . map( JsValue :: from) )
212
- } )
213
- . into_js_function_copied( class. context( ) ) ;
214
- let revoke_object_url = ( || -> JsResult <( ) > {
215
- Err ( js_error!( Error : "URL.revokeObjectURL is not implemented" ) )
216
- } )
217
- . into_js_function_copied( class. context( ) ) ;
218
-
219
- class
220
- . static_method( js_string!( "createObjectURL" ) , 1 , create_object_url)
221
- . static_method( js_string!( "canParse" ) , 2 , can_parse)
222
- . static_method( js_string!( "parse" ) , 2 , parse)
223
- . static_method( js_string!( "revokeObjectUrl" ) , 1 , revoke_object_url) ;
224
-
225
- Ok ( ( ) )
226
- }
219
+ #[ boa( static ) ]
220
+ fn can_parse ( url : Convert < String > , base : Option < Convert < String > > ) -> bool {
221
+ Url :: new ( url, base) . is_ok ( )
222
+ }
227
223
228
- fn to_string as "toString" ( this: JsClass <Url >) -> JsString {
229
- JsString :: from( format!( "{}" , this. borrow( ) . 0 ) )
230
- }
224
+ #[ boa( static ) ]
225
+ fn parse (
226
+ url : Convert < String > ,
227
+ base : Option < Convert < String > > ,
228
+ context : & mut Context ,
229
+ ) -> JsResult < JsValue > {
230
+ Url :: new ( url, base) . map_or ( Ok ( JsValue :: null ( ) ) , |u| {
231
+ Url :: from_data ( u, context) . map ( JsValue :: from)
232
+ } )
233
+ }
231
234
232
- fn to_json as "toJSON" ( this : JsClass < Url > ) -> JsString {
233
- JsString :: from ( format! ( "{}" , this . borrow ( ) . 0 ) )
234
- }
235
+ # [ boa ( static ) ]
236
+ fn revoke_object_url ( ) -> JsResult < ( ) > {
237
+ Err ( js_error ! ( Error : "URL.revokeObjectURL is not implemented" ) )
235
238
}
236
239
}
0 commit comments