Skip to content

Commit

Permalink
Apply syntax changes proposed in whatwg/urlpattern#179.
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremyroman committed Nov 3, 2023
1 parent e0b1d0c commit e3d9840
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 30 deletions.
50 changes: 32 additions & 18 deletions src/url-pattern-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,11 +106,8 @@ export class Parser {
this.#changeState(State.HASH, /*skip=*/1);
} else if (this.#isSearchPrefix()) {
this.#changeState(State.SEARCH, /*skip=*/1);
this.#internalResult.hash = '';
} else {
this.#changeState(State.PATHNAME, /*skip=*/0);
this.#internalResult.search = '';
this.#internalResult.hash = '';
}
continue;
}
Expand Down Expand Up @@ -147,17 +144,6 @@ export class Parser {
switch (this.#state) {
case State.INIT:
if (this.#isProtocolSuffix()) {
// We are in absolute mode and we know values will not be inherited
// from a base URL. Therefore initialize the rest of the components
// to the empty string.
this.#internalResult.username = '';
this.#internalResult.password = '';
this.#internalResult.hostname = '';
this.#internalResult.port = '';
this.#internalResult.pathname = '';
this.#internalResult.search = '';
this.#internalResult.hash = '';

// Update the state to expect the start of an absolute URL.
this.#rewindAndSetState(State.PROTOCOL);
}
Expand All @@ -179,10 +165,6 @@ export class Parser {
let nextState: State = State.PATHNAME;
let skip: number = 1;

if (this.#shouldTreatAsStandardURL) {
this.#internalResult.pathname = '/';
}

// If there are authority slashes, like `https://`, then
// we must transition to the authority section of the URLPattern.
if (this.#nextIsAuthoritySlashes()) {
Expand Down Expand Up @@ -319,6 +301,13 @@ export class Parser {
break;
}
}

if (this.#internalResult.hostname !== undefined &&
this.#internalResult.port === undefined) {
// If the hostname is specified in a constructor string but the port is
// not, the default port is assumed to be meant.
this.#internalResult.port = '';
}
}

#changeState(newState: State, skip: number): void {
Expand Down Expand Up @@ -358,6 +347,31 @@ export class Parser {
break;
}

if (this.#state !== State.INIT && newState !== State.DONE) {
// If hostname, pathname or search is skipped but something appears after
// it, then it takes its default value (usually the empty string).
if ([State.PROTOCOL, State.AUTHORITY, State.USERNAME, State.PASSWORD]
.includes(this.#state) &&
[State.PORT, State.PATHNAME, State.SEARCH, State.HASH]
.includes(newState)) {
this.#internalResult.hostname ??= '';
}
if ([State.PROTOCOL, State.AUTHORITY, State.USERNAME, State.PASSWORD,
State.HOSTNAME, State.PORT]
.includes(this.#state) &&
[State.SEARCH, State.HASH]
.includes(newState)) {
this.#internalResult.pathname ??=
(this.#shouldTreatAsStandardURL ? '/' : '');
}
if ([State.PROTOCOL, State.AUTHORITY, State.USERNAME, State.PASSWORD,
State.HOSTNAME, State.PORT, State.PATHNAME]
.includes(this.#state) &&
newState === State.HASH) {
this.#internalResult.search ??= '';
}
}

this.#changeStateWithoutSettingComponent(newState, skip);
}

Expand Down
46 changes: 34 additions & 12 deletions src/url-pattern.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,22 +77,44 @@ function processBaseURLString(input: string, isPattern: boolean) {
function applyInit(o: URLPatternInit, init: URLPatternInit, isPattern: boolean): URLPatternInit {
// If there is a baseURL we need to apply its component values first. The
// rest of the URLPatternInit structure will then later override these
// values. Note, the baseURL will always set either an empty string or
// longer value for each considered component. We do not allow null strings
// to persist for these components past this phase since they should no
// longer be treated as wildcards.
// values.
let baseURL;
if (typeof init.baseURL === 'string') {
try {
baseURL = new URL(init.baseURL);
o.protocol = processBaseURLString(baseURL.protocol.substring(0, baseURL.protocol.length - 1), isPattern);
o.username = processBaseURLString(baseURL.username, isPattern);
o.password = processBaseURLString(baseURL.password, isPattern);
o.hostname = processBaseURLString(baseURL.hostname, isPattern);
o.port = processBaseURLString(baseURL.port, isPattern);
o.pathname = processBaseURLString(baseURL.pathname, isPattern);
o.search = processBaseURLString(baseURL.search.substring(1, baseURL.search.length), isPattern);
o.hash = processBaseURLString(baseURL.hash.substring(1, baseURL.hash.length), isPattern);
if (init.protocol === undefined) {
o.protocol = processBaseURLString(baseURL.protocol.substring(0, baseURL.protocol.length - 1), isPattern);
}
if (!isPattern && init.protocol === undefined && init.hostname === undefined &&
init.port === undefined && init.username === undefined) {
o.username = processBaseURLString(baseURL.username, isPattern);
}
if (!isPattern && init.protocol === undefined && init.hostname === undefined &&
init.port === undefined && init.username === undefined &&
init.password === undefined) {
o.password = processBaseURLString(baseURL.password, isPattern);
}
if (init.protocol === undefined && init.hostname === undefined) {
o.hostname = processBaseURLString(baseURL.hostname, isPattern);
}
if (init.protocol === undefined && init.hostname === undefined &&
init.port === undefined) {
o.port = processBaseURLString(baseURL.port, isPattern);
}
if (init.protocol === undefined && init.hostname === undefined &&
init.port === undefined && init.pathname === undefined) {
o.pathname = processBaseURLString(baseURL.pathname, isPattern);
}
if (init.protocol === undefined && init.hostname === undefined &&
init.port === undefined && init.pathname === undefined &&
init.search === undefined) {
o.search = processBaseURLString(baseURL.search.substring(1, baseURL.search.length), isPattern);
}
if (init.protocol === undefined && init.hostname === undefined &&
init.port === undefined && init.pathname === undefined &&
init.search === undefined && init.hash === undefined) {
o.hash = processBaseURLString(baseURL.hash.substring(1, baseURL.hash.length), isPattern);
}
} catch {
throw new TypeError(`invalid baseURL '${init.baseURL}'.`);
}
Expand Down

0 comments on commit e3d9840

Please sign in to comment.