@@ -23,6 +23,18 @@ const IteratorPrototype = Object.getPrototypeOf(
23
23
Object . getPrototypeOf ( [ ] [ Symbol . iterator ] ( ) )
24
24
) ;
25
25
26
+ const unpairedSurrogateRe =
27
+ / ( [ ^ \uD800 - \uDBFF ] | ^ ) [ \uDC00 - \uDFFF ] | [ \uD800 - \uDBFF ] (? ! [ \uDC00 - \uDFFF ] ) / ;
28
+ function toUSVString ( val ) {
29
+ const str = '' + val ;
30
+ // As of V8 5.5, `str.search()` (and `unpairedSurrogateRe[@@search]()`) are
31
+ // slower than `unpairedSurrogateRe.exec()`.
32
+ const match = unpairedSurrogateRe . exec ( str ) ;
33
+ if ( ! match )
34
+ return str ;
35
+ return binding . toUSVString ( str , match . index ) ;
36
+ }
37
+
26
38
class OpaqueOrigin {
27
39
toString ( ) {
28
40
return 'null' ;
@@ -108,7 +120,6 @@ function onParseError(flags, input) {
108
120
109
121
// Reused by URL constructor and URL#href setter.
110
122
function parse ( url , input , base ) {
111
- input = String ( input ) ;
112
123
const base_context = base ? base [ context ] : undefined ;
113
124
url [ context ] = new StorageObject ( ) ;
114
125
binding . parse ( input . trim ( ) , - 1 ,
@@ -203,8 +214,10 @@ function onParseHashComplete(flags, protocol, username, password,
203
214
204
215
class URL {
205
216
constructor ( input , base ) {
217
+ // toUSVString is not needed.
218
+ input = '' + input ;
206
219
if ( base !== undefined && ! ( base instanceof URL ) )
207
- base = new URL ( String ( base ) ) ;
220
+ base = new URL ( base ) ;
208
221
parse ( this , input , base ) ;
209
222
}
210
223
@@ -312,6 +325,8 @@ Object.defineProperties(URL.prototype, {
312
325
return this [ kFormat ] ( { } ) ;
313
326
} ,
314
327
set ( input ) {
328
+ // toUSVString is not needed.
329
+ input = '' + input ;
315
330
parse ( this , input ) ;
316
331
}
317
332
} ,
@@ -329,7 +344,8 @@ Object.defineProperties(URL.prototype, {
329
344
return this [ context ] . scheme ;
330
345
} ,
331
346
set ( scheme ) {
332
- scheme = String ( scheme ) ;
347
+ // toUSVString is not needed.
348
+ scheme = '' + scheme ;
333
349
if ( scheme . length === 0 )
334
350
return ;
335
351
binding . parse ( scheme , binding . kSchemeStart , null , this [ context ] ,
@@ -343,7 +359,8 @@ Object.defineProperties(URL.prototype, {
343
359
return this [ context ] . username || '' ;
344
360
} ,
345
361
set ( username ) {
346
- username = String ( username ) ;
362
+ // toUSVString is not needed.
363
+ username = '' + username ;
347
364
if ( ! this . hostname )
348
365
return ;
349
366
const ctx = this [ context ] ;
@@ -363,7 +380,8 @@ Object.defineProperties(URL.prototype, {
363
380
return this [ context ] . password || '' ;
364
381
} ,
365
382
set ( password ) {
366
- password = String ( password ) ;
383
+ // toUSVString is not needed.
384
+ password = '' + password ;
367
385
if ( ! this . hostname )
368
386
return ;
369
387
const ctx = this [ context ] ;
@@ -388,7 +406,8 @@ Object.defineProperties(URL.prototype, {
388
406
} ,
389
407
set ( host ) {
390
408
const ctx = this [ context ] ;
391
- host = String ( host ) ;
409
+ // toUSVString is not needed.
410
+ host = '' + host ;
392
411
if ( this [ cannotBeBase ] ||
393
412
( this [ special ] && host . length === 0 ) ) {
394
413
// Cannot set the host if cannot-be-base is set or
@@ -412,7 +431,8 @@ Object.defineProperties(URL.prototype, {
412
431
} ,
413
432
set ( host ) {
414
433
const ctx = this [ context ] ;
415
- host = String ( host ) ;
434
+ // toUSVString is not needed.
435
+ host = '' + host ;
416
436
if ( this [ cannotBeBase ] ||
417
437
( this [ special ] && host . length === 0 ) ) {
418
438
// Cannot set the host if cannot-be-base is set or
@@ -436,11 +456,12 @@ Object.defineProperties(URL.prototype, {
436
456
return port === undefined ? '' : String ( port ) ;
437
457
} ,
438
458
set ( port ) {
459
+ // toUSVString is not needed.
460
+ port = '' + port ;
439
461
const ctx = this [ context ] ;
440
462
if ( ! ctx . host || this [ cannotBeBase ] ||
441
463
this . protocol === 'file:' )
442
464
return ;
443
- port = String ( port ) ;
444
465
if ( port === '' ) {
445
466
ctx . port = undefined ;
446
467
return ;
@@ -459,9 +480,11 @@ Object.defineProperties(URL.prototype, {
459
480
return ctx . path !== undefined ? `/${ ctx . path . join ( '/' ) } ` : '' ;
460
481
} ,
461
482
set ( path ) {
483
+ // toUSVString is not needed.
484
+ path = '' + path ;
462
485
if ( this [ cannotBeBase ] )
463
486
return ;
464
- binding . parse ( String ( path ) , binding . kPathStart , null , this [ context ] ,
487
+ binding . parse ( path , binding . kPathStart , null , this [ context ] ,
465
488
onParsePathComplete . bind ( this ) ) ;
466
489
}
467
490
} ,
@@ -474,7 +497,7 @@ Object.defineProperties(URL.prototype, {
474
497
} ,
475
498
set ( search ) {
476
499
const ctx = this [ context ] ;
477
- search = String ( search ) ;
500
+ search = toUSVString ( search ) ;
478
501
if ( ! search ) {
479
502
ctx . query = null ;
480
503
ctx . flags &= ~ binding . URL_FLAGS_HAS_QUERY ;
@@ -506,7 +529,8 @@ Object.defineProperties(URL.prototype, {
506
529
} ,
507
530
set ( hash ) {
508
531
const ctx = this [ context ] ;
509
- hash = String ( hash ) ;
532
+ // toUSVString is not needed.
533
+ hash = '' + hash ;
510
534
if ( this . protocol === 'javascript:' )
511
535
return ;
512
536
if ( ! hash ) {
@@ -649,19 +673,22 @@ class URLSearchParams {
649
673
if ( pair . length !== 2 ) {
650
674
throw new TypeError ( 'Each query pair must be a name/value tuple' ) ;
651
675
}
652
- this [ searchParams ] . push ( String ( pair [ 0 ] ) , String ( pair [ 1 ] ) ) ;
676
+ const key = toUSVString ( pair [ 0 ] ) ;
677
+ const value = toUSVString ( pair [ 1 ] ) ;
678
+ this [ searchParams ] . push ( key , value ) ;
653
679
}
654
680
} else {
655
681
// record<USVString, USVString>
656
682
this [ searchParams ] = [ ] ;
657
- for ( const key of Object . keys ( init ) ) {
658
- const value = String ( init [ key ] ) ;
683
+ for ( var key of Object . keys ( init ) ) {
684
+ key = toUSVString ( key ) ;
685
+ const value = toUSVString ( init [ key ] ) ;
659
686
this [ searchParams ] . push ( key , value ) ;
660
687
}
661
688
}
662
689
} else {
663
690
// USVString
664
- init = String ( init ) ;
691
+ init = toUSVString ( init ) ;
665
692
if ( init [ 0 ] === '?' ) init = init . slice ( 1 ) ;
666
693
initSearchParams ( this , init ) ;
667
694
}
@@ -740,8 +767,8 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
740
767
throw new TypeError ( '"name" and "value" arguments must be specified' ) ;
741
768
}
742
769
743
- name = String ( name ) ;
744
- value = String ( value ) ;
770
+ name = toUSVString ( name ) ;
771
+ value = toUSVString ( value ) ;
745
772
this [ searchParams ] . push ( name , value ) ;
746
773
update ( this [ context ] , this ) ;
747
774
} ,
@@ -755,7 +782,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
755
782
}
756
783
757
784
const list = this [ searchParams ] ;
758
- name = String ( name ) ;
785
+ name = toUSVString ( name ) ;
759
786
for ( var i = 0 ; i < list . length ; ) {
760
787
const cur = list [ i ] ;
761
788
if ( cur === name ) {
@@ -776,7 +803,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
776
803
}
777
804
778
805
const list = this [ searchParams ] ;
779
- name = String ( name ) ;
806
+ name = toUSVString ( name ) ;
780
807
for ( var i = 0 ; i < list . length ; i += 2 ) {
781
808
if ( list [ i ] === name ) {
782
809
return list [ i + 1 ] ;
@@ -795,7 +822,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
795
822
796
823
const list = this [ searchParams ] ;
797
824
const values = [ ] ;
798
- name = String ( name ) ;
825
+ name = toUSVString ( name ) ;
799
826
for ( var i = 0 ; i < list . length ; i += 2 ) {
800
827
if ( list [ i ] === name ) {
801
828
values . push ( list [ i + 1 ] ) ;
@@ -813,7 +840,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
813
840
}
814
841
815
842
const list = this [ searchParams ] ;
816
- name = String ( name ) ;
843
+ name = toUSVString ( name ) ;
817
844
for ( var i = 0 ; i < list . length ; i += 2 ) {
818
845
if ( list [ i ] === name ) {
819
846
return true ;
@@ -831,8 +858,8 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
831
858
}
832
859
833
860
const list = this [ searchParams ] ;
834
- name = String ( name ) ;
835
- value = String ( value ) ;
861
+ name = toUSVString ( name ) ;
862
+ value = toUSVString ( value ) ;
836
863
837
864
// If there are any name-value pairs whose name is `name`, in `list`, set
838
865
// the value of the first such name-value pair to `value` and remove the
@@ -1094,11 +1121,13 @@ function originFor(url, base) {
1094
1121
}
1095
1122
1096
1123
function domainToASCII ( domain ) {
1097
- return binding . domainToASCII ( String ( domain ) ) ;
1124
+ // toUSVString is not needed.
1125
+ return binding . domainToASCII ( '' + domain ) ;
1098
1126
}
1099
1127
1100
1128
function domainToUnicode ( domain ) {
1101
- return binding . domainToUnicode ( String ( domain ) ) ;
1129
+ // toUSVString is not needed.
1130
+ return binding . domainToUnicode ( '' + domain ) ;
1102
1131
}
1103
1132
1104
1133
// Utility function that converts a URL object into an ordinary
@@ -1184,11 +1213,14 @@ function getPathFromURL(path) {
1184
1213
return isWindows ? getPathFromURLWin32 ( path ) : getPathFromURLPosix ( path ) ;
1185
1214
}
1186
1215
1187
- exports . getPathFromURL = getPathFromURL ;
1188
- exports . URL = URL ;
1189
- exports . URLSearchParams = URLSearchParams ;
1190
- exports . domainToASCII = domainToASCII ;
1191
- exports . domainToUnicode = domainToUnicode ;
1192
- exports . urlToOptions = urlToOptions ;
1193
- exports . formatSymbol = kFormat ;
1194
- exports . searchParamsSymbol = searchParams ;
1216
+ module . exports = {
1217
+ toUSVString,
1218
+ getPathFromURL,
1219
+ URL ,
1220
+ URLSearchParams,
1221
+ domainToASCII,
1222
+ domainToUnicode,
1223
+ urlToOptions,
1224
+ formatSymbol : kFormat ,
1225
+ searchParamsSymbol : searchParams
1226
+ } ;
0 commit comments