@@ -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' ;
@@ -104,7 +116,6 @@ function onParseComplete(flags, protocol, username, password,
104
116
105
117
// Reused by URL constructor and URL#href setter.
106
118
function parse ( url , input , base ) {
107
- input = String ( input ) ;
108
119
const base_context = base ? base [ context ] : undefined ;
109
120
url [ context ] = new StorageObject ( ) ;
110
121
binding . parse ( input . trim ( ) , - 1 ,
@@ -206,8 +217,10 @@ function onParseHashComplete(flags, protocol, username, password,
206
217
207
218
class URL {
208
219
constructor ( input , base ) {
220
+ // toUSVString is not needed.
221
+ input = '' + input ;
209
222
if ( base !== undefined && ! ( base instanceof URL ) )
210
- base = new URL ( String ( base ) ) ;
223
+ base = new URL ( base ) ;
211
224
parse ( this , input , base ) ;
212
225
}
213
226
@@ -315,6 +328,8 @@ Object.defineProperties(URL.prototype, {
315
328
return this [ kFormat ] ( { } ) ;
316
329
} ,
317
330
set ( input ) {
331
+ // toUSVString is not needed.
332
+ input = '' + input ;
318
333
parse ( this , input ) ;
319
334
}
320
335
} ,
@@ -332,7 +347,8 @@ Object.defineProperties(URL.prototype, {
332
347
return this [ context ] . scheme ;
333
348
} ,
334
349
set ( scheme ) {
335
- scheme = String ( scheme ) ;
350
+ // toUSVString is not needed.
351
+ scheme = '' + scheme ;
336
352
if ( scheme . length === 0 )
337
353
return ;
338
354
binding . parse ( scheme , binding . kSchemeStart , null , this [ context ] ,
@@ -346,7 +362,8 @@ Object.defineProperties(URL.prototype, {
346
362
return this [ context ] . username || '' ;
347
363
} ,
348
364
set ( username ) {
349
- username = String ( username ) ;
365
+ // toUSVString is not needed.
366
+ username = '' + username ;
350
367
if ( ! this . hostname )
351
368
return ;
352
369
const ctx = this [ context ] ;
@@ -366,7 +383,8 @@ Object.defineProperties(URL.prototype, {
366
383
return this [ context ] . password || '' ;
367
384
} ,
368
385
set ( password ) {
369
- password = String ( password ) ;
386
+ // toUSVString is not needed.
387
+ password = '' + password ;
370
388
if ( ! this . hostname )
371
389
return ;
372
390
const ctx = this [ context ] ;
@@ -391,7 +409,8 @@ Object.defineProperties(URL.prototype, {
391
409
} ,
392
410
set ( host ) {
393
411
const ctx = this [ context ] ;
394
- host = String ( host ) ;
412
+ // toUSVString is not needed.
413
+ host = '' + host ;
395
414
if ( this [ cannotBeBase ] ||
396
415
( this [ special ] && host . length === 0 ) ) {
397
416
// Cannot set the host if cannot-be-base is set or
@@ -415,7 +434,8 @@ Object.defineProperties(URL.prototype, {
415
434
} ,
416
435
set ( host ) {
417
436
const ctx = this [ context ] ;
418
- host = String ( host ) ;
437
+ // toUSVString is not needed.
438
+ host = '' + host ;
419
439
if ( this [ cannotBeBase ] ||
420
440
( this [ special ] && host . length === 0 ) ) {
421
441
// Cannot set the host if cannot-be-base is set or
@@ -439,11 +459,12 @@ Object.defineProperties(URL.prototype, {
439
459
return port === undefined ? '' : String ( port ) ;
440
460
} ,
441
461
set ( port ) {
462
+ // toUSVString is not needed.
463
+ port = '' + port ;
442
464
const ctx = this [ context ] ;
443
465
if ( ! ctx . host || this [ cannotBeBase ] ||
444
466
this . protocol === 'file:' )
445
467
return ;
446
- port = String ( port ) ;
447
468
if ( port === '' ) {
448
469
ctx . port = undefined ;
449
470
return ;
@@ -462,9 +483,11 @@ Object.defineProperties(URL.prototype, {
462
483
return ctx . path !== undefined ? `/${ ctx . path . join ( '/' ) } ` : '' ;
463
484
} ,
464
485
set ( path ) {
486
+ // toUSVString is not needed.
487
+ path = '' + path ;
465
488
if ( this [ cannotBeBase ] )
466
489
return ;
467
- binding . parse ( String ( path ) , binding . kPathStart , null , this [ context ] ,
490
+ binding . parse ( path , binding . kPathStart , null , this [ context ] ,
468
491
onParsePathComplete . bind ( this ) ) ;
469
492
}
470
493
} ,
@@ -477,7 +500,7 @@ Object.defineProperties(URL.prototype, {
477
500
} ,
478
501
set ( search ) {
479
502
const ctx = this [ context ] ;
480
- search = String ( search ) ;
503
+ search = toUSVString ( search ) ;
481
504
if ( ! search ) {
482
505
ctx . query = null ;
483
506
ctx . flags &= ~ binding . URL_FLAGS_HAS_QUERY ;
@@ -509,7 +532,8 @@ Object.defineProperties(URL.prototype, {
509
532
} ,
510
533
set ( hash ) {
511
534
const ctx = this [ context ] ;
512
- hash = String ( hash ) ;
535
+ // toUSVString is not needed.
536
+ hash = '' + hash ;
513
537
if ( this . protocol === 'javascript:' )
514
538
return ;
515
539
if ( ! hash ) {
@@ -652,19 +676,22 @@ class URLSearchParams {
652
676
if ( pair . length !== 2 ) {
653
677
throw new TypeError ( 'Each query pair must be a name/value tuple' ) ;
654
678
}
655
- this [ searchParams ] . push ( String ( pair [ 0 ] ) , String ( pair [ 1 ] ) ) ;
679
+ const key = toUSVString ( pair [ 0 ] ) ;
680
+ const value = toUSVString ( pair [ 1 ] ) ;
681
+ this [ searchParams ] . push ( key , value ) ;
656
682
}
657
683
} else {
658
684
// record<USVString, USVString>
659
685
this [ searchParams ] = [ ] ;
660
- for ( const key of Object . keys ( init ) ) {
661
- const value = String ( init [ key ] ) ;
686
+ for ( var key of Object . keys ( init ) ) {
687
+ key = toUSVString ( key ) ;
688
+ const value = toUSVString ( init [ key ] ) ;
662
689
this [ searchParams ] . push ( key , value ) ;
663
690
}
664
691
}
665
692
} else {
666
693
// USVString
667
- init = String ( init ) ;
694
+ init = toUSVString ( init ) ;
668
695
if ( init [ 0 ] === '?' ) init = init . slice ( 1 ) ;
669
696
initSearchParams ( this , init ) ;
670
697
}
@@ -743,8 +770,8 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
743
770
throw new TypeError ( '"name" and "value" arguments must be specified' ) ;
744
771
}
745
772
746
- name = String ( name ) ;
747
- value = String ( value ) ;
773
+ name = toUSVString ( name ) ;
774
+ value = toUSVString ( value ) ;
748
775
this [ searchParams ] . push ( name , value ) ;
749
776
update ( this [ context ] , this ) ;
750
777
} ,
@@ -758,7 +785,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
758
785
}
759
786
760
787
const list = this [ searchParams ] ;
761
- name = String ( name ) ;
788
+ name = toUSVString ( name ) ;
762
789
for ( var i = 0 ; i < list . length ; ) {
763
790
const cur = list [ i ] ;
764
791
if ( cur === name ) {
@@ -779,7 +806,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
779
806
}
780
807
781
808
const list = this [ searchParams ] ;
782
- name = String ( name ) ;
809
+ name = toUSVString ( name ) ;
783
810
for ( var i = 0 ; i < list . length ; i += 2 ) {
784
811
if ( list [ i ] === name ) {
785
812
return list [ i + 1 ] ;
@@ -798,7 +825,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
798
825
799
826
const list = this [ searchParams ] ;
800
827
const values = [ ] ;
801
- name = String ( name ) ;
828
+ name = toUSVString ( name ) ;
802
829
for ( var i = 0 ; i < list . length ; i += 2 ) {
803
830
if ( list [ i ] === name ) {
804
831
values . push ( list [ i + 1 ] ) ;
@@ -816,7 +843,7 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
816
843
}
817
844
818
845
const list = this [ searchParams ] ;
819
- name = String ( name ) ;
846
+ name = toUSVString ( name ) ;
820
847
for ( var i = 0 ; i < list . length ; i += 2 ) {
821
848
if ( list [ i ] === name ) {
822
849
return true ;
@@ -834,8 +861,8 @@ defineIDLClass(URLSearchParams.prototype, 'URLSearchParams', {
834
861
}
835
862
836
863
const list = this [ searchParams ] ;
837
- name = String ( name ) ;
838
- value = String ( value ) ;
864
+ name = toUSVString ( name ) ;
865
+ value = toUSVString ( value ) ;
839
866
840
867
// If there are any name-value pairs whose name is `name`, in `list`, set
841
868
// the value of the first such name-value pair to `value` and remove the
@@ -1098,11 +1125,13 @@ function originFor(url, base) {
1098
1125
}
1099
1126
1100
1127
function domainToASCII ( domain ) {
1101
- return binding . domainToASCII ( String ( domain ) ) ;
1128
+ // toUSVString is not needed.
1129
+ return binding . domainToASCII ( '' + domain ) ;
1102
1130
}
1103
1131
1104
1132
function domainToUnicode ( domain ) {
1105
- return binding . domainToUnicode ( String ( domain ) ) ;
1133
+ // toUSVString is not needed.
1134
+ return binding . domainToUnicode ( '' + domain ) ;
1106
1135
}
1107
1136
1108
1137
// Utility function that converts a URL object into an ordinary
@@ -1188,11 +1217,14 @@ function getPathFromURL(path) {
1188
1217
return isWindows ? getPathFromURLWin32 ( path ) : getPathFromURLPosix ( path ) ;
1189
1218
}
1190
1219
1191
- exports . getPathFromURL = getPathFromURL ;
1192
- exports . URL = URL ;
1193
- exports . URLSearchParams = URLSearchParams ;
1194
- exports . domainToASCII = domainToASCII ;
1195
- exports . domainToUnicode = domainToUnicode ;
1196
- exports . urlToOptions = urlToOptions ;
1197
- exports . formatSymbol = kFormat ;
1198
- exports . searchParamsSymbol = searchParams ;
1220
+ module . exports = {
1221
+ toUSVString,
1222
+ getPathFromURL,
1223
+ URL ,
1224
+ URLSearchParams,
1225
+ domainToASCII,
1226
+ domainToUnicode,
1227
+ urlToOptions,
1228
+ formatSymbol : kFormat ,
1229
+ searchParamsSymbol : searchParams
1230
+ } ;
0 commit comments