@@ -98,6 +98,24 @@ function lolcation(loc) {
9898 return finaldestination ;
9999}
100100
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+
101119/**
102120 * @typedef ProtocolExtract
103121 * @type Object
@@ -110,16 +128,32 @@ function lolcation(loc) {
110128 * Extract protocol information from a URL with/without double slash ("//").
111129 *
112130 * @param {String } address URL we want to extract from.
131+ * @param {Object } location
113132 * @return {ProtocolExtract } Extracted information.
114133 * @private
115134 */
116- function extractProtocol ( address ) {
135+ function extractProtocol ( address , location ) {
117136 address = trimLeft ( address ) ;
137+ location = location || { } ;
118138
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+ }
123157
124158 return {
125159 protocol : protocol ,
@@ -214,7 +248,7 @@ function Url(address, location, parser) {
214248 //
215249 // Extract protocol information before running the instructions.
216250 //
217- extracted = extractProtocol ( address || '' ) ;
251+ extracted = extractProtocol ( address || '' , location ) ;
218252 relative = ! extracted . protocol && ! extracted . slashes ;
219253 url . slashes = extracted . slashes || relative && location . slashes ;
220254 url . protocol = extracted . protocol || location . protocol || '' ;
@@ -224,7 +258,10 @@ function Url(address, location, parser) {
224258 // When the authority component is absent the URL starts with a path
225259 // component.
226260 //
227- if ( ! extracted . slashes || url . protocol === 'file:' ) {
261+ if (
262+ url . protocol === 'file:' ||
263+ ( ! extracted . slashes && ! isSpecial ( extracted . protocol ) )
264+ ) {
228265 instructions [ 3 ] = [ / ( .* ) / , 'pathname' ] ;
229266 }
230267
0 commit comments