Skip to content

Commit e3d9840

Browse files
committed
Apply syntax changes proposed in whatwg/urlpattern#179.
1 parent e0b1d0c commit e3d9840

File tree

2 files changed

+66
-30
lines changed

2 files changed

+66
-30
lines changed

src/url-pattern-parser.ts

+32-18
Original file line numberDiff line numberDiff line change
@@ -106,11 +106,8 @@ export class Parser {
106106
this.#changeState(State.HASH, /*skip=*/1);
107107
} else if (this.#isSearchPrefix()) {
108108
this.#changeState(State.SEARCH, /*skip=*/1);
109-
this.#internalResult.hash = '';
110109
} else {
111110
this.#changeState(State.PATHNAME, /*skip=*/0);
112-
this.#internalResult.search = '';
113-
this.#internalResult.hash = '';
114111
}
115112
continue;
116113
}
@@ -147,17 +144,6 @@ export class Parser {
147144
switch (this.#state) {
148145
case State.INIT:
149146
if (this.#isProtocolSuffix()) {
150-
// We are in absolute mode and we know values will not be inherited
151-
// from a base URL. Therefore initialize the rest of the components
152-
// to the empty string.
153-
this.#internalResult.username = '';
154-
this.#internalResult.password = '';
155-
this.#internalResult.hostname = '';
156-
this.#internalResult.port = '';
157-
this.#internalResult.pathname = '';
158-
this.#internalResult.search = '';
159-
this.#internalResult.hash = '';
160-
161147
// Update the state to expect the start of an absolute URL.
162148
this.#rewindAndSetState(State.PROTOCOL);
163149
}
@@ -179,10 +165,6 @@ export class Parser {
179165
let nextState: State = State.PATHNAME;
180166
let skip: number = 1;
181167

182-
if (this.#shouldTreatAsStandardURL) {
183-
this.#internalResult.pathname = '/';
184-
}
185-
186168
// If there are authority slashes, like `https://`, then
187169
// we must transition to the authority section of the URLPattern.
188170
if (this.#nextIsAuthoritySlashes()) {
@@ -319,6 +301,13 @@ export class Parser {
319301
break;
320302
}
321303
}
304+
305+
if (this.#internalResult.hostname !== undefined &&
306+
this.#internalResult.port === undefined) {
307+
// If the hostname is specified in a constructor string but the port is
308+
// not, the default port is assumed to be meant.
309+
this.#internalResult.port = '';
310+
}
322311
}
323312

324313
#changeState(newState: State, skip: number): void {
@@ -358,6 +347,31 @@ export class Parser {
358347
break;
359348
}
360349

350+
if (this.#state !== State.INIT && newState !== State.DONE) {
351+
// If hostname, pathname or search is skipped but something appears after
352+
// it, then it takes its default value (usually the empty string).
353+
if ([State.PROTOCOL, State.AUTHORITY, State.USERNAME, State.PASSWORD]
354+
.includes(this.#state) &&
355+
[State.PORT, State.PATHNAME, State.SEARCH, State.HASH]
356+
.includes(newState)) {
357+
this.#internalResult.hostname ??= '';
358+
}
359+
if ([State.PROTOCOL, State.AUTHORITY, State.USERNAME, State.PASSWORD,
360+
State.HOSTNAME, State.PORT]
361+
.includes(this.#state) &&
362+
[State.SEARCH, State.HASH]
363+
.includes(newState)) {
364+
this.#internalResult.pathname ??=
365+
(this.#shouldTreatAsStandardURL ? '/' : '');
366+
}
367+
if ([State.PROTOCOL, State.AUTHORITY, State.USERNAME, State.PASSWORD,
368+
State.HOSTNAME, State.PORT, State.PATHNAME]
369+
.includes(this.#state) &&
370+
newState === State.HASH) {
371+
this.#internalResult.search ??= '';
372+
}
373+
}
374+
361375
this.#changeStateWithoutSettingComponent(newState, skip);
362376
}
363377

src/url-pattern.ts

+34-12
Original file line numberDiff line numberDiff line change
@@ -77,22 +77,44 @@ function processBaseURLString(input: string, isPattern: boolean) {
7777
function applyInit(o: URLPatternInit, init: URLPatternInit, isPattern: boolean): URLPatternInit {
7878
// If there is a baseURL we need to apply its component values first. The
7979
// rest of the URLPatternInit structure will then later override these
80-
// values. Note, the baseURL will always set either an empty string or
81-
// longer value for each considered component. We do not allow null strings
82-
// to persist for these components past this phase since they should no
83-
// longer be treated as wildcards.
80+
// values.
8481
let baseURL;
8582
if (typeof init.baseURL === 'string') {
8683
try {
8784
baseURL = new URL(init.baseURL);
88-
o.protocol = processBaseURLString(baseURL.protocol.substring(0, baseURL.protocol.length - 1), isPattern);
89-
o.username = processBaseURLString(baseURL.username, isPattern);
90-
o.password = processBaseURLString(baseURL.password, isPattern);
91-
o.hostname = processBaseURLString(baseURL.hostname, isPattern);
92-
o.port = processBaseURLString(baseURL.port, isPattern);
93-
o.pathname = processBaseURLString(baseURL.pathname, isPattern);
94-
o.search = processBaseURLString(baseURL.search.substring(1, baseURL.search.length), isPattern);
95-
o.hash = processBaseURLString(baseURL.hash.substring(1, baseURL.hash.length), isPattern);
85+
if (init.protocol === undefined) {
86+
o.protocol = processBaseURLString(baseURL.protocol.substring(0, baseURL.protocol.length - 1), isPattern);
87+
}
88+
if (!isPattern && init.protocol === undefined && init.hostname === undefined &&
89+
init.port === undefined && init.username === undefined) {
90+
o.username = processBaseURLString(baseURL.username, isPattern);
91+
}
92+
if (!isPattern && init.protocol === undefined && init.hostname === undefined &&
93+
init.port === undefined && init.username === undefined &&
94+
init.password === undefined) {
95+
o.password = processBaseURLString(baseURL.password, isPattern);
96+
}
97+
if (init.protocol === undefined && init.hostname === undefined) {
98+
o.hostname = processBaseURLString(baseURL.hostname, isPattern);
99+
}
100+
if (init.protocol === undefined && init.hostname === undefined &&
101+
init.port === undefined) {
102+
o.port = processBaseURLString(baseURL.port, isPattern);
103+
}
104+
if (init.protocol === undefined && init.hostname === undefined &&
105+
init.port === undefined && init.pathname === undefined) {
106+
o.pathname = processBaseURLString(baseURL.pathname, isPattern);
107+
}
108+
if (init.protocol === undefined && init.hostname === undefined &&
109+
init.port === undefined && init.pathname === undefined &&
110+
init.search === undefined) {
111+
o.search = processBaseURLString(baseURL.search.substring(1, baseURL.search.length), isPattern);
112+
}
113+
if (init.protocol === undefined && init.hostname === undefined &&
114+
init.port === undefined && init.pathname === undefined &&
115+
init.search === undefined && init.hash === undefined) {
116+
o.hash = processBaseURLString(baseURL.hash.substring(1, baseURL.hash.length), isPattern);
117+
}
96118
} catch {
97119
throw new TypeError(`invalid baseURL '${init.baseURL}'.`);
98120
}

0 commit comments

Comments
 (0)