urltomarkdown/node_modules/domino/lib/URLUtils.js

271 lines
6.9 KiB
JavaScript
Executable File

"use strict";
var URL = require('./URL');
module.exports = URLUtils;
// Allow the `x == null` pattern. This is eslint's "null: 'ignore'" option,
// but jshint doesn't support this.
/* jshint eqeqeq: false */
// This is an abstract superclass for Location, HTMLAnchorElement and
// other types that have the standard complement of "URL decomposition
// IDL attributes". This is now standardized as URLUtils, see:
// https://url.spec.whatwg.org/#urlutils
// Subclasses must define a getter/setter on href.
// The getter and setter methods parse and rebuild the URL on each
// invocation; there is no attempt to cache the value and be more efficient
function URLUtils() {}
URLUtils.prototype = Object.create(Object.prototype, {
_url: { get: function() {
// XXX: this should do the "Reinitialize url" steps, and "null" should
// be a valid return value.
return new URL(this.href);
} },
protocol: {
get: function() {
var url = this._url;
if (url && url.scheme) return url.scheme + ":";
else return ":";
},
set: function(v) {
var output = this.href;
var url = new URL(output);
if (url.isAbsolute()) {
v = v.replace(/:+$/, "");
v = v.replace(/[^-+\.a-zA-Z0-9]/g, URL.percentEncode);
if (v.length > 0) {
url.scheme = v;
output = url.toString();
}
}
this.href = output;
},
},
host: {
get: function() {
var url = this._url;
if (url.isAbsolute() && url.isAuthorityBased())
return url.host + (url.port ? (":" + url.port) : "");
else
return "";
},
set: function(v) {
var output = this.href;
var url = new URL(output);
if (url.isAbsolute() && url.isAuthorityBased()) {
v = v.replace(/[^-+\._~!$&'()*,;:=a-zA-Z0-9]/g, URL.percentEncode);
if (v.length > 0) {
url.host = v;
delete url.port;
output = url.toString();
}
}
this.href = output;
},
},
hostname: {
get: function() {
var url = this._url;
if (url.isAbsolute() && url.isAuthorityBased())
return url.host;
else
return "";
},
set: function(v) {
var output = this.href;
var url = new URL(output);
if (url.isAbsolute() && url.isAuthorityBased()) {
v = v.replace(/^\/+/, "");
v = v.replace(/[^-+\._~!$&'()*,;:=a-zA-Z0-9]/g, URL.percentEncode);
if (v.length > 0) {
url.host = v;
output = url.toString();
}
}
this.href = output;
},
},
port: {
get: function() {
var url = this._url;
if (url.isAbsolute() && url.isAuthorityBased() && url.port!==undefined)
return url.port;
else
return "";
},
set: function(v) {
var output = this.href;
var url = new URL(output);
if (url.isAbsolute() && url.isAuthorityBased()) {
v = '' + v;
v = v.replace(/[^0-9].*$/, "");
v = v.replace(/^0+/, "");
if (v.length === 0) v = "0";
if (parseInt(v, 10) <= 65535) {
url.port = v;
output = url.toString();
}
}
this.href = output;
},
},
pathname: {
get: function() {
var url = this._url;
if (url.isAbsolute() && url.isHierarchical())
return url.path;
else
return "";
},
set: function(v) {
var output = this.href;
var url = new URL(output);
if (url.isAbsolute() && url.isHierarchical()) {
if (v.charAt(0) !== "/")
v = "/" + v;
v = v.replace(/[^-+\._~!$&'()*,;:=@\/a-zA-Z0-9]/g, URL.percentEncode);
url.path = v;
output = url.toString();
}
this.href = output;
},
},
search: {
get: function() {
var url = this._url;
if (url.isAbsolute() && url.isHierarchical() && url.query!==undefined)
return "?" + url.query;
else
return "";
},
set: function(v) {
var output = this.href;
var url = new URL(output);
if (url.isAbsolute() && url.isHierarchical()) {
if (v.charAt(0) === "?") v = v.substring(1);
v = v.replace(/[^-+\._~!$&'()*,;:=@\/?a-zA-Z0-9]/g, URL.percentEncode);
url.query = v;
output = url.toString();
}
this.href = output;
},
},
hash: {
get: function() {
var url = this._url;
if (url == null || url.fragment == null || url.fragment === '') {
return "";
} else {
return "#" + url.fragment;
}
},
set: function(v) {
var output = this.href;
var url = new URL(output);
if (v.charAt(0) === "#") v = v.substring(1);
v = v.replace(/[^-+\._~!$&'()*,;:=@\/?a-zA-Z0-9]/g, URL.percentEncode);
url.fragment = v;
output = url.toString();
this.href = output;
},
},
username: {
get: function() {
var url = this._url;
return url.username || '';
},
set: function(v) {
var output = this.href;
var url = new URL(output);
if (url.isAbsolute()) {
v = v.replace(/[\x00-\x1F\x7F-\uFFFF "#<>?`\/@\\:]/g, URL.percentEncode);
url.username = v;
output = url.toString();
}
this.href = output;
},
},
password: {
get: function() {
var url = this._url;
return url.password || '';
},
set: function(v) {
var output = this.href;
var url = new URL(output);
if (url.isAbsolute()) {
if (v==='') {
url.password = null;
} else {
v = v.replace(/[\x00-\x1F\x7F-\uFFFF "#<>?`\/@\\]/g, URL.percentEncode);
url.password = v;
}
output = url.toString();
}
this.href = output;
},
},
origin: { get: function() {
var url = this._url;
if (url == null) { return ''; }
var originForPort = function(defaultPort) {
var origin = [url.scheme, url.host, +url.port || defaultPort];
// XXX should be "unicode serialization"
return origin[0] + '://' + origin[1] +
(origin[2] === defaultPort ? '' : (':' + origin[2]));
};
switch (url.scheme) {
case 'ftp':
return originForPort(21);
case 'gopher':
return originForPort(70);
case 'http':
case 'ws':
return originForPort(80);
case 'https':
case 'wss':
return originForPort(443);
default:
// this is what chrome does
return url.scheme + '://';
}
} },
/*
searchParams: {
get: function() {
var url = this._url;
// XXX
},
set: function(v) {
var output = this.href;
var url = new URL(output);
// XXX
this.href = output;
},
},
*/
});
URLUtils._inherit = function(proto) {
// copy getters/setters from URLUtils to o.
Object.getOwnPropertyNames(URLUtils.prototype).forEach(function(p) {
if (p==='constructor' || p==='href') { return; }
var desc = Object.getOwnPropertyDescriptor(URLUtils.prototype, p);
Object.defineProperty(proto, p, desc);
});
};