@@ -98,6 +98,24 @@ function lolcation(loc) {
98
98
return finaldestination ;
99
99
}
100
100
101
+ /**
102
+ * Check whether a protocol scheme is special.
103
+ *
104
+ * @param {String } The protocol scheme of the URL
105
+ * @return {Boolean } `true` if the protocol scheme is special, else `false`
106
+ * @private
107
+ */
108
+ function isSpecial ( scheme ) {
109
+ return (
110
+ scheme === 'ftp:' ||
111
+ scheme === 'file:' ||
112
+ scheme === 'http:' ||
113
+ scheme === 'https:' ||
114
+ scheme === 'ws:' ||
115
+ scheme === 'wss:'
116
+ ) ;
117
+ }
118
+
101
119
/**
102
120
* @typedef ProtocolExtract
103
121
* @type Object
@@ -110,16 +128,32 @@ function lolcation(loc) {
110
128
* Extract protocol information from a URL with/without double slash ("//").
111
129
*
112
130
* @param {String } address URL we want to extract from.
131
+ * @param {Object } location
113
132
* @return {ProtocolExtract } Extracted information.
114
133
* @private
115
134
*/
116
- function extractProtocol ( address ) {
135
+ function extractProtocol ( address , location ) {
117
136
address = trimLeft ( address ) ;
137
+ location = location || { } ;
118
138
119
- var match = protocolre . exec ( address )
120
- , protocol = match [ 1 ] ? match [ 1 ] . toLowerCase ( ) : ''
121
- , slashes = ! ! ( match [ 2 ] && match [ 2 ] . length >= 2 )
122
- , rest = match [ 2 ] && match [ 2 ] . length === 1 ? '/' + match [ 3 ] : match [ 3 ] ;
139
+ var match = protocolre . exec ( address ) ;
140
+ var protocol = match [ 1 ] ? match [ 1 ] . toLowerCase ( ) : '' ;
141
+ var rest = match [ 2 ] ? match [ 2 ] + match [ 3 ] : match [ 3 ] ;
142
+ var slashes = ! ! ( match [ 2 ] && match [ 2 ] . length >= 2 ) ;
143
+
144
+ if ( protocol === 'file:' ) {
145
+ if ( slashes ) {
146
+ rest = rest . slice ( 2 ) ;
147
+ }
148
+ } else if ( isSpecial ( protocol ) ) {
149
+ rest = match [ 3 ] ;
150
+ } else if ( protocol ) {
151
+ if ( rest . indexOf ( '//' ) === 0 ) {
152
+ rest = rest . slice ( 2 ) ;
153
+ }
154
+ } else if ( slashes && location . hostname ) {
155
+ rest = match [ 3 ] ;
156
+ }
123
157
124
158
return {
125
159
protocol : protocol ,
@@ -214,7 +248,7 @@ function Url(address, location, parser) {
214
248
//
215
249
// Extract protocol information before running the instructions.
216
250
//
217
- extracted = extractProtocol ( address || '' ) ;
251
+ extracted = extractProtocol ( address || '' , location ) ;
218
252
relative = ! extracted . protocol && ! extracted . slashes ;
219
253
url . slashes = extracted . slashes || relative && location . slashes ;
220
254
url . protocol = extracted . protocol || location . protocol || '' ;
@@ -224,7 +258,10 @@ function Url(address, location, parser) {
224
258
// When the authority component is absent the URL starts with a path
225
259
// component.
226
260
//
227
- if ( ! extracted . slashes || url . protocol === 'file:' ) {
261
+ if (
262
+ url . protocol === 'file:' ||
263
+ ( ! extracted . slashes && ! isSpecial ( extracted . protocol ) )
264
+ ) {
228
265
instructions [ 3 ] = [ / ( .* ) / , 'pathname' ] ;
229
266
}
230
267
0 commit comments