提交 9e1f5ccb 编写于 作者: D Daijiro Wachi 提交者: Ryan Dahl

Use the same parse processing at contractor of URL with setters (#1549)

上级 7800d9f0
...@@ -7,7 +7,7 @@ interface URLParts { ...@@ -7,7 +7,7 @@ interface URLParts {
password: string; password: string;
hostname: string; hostname: string;
port: string; port: string;
path: string; pathname: string;
query: string; query: string;
hash: string; hash: string;
} }
...@@ -15,7 +15,7 @@ interface URLParts { ...@@ -15,7 +15,7 @@ interface URLParts {
const patterns = { const patterns = {
protocol: "(?:([^:/?#]+):)", protocol: "(?:([^:/?#]+):)",
authority: "(?://([^/?#]*))", authority: "(?://([^/?#]*))",
path: "([^?#]*)", pathname: "([^?#]*)",
query: "(\\?[^#]*)", query: "(\\?[^#]*)",
hash: "(#.*)", hash: "(#.*)",
...@@ -25,7 +25,7 @@ const patterns = { ...@@ -25,7 +25,7 @@ const patterns = {
}; };
const urlRegExp = new RegExp( const urlRegExp = new RegExp(
`^${patterns.protocol}?${patterns.authority}?${patterns.path}${ `^${patterns.protocol}?${patterns.authority}?${patterns.pathname}${
patterns.query patterns.query
}?${patterns.hash}?` }?${patterns.hash}?`
); );
...@@ -40,6 +40,17 @@ const searchParamsMethods: Array<keyof urlSearchParams.URLSearchParams> = [ ...@@ -40,6 +40,17 @@ const searchParamsMethods: Array<keyof urlSearchParams.URLSearchParams> = [
"set" "set"
]; ];
const initializedURLParts = {
protocol: "",
username: "",
password: "",
hostname: "",
port: "",
pathname: "",
query: "",
hash: ""
};
function parse(url: string): URLParts | undefined { function parse(url: string): URLParts | undefined {
const urlMatch = urlRegExp.exec(url); const urlMatch = urlRegExp.exec(url);
if (urlMatch) { if (urlMatch) {
...@@ -54,7 +65,7 @@ function parse(url: string): URLParts | undefined { ...@@ -54,7 +65,7 @@ function parse(url: string): URLParts | undefined {
password: authorityMatch[2] || "", password: authorityMatch[2] || "",
hostname: authorityMatch[3] || "", hostname: authorityMatch[3] || "",
port: authorityMatch[4] || "", port: authorityMatch[4] || "",
path: urlMatch[3] || "", pathname: urlMatch[3] || "",
query: urlMatch[4] || "", query: urlMatch[4] || "",
hash: urlMatch[5] || "" hash: urlMatch[5] || ""
}; };
...@@ -155,7 +166,7 @@ export class URL { ...@@ -155,7 +166,7 @@ export class URL {
} }
get pathname(): string { get pathname(): string {
return this._parts.path ? this._parts.path : "/"; return this._parts.pathname ? this._parts.pathname : "/";
} }
set pathname(value: string) { set pathname(value: string) {
...@@ -163,8 +174,8 @@ export class URL { ...@@ -163,8 +174,8 @@ export class URL {
if (!value || value.charAt(0) !== "/") { if (!value || value.charAt(0) !== "/") {
value = `/${value}`; value = `/${value}`;
} }
// paths can contain % unescaped // pathnames can contain % unescaped
this._parts.path = escape(value).replace(/%25/g, "%"); this._parts.pathname = escape(value).replace(/%25/g, "%");
} }
get port(): string { get port(): string {
...@@ -218,6 +229,15 @@ export class URL { ...@@ -218,6 +229,15 @@ export class URL {
return this._searchParams; return this._searchParams;
} }
get query(): string {
return this._parts.query;
}
set query(value: string) {
value = String(value);
this._parts.query = value;
}
constructor(url: string, base?: string | URL) { constructor(url: string, base?: string | URL) {
let baseParts: URLParts | undefined; let baseParts: URLParts | undefined;
if (base) { if (base) {
...@@ -234,17 +254,24 @@ export class URL { ...@@ -234,17 +254,24 @@ export class URL {
if (urlParts.protocol) { if (urlParts.protocol) {
this._parts = urlParts; this._parts = urlParts;
this.protocol = urlParts.protocol;
this.username = urlParts.username;
this.password = urlParts.password;
this.hostname = urlParts.hostname;
this.port = urlParts.port;
this.pathname = urlParts.pathname;
this.query = urlParts.query;
this.hash = urlParts.hash;
} else if (baseParts) { } else if (baseParts) {
this._parts = { this._parts = initializedURLParts;
protocol: baseParts.protocol, this.protocol = baseParts.protocol;
username: baseParts.username, this.username = baseParts.username;
password: baseParts.password, this.password = baseParts.password;
hostname: baseParts.hostname, this.hostname = baseParts.hostname;
port: baseParts.port, this.port = baseParts.port;
path: urlParts.path || baseParts.path, this.pathname = urlParts.pathname || baseParts.pathname;
query: urlParts.query || baseParts.query, this.query = urlParts.query || baseParts.query;
hash: urlParts.hash this.hash = urlParts.hash;
};
} else { } else {
throw new TypeError("URL requires a base URL."); throw new TypeError("URL requires a base URL.");
} }
......
...@@ -31,6 +31,19 @@ test(function urlParsing() { ...@@ -31,6 +31,19 @@ test(function urlParsing() {
); );
}); });
test(function constractorParsing() {
const url = new URL("http://どめいん.com/ぱす?きー=ばりゅー#はっしゅ");
const { host, pathname, search, hash } = url;
url.host = "どめいん.com";
url.pathname = "/ぱす";
url.search = "?きー=ばりゅー";
url.hash = "#はっしゅ";
assertEqual(host, url.host);
assertEqual(pathname, url.pathname);
assertEqual(search, url.search);
assertEqual(hash, url.hash);
});
test(function urlModifications() { test(function urlModifications() {
const url = new URL( const url = new URL(
"https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat" "https://foo:bar@baz.qat:8000/qux/quux?foo=bar&baz=12#qat"
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册