@@ -27,6 +27,8 @@ const {
27
27
ObjectAssign,
28
28
ObjectKeys,
29
29
StringPrototypeCharCodeAt,
30
+ StringPrototypeIndexOf,
31
+ StringPrototypeSlice,
30
32
decodeURIComponent,
31
33
} = primordials ;
32
34
@@ -637,6 +639,10 @@ Url.prototype.format = function format() {
637
639
}
638
640
639
641
let protocol = this . protocol || '' ;
642
+ if ( protocol && StringPrototypeCharCodeAt ( protocol , protocol . length - 1 ) !== 58 /* : */ ) {
643
+ protocol += ':' ;
644
+ }
645
+
640
646
let pathname = this . pathname || '' ;
641
647
let hash = this . hash || '' ;
642
648
let host = '' ;
@@ -646,7 +652,7 @@ Url.prototype.format = function format() {
646
652
host = auth + this . host ;
647
653
} else if ( this . hostname ) {
648
654
host = auth + (
649
- this . hostname . includes ( ':' ) && ! isIpv6Hostname ( this . hostname ) ?
655
+ StringPrototypeIndexOf ( this . hostname , ':' ) !== - 1 && ! isIpv6Hostname ( this . hostname ) ?
650
656
'[' + this . hostname + ']' :
651
657
this . hostname
652
658
) ;
@@ -658,59 +664,55 @@ Url.prototype.format = function format() {
658
664
if ( this . query !== null && typeof this . query === 'object' ) {
659
665
query = querystring . stringify ( this . query ) ;
660
666
}
661
-
662
667
let search = this . search || ( query && ( '?' + query ) ) || '' ;
663
668
664
- if ( protocol && protocol . charCodeAt ( protocol . length - 1 ) !== 58 /* : */ )
665
- protocol += ':' ;
666
-
667
- let newPathname = '' ;
668
- let lastPos = 0 ;
669
- for ( let i = 0 ; i < pathname . length ; ++ i ) {
670
- switch ( pathname . charCodeAt ( i ) ) {
671
- case CHAR_HASH :
672
- if ( i - lastPos > 0 )
673
- newPathname += pathname . slice ( lastPos , i ) ;
674
- newPathname += '%23' ;
675
- lastPos = i + 1 ;
676
- break ;
677
- case CHAR_QUESTION_MARK :
678
- if ( i - lastPos > 0 )
679
- newPathname += pathname . slice ( lastPos , i ) ;
680
- newPathname += '%3F' ;
669
+ if ( StringPrototypeIndexOf ( pathname , '#' ) !== - 1 || StringPrototypeIndexOf ( pathname , '?' ) !== - 1 ) {
670
+ let newPathname = '' ;
671
+ let lastPos = 0 ;
672
+ const len = pathname . length ;
673
+ for ( let i = 0 ; i < len ; i ++ ) {
674
+ const code = StringPrototypeCharCodeAt ( pathname , i ) ;
675
+ if ( code === CHAR_HASH || code === CHAR_QUESTION_MARK ) {
676
+ if ( i > lastPos ) {
677
+ newPathname += StringPrototypeSlice ( pathname , lastPos , i ) ;
678
+ }
679
+ newPathname += ( code === CHAR_HASH ? '%23' : '%3F' ) ;
681
680
lastPos = i + 1 ;
682
- break ;
681
+ }
683
682
}
684
- }
685
- if ( lastPos > 0 ) {
686
- if ( lastPos !== pathname . length )
687
- pathname = newPathname + pathname . slice ( lastPos ) ;
688
- else
689
- pathname = newPathname ;
683
+ if ( lastPos < len ) {
684
+ newPathname += StringPrototypeSlice ( pathname , lastPos ) ;
685
+ }
686
+ pathname = newPathname ;
690
687
}
691
688
692
689
// Only the slashedProtocols get the //. Not mailto:, xmpp:, etc.
693
690
// unless they had them to begin with.
694
691
if ( this . slashes || slashedProtocol . has ( protocol ) ) {
695
692
if ( this . slashes || host ) {
696
- if ( pathname && pathname . charCodeAt ( 0 ) !== CHAR_FORWARD_SLASH )
693
+ if ( pathname && StringPrototypeCharCodeAt ( pathname , 0 ) !== CHAR_FORWARD_SLASH )
697
694
pathname = '/' + pathname ;
698
695
host = '//' + host ;
699
696
} else if ( protocol . length >= 4 &&
700
- protocol . charCodeAt ( 0 ) === 102 /* f */ &&
701
- protocol . charCodeAt ( 1 ) === 105 /* i */ &&
702
- protocol . charCodeAt ( 2 ) === 108 /* l */ &&
703
- protocol . charCodeAt ( 3 ) === 101 /* e */ ) {
697
+ StringPrototypeCharCodeAt ( protocol , 0 ) === 102 /* f */ &&
698
+ StringPrototypeCharCodeAt ( protocol , 1 ) === 105 /* i */ &&
699
+ StringPrototypeCharCodeAt ( protocol , 2 ) === 108 /* l */ &&
700
+ StringPrototypeCharCodeAt ( protocol , 3 ) === 101 /* e */ ) {
704
701
host = '//' ;
705
702
}
706
703
}
707
704
708
- search = search . replaceAll ( '#' , '%23' ) ;
705
+ // Escape '#' in search.
706
+ if ( search . indexOf ( '#' ) !== - 1 ) {
707
+ search = search . replace ( / # / g, '%23' ) ;
708
+ }
709
709
710
- if ( hash && hash . charCodeAt ( 0 ) !== CHAR_HASH )
710
+ if ( hash && StringPrototypeCharCodeAt ( hash , 0 ) !== CHAR_HASH ) {
711
711
hash = '#' + hash ;
712
- if ( search && search . charCodeAt ( 0 ) !== CHAR_QUESTION_MARK )
712
+ }
713
+ if ( search && StringPrototypeCharCodeAt ( search , 0 ) !== CHAR_QUESTION_MARK ) {
713
714
search = '?' + search ;
715
+ }
714
716
715
717
return protocol + host + pathname + search + hash ;
716
718
} ;
0 commit comments