7
7
ArrayPrototypePush,
8
8
ArrayPrototypeReduce,
9
9
ArrayPrototypeSlice,
10
- FunctionPrototypeBind ,
10
+ Boolean ,
11
11
Int8Array,
12
12
IteratorPrototype,
13
13
Number,
@@ -17,7 +17,6 @@ const {
17
17
ObjectGetOwnPropertySymbols,
18
18
ObjectGetPrototypeOf,
19
19
ObjectKeys,
20
- ObjectPrototypeHasOwnProperty,
21
20
ReflectGetOwnPropertyDescriptor,
22
21
ReflectOwnKeys,
23
22
RegExpPrototypeSymbolReplace,
@@ -537,16 +536,27 @@ ObjectDefineProperties(URLSearchParams.prototype, {
537
536
} ,
538
537
} ) ;
539
538
540
- function isURLThis ( self ) {
541
- return self != null && ObjectPrototypeHasOwnProperty ( self , context ) ;
539
+ /**
540
+ * Checks if a value has the shape of a WHATWG URL object.
541
+ *
542
+ * Using a symbol or instanceof would not be able to recognize URL objects
543
+ * coming from other implementations (e.g. in Electron), so instead we are
544
+ * checking some well known properties for a lack of a better test.
545
+ *
546
+ * @param {* } self
547
+ * @returns {self is URL }
548
+ */
549
+ function isURL ( self ) {
550
+ return Boolean ( self ?. href && self . origin ) ;
542
551
}
543
552
544
553
class URL {
554
+ #context = new URLContext ( ) ;
555
+ #searchParams;
556
+
545
557
constructor ( input , base = undefined ) {
546
558
// toUSVString is not needed.
547
559
input = `${ input } ` ;
548
- this [ context ] = new URLContext ( ) ;
549
- this . #onParseComplete = FunctionPrototypeBind ( this . #onParseComplete, this ) ;
550
560
551
561
if ( base !== undefined ) {
552
562
base = `${ base } ` ;
@@ -562,11 +572,6 @@ class URL {
562
572
}
563
573
564
574
[ inspect . custom ] ( depth , opts ) {
565
- if ( this == null ||
566
- ObjectGetPrototypeOf ( this [ context ] ) !== URLContext . prototype ) {
567
- throw new ERR_INVALID_THIS ( 'URL' ) ;
568
- }
569
-
570
575
if ( typeof depth === 'number' && depth < 0 )
571
576
return this ;
572
577
@@ -587,181 +592,133 @@ class URL {
587
592
obj . hash = this . hash ;
588
593
589
594
if ( opts . showHidden ) {
590
- obj [ context ] = this [ context ] ;
595
+ obj [ context ] = this . # context;
591
596
}
592
597
593
598
return `${ constructor . name } ${ inspect ( obj , opts ) } ` ;
594
599
}
595
600
596
601
#onParseComplete = ( href , origin , protocol , hostname , pathname ,
597
602
search , username , password , port , hash ) => {
598
- const ctx = this [ context ] ;
599
- ctx . href = href ;
600
- ctx . origin = origin ;
601
- ctx . protocol = protocol ;
602
- ctx . hostname = hostname ;
603
- ctx . pathname = pathname ;
604
- ctx . search = search ;
605
- ctx . username = username ;
606
- ctx . password = password ;
607
- ctx . port = port ;
608
- ctx . hash = hash ;
609
- if ( ! this [ searchParams ] ) { // Invoked from URL constructor
610
- this [ searchParams ] = new URLSearchParams ( ) ;
611
- this [ searchParams ] [ context ] = this ;
603
+ this . #context. href = href ;
604
+ this . #context. origin = origin ;
605
+ this . #context. protocol = protocol ;
606
+ this . #context. hostname = hostname ;
607
+ this . #context. pathname = pathname ;
608
+ this . #context. search = search ;
609
+ this . #context. username = username ;
610
+ this . #context. password = password ;
611
+ this . #context. port = port ;
612
+ this . #context. hash = hash ;
613
+ if ( this . #searchParams) {
614
+ this . #searchParams[ searchParams ] = parseParams ( search ) ;
612
615
}
613
- initSearchParams ( this [ searchParams ] , ctx . search ) ;
614
616
} ;
615
617
616
618
toString ( ) {
617
- if ( ! isURLThis ( this ) )
618
- throw new ERR_INVALID_THIS ( 'URL' ) ;
619
- return this [ context ] . href ;
619
+ return this . #context. href ;
620
620
}
621
621
622
622
get href ( ) {
623
- if ( ! isURLThis ( this ) )
624
- throw new ERR_INVALID_THIS ( 'URL' ) ;
625
- return this [ context ] . href ;
623
+ return this . #context. href ;
626
624
}
627
625
628
626
set href ( value ) {
629
- if ( ! isURLThis ( this ) )
630
- throw new ERR_INVALID_THIS ( 'URL' ) ;
631
- const valid = updateUrl ( this [ context ] . href , updateActions . kHref , `${ value } ` , this . #onParseComplete) ;
627
+ const valid = updateUrl ( this . #context. href , updateActions . kHref , `${ value } ` , this . #onParseComplete) ;
632
628
if ( ! valid ) { throw ERR_INVALID_URL ( `${ value } ` ) ; }
633
629
}
634
630
635
631
// readonly
636
632
get origin ( ) {
637
- if ( ! isURLThis ( this ) )
638
- throw new ERR_INVALID_THIS ( 'URL' ) ;
639
- return this [ context ] . origin ;
633
+ return this . #context. origin ;
640
634
}
641
635
642
636
get protocol ( ) {
643
- if ( ! isURLThis ( this ) )
644
- throw new ERR_INVALID_THIS ( 'URL' ) ;
645
- return this [ context ] . protocol ;
637
+ return this . #context. protocol ;
646
638
}
647
639
648
640
set protocol ( value ) {
649
- if ( ! isURLThis ( this ) )
650
- throw new ERR_INVALID_THIS ( 'URL' ) ;
651
- updateUrl ( this [ context ] . href , updateActions . kProtocol , `${ value } ` , this . #onParseComplete) ;
641
+ updateUrl ( this . #context. href , updateActions . kProtocol , `${ value } ` , this . #onParseComplete) ;
652
642
}
653
643
654
644
get username ( ) {
655
- if ( ! isURLThis ( this ) )
656
- throw new ERR_INVALID_THIS ( 'URL' ) ;
657
- return this [ context ] . username ;
645
+ return this . #context. username ;
658
646
}
659
647
660
648
set username ( value ) {
661
- if ( ! isURLThis ( this ) )
662
- throw new ERR_INVALID_THIS ( 'URL' ) ;
663
- updateUrl ( this [ context ] . href , updateActions . kUsername , `${ value } ` , this . #onParseComplete) ;
649
+ updateUrl ( this . #context. href , updateActions . kUsername , `${ value } ` , this . #onParseComplete) ;
664
650
}
665
651
666
652
get password ( ) {
667
- if ( ! isURLThis ( this ) )
668
- throw new ERR_INVALID_THIS ( 'URL' ) ;
669
- return this [ context ] . password ;
653
+ return this . #context. password ;
670
654
}
671
655
672
656
set password ( value ) {
673
- if ( ! isURLThis ( this ) )
674
- throw new ERR_INVALID_THIS ( 'URL' ) ;
675
- updateUrl ( this [ context ] . href , updateActions . kPassword , `${ value } ` , this . #onParseComplete) ;
657
+ updateUrl ( this . #context. href , updateActions . kPassword , `${ value } ` , this . #onParseComplete) ;
676
658
}
677
659
678
660
get host ( ) {
679
- if ( ! isURLThis ( this ) )
680
- throw new ERR_INVALID_THIS ( 'URL' ) ;
681
- const port = this [ context ] . port ;
661
+ const port = this . #context. port ;
682
662
const suffix = port . length > 0 ? `:${ port } ` : '' ;
683
- return this [ context ] . hostname + suffix ;
663
+ return this . # context. hostname + suffix ;
684
664
}
685
665
686
666
set host ( value ) {
687
- if ( ! isURLThis ( this ) )
688
- throw new ERR_INVALID_THIS ( 'URL' ) ;
689
- updateUrl ( this [ context ] . href , updateActions . kHost , `${ value } ` , this . #onParseComplete) ;
667
+ updateUrl ( this . #context. href , updateActions . kHost , `${ value } ` , this . #onParseComplete) ;
690
668
}
691
669
692
670
get hostname ( ) {
693
- if ( ! isURLThis ( this ) )
694
- throw new ERR_INVALID_THIS ( 'URL' ) ;
695
- return this [ context ] . hostname ;
671
+ return this . #context. hostname ;
696
672
}
697
673
698
674
set hostname ( value ) {
699
- if ( ! isURLThis ( this ) )
700
- throw new ERR_INVALID_THIS ( 'URL' ) ;
701
- updateUrl ( this [ context ] . href , updateActions . kHostname , `${ value } ` , this . #onParseComplete) ;
675
+ updateUrl ( this . #context. href , updateActions . kHostname , `${ value } ` , this . #onParseComplete) ;
702
676
}
703
677
704
678
get port ( ) {
705
- if ( ! isURLThis ( this ) )
706
- throw new ERR_INVALID_THIS ( 'URL' ) ;
707
- return this [ context ] . port ;
679
+ return this . #context. port ;
708
680
}
709
681
710
682
set port ( value ) {
711
- if ( ! isURLThis ( this ) )
712
- throw new ERR_INVALID_THIS ( 'URL' ) ;
713
- updateUrl ( this [ context ] . href , updateActions . kPort , `${ value } ` , this . #onParseComplete) ;
683
+ updateUrl ( this . #context. href , updateActions . kPort , `${ value } ` , this . #onParseComplete) ;
714
684
}
715
685
716
686
get pathname ( ) {
717
- if ( ! isURLThis ( this ) )
718
- throw new ERR_INVALID_THIS ( 'URL' ) ;
719
- return this [ context ] . pathname ;
687
+ return this . #context. pathname ;
720
688
}
721
689
722
690
set pathname ( value ) {
723
- if ( ! isURLThis ( this ) )
724
- throw new ERR_INVALID_THIS ( 'URL' ) ;
725
- updateUrl ( this [ context ] . href , updateActions . kPathname , `${ value } ` , this . #onParseComplete) ;
691
+ updateUrl ( this . #context. href , updateActions . kPathname , `${ value } ` , this . #onParseComplete) ;
726
692
}
727
693
728
694
get search ( ) {
729
- if ( ! isURLThis ( this ) )
730
- throw new ERR_INVALID_THIS ( 'URL' ) ;
731
- return this [ context ] . search ;
695
+ return this . #context. search ;
732
696
}
733
697
734
- set search ( search ) {
735
- if ( ! isURLThis ( this ) )
736
- throw new ERR_INVALID_THIS ( 'URL' ) ;
737
- search = toUSVString ( search ) ;
738
- updateUrl ( this [ context ] . href , updateActions . kSearch , search , this . #onParseComplete) ;
739
- initSearchParams ( this [ searchParams ] , this [ context ] . search ) ;
698
+ set search ( value ) {
699
+ updateUrl ( this . #context. href , updateActions . kSearch , toUSVString ( value ) , this . #onParseComplete) ;
740
700
}
741
701
742
702
// readonly
743
703
get searchParams ( ) {
744
- if ( ! isURLThis ( this ) )
745
- throw new ERR_INVALID_THIS ( 'URL' ) ;
746
- return this [ searchParams ] ;
704
+ // Create URLSearchParams on demand to greatly improve the URL performance.
705
+ if ( this . #searchParams == null ) {
706
+ this . #searchParams = new URLSearchParams ( this . #context. search ) ;
707
+ this . #searchParams[ context ] = this ;
708
+ }
709
+ return this . #searchParams;
747
710
}
748
711
749
712
get hash ( ) {
750
- if ( ! isURLThis ( this ) )
751
- throw new ERR_INVALID_THIS ( 'URL' ) ;
752
- return this [ context ] . hash ;
713
+ return this . #context. hash ;
753
714
}
754
715
755
716
set hash ( value ) {
756
- if ( ! isURLThis ( this ) )
757
- throw new ERR_INVALID_THIS ( 'URL' ) ;
758
- updateUrl ( this [ context ] . href , updateActions . kHash , `${ value } ` , this . #onParseComplete) ;
717
+ updateUrl ( this . #context. href , updateActions . kHash , `${ value } ` , this . #onParseComplete) ;
759
718
}
760
719
761
720
toJSON ( ) {
762
- if ( ! isURLThis ( this ) )
763
- throw new ERR_INVALID_THIS ( 'URL' ) ;
764
- return this [ context ] . href ;
721
+ return this . #context. href ;
765
722
}
766
723
767
724
static createObjectURL ( obj ) {
@@ -1219,7 +1176,7 @@ function getPathFromURLPosix(url) {
1219
1176
function fileURLToPath ( path ) {
1220
1177
if ( typeof path === 'string' )
1221
1178
path = new URL ( path ) ;
1222
- else if ( ! isURLInstance ( path ) )
1179
+ else if ( ! isURL ( path ) )
1223
1180
throw new ERR_INVALID_ARG_TYPE ( 'path' , [ 'string' , 'URL' ] , path ) ;
1224
1181
if ( path . protocol !== 'file:' )
1225
1182
throw new ERR_INVALID_URL_SCHEME ( 'file' ) ;
@@ -1295,12 +1252,8 @@ function pathToFileURL(filepath) {
1295
1252
return outURL ;
1296
1253
}
1297
1254
1298
- function isURLInstance ( fileURLOrPath ) {
1299
- return fileURLOrPath != null && fileURLOrPath . href && fileURLOrPath . origin ;
1300
- }
1301
-
1302
1255
function toPathIfFileURL ( fileURLOrPath ) {
1303
- if ( ! isURLInstance ( fileURLOrPath ) )
1256
+ if ( ! isURL ( fileURLOrPath ) )
1304
1257
return fileURLOrPath ;
1305
1258
return fileURLToPath ( fileURLOrPath ) ;
1306
1259
}
@@ -1310,12 +1263,12 @@ module.exports = {
1310
1263
fileURLToPath,
1311
1264
pathToFileURL,
1312
1265
toPathIfFileURL,
1313
- isURLInstance,
1314
1266
URL ,
1315
1267
URLSearchParams,
1316
1268
domainToASCII,
1317
1269
domainToUnicode,
1318
1270
urlToHttpOptions,
1319
1271
searchParamsSymbol : searchParams ,
1320
1272
encodeStr,
1273
+ isURL,
1321
1274
} ;
0 commit comments