in packages/rum-core/src/common/url.js [82:181]
constructor(url) {
let { protocol, address, slashes } = this.extractProtocol(url || '')
const relative = !protocol && !slashes
const location = this.getLocation()
const instructions = RULES.slice()
// Sanitize what is left of the address
address = address.replace('\\', '/')
/**
* When the authority component is absent the URL starts with a path component.
* By setting it as NaN, we set the remaining parsed address to path
*/
if (!slashes) {
instructions[2] = [NaN, 'path']
}
let index
for (let i = 0; i < instructions.length; i++) {
const instruction = instructions[i]
const parse = instruction[0]
const key = instruction[1]
if (typeof parse === 'string') {
index = address.indexOf(parse)
if (~index) {
const instLength = instruction[2]
if (instLength) {
/**
* we need to figure out the explicit index where the auth portion
* in the host ends before parsing the rest of the URL as host.
*
* ex: http://a@b@c.com/d
* auth -> a@b
* host -> c.com
*/
let newIndex = address.lastIndexOf(parse)
index = Math.max(index, newIndex)
this[key] = address.slice(0, index)
address = address.slice(index + instLength)
} else {
this[key] = address.slice(index)
address = address.slice(0, index)
}
}
} else {
/** NaN condition */
this[key] = address
address = ''
}
/**
* Default values for all keys from location if url is relative
*/
this[key] =
this[key] || (relative && instruction[3] ? location[key] || '' : '')
/**
* host should be lowercased so they can be used to
* create a proper `origin`.
*/
if (instruction[3]) this[key] = this[key].toLowerCase()
}
/**
* if the URL is relative, prepend the path with `/`
* to construct the href correctly
*/
if (relative && this.path.charAt(0) !== '/') {
this.path = '/' + this.path
}
this.relative = relative
this.protocol = protocol || location.protocol
/**
* Construct port and hostname from host
*
* Port numbers are not added for default ports of a given protocol
* and hostname would match host when port is not present
*/
this.hostname = this.host
this.port = ''
if (/:\d+$/.test(this.host)) {
const value = this.host.split(':')
const port = value.pop()
const hostname = value.join(':')
if (isDefaultPort(port, this.protocol)) {
this.host = hostname
} else {
this.port = port
}
this.hostname = hostname
}
this.origin =
this.protocol && this.host && this.protocol !== 'file:'
? this.protocol + '//' + this.host
: 'null'
this.href = this.toString()
}