Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add URLPatternList #166

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 62 additions & 0 deletions spec.bs
Original file line number Diff line number Diff line change
Expand Up @@ -810,6 +810,68 @@ To <dfn>compute protocol matches a special scheme flag</dfn> given a [=construct
1. If the result of running [=protocol component matches a special scheme=] given |protocol component| is true, then set |parser|'s [=constructor string parser/protocol matches a special scheme flag=] to true.
</div>

<h2 id=urlpatternlist-class>The {{URLPatternList}} class </h2>

<xmp class="idl">
[Exposed=(Window,Worker)]
interface URLPatternList {
constructor(sequence<URLPattern> patterns);

boolean test(optional URLPatternInput input = {}, optional USVString baseURL);

URLPatternListResult? exec(optional URLPatternInput input = {}, optional USVString baseURL);
};

dictionary URLPatternListResult : URLPatternResult {
URLPattern pattern;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't know how it works internally but shouldn't it contain the match result as well? Since the point is to pick a pattern to match and it's likely doing some work behind the scenes

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It does — the : URLPatternResult part means this dictionary extends URLPatternResult.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aaah i didn’t see it. (Not familiar with this spec language 😂)

};
</xmp>

Note: The {{URLPatternList}} is a utility that combines many patterns into one
matcher. This functionality can also be achieved in a naive userland
implementation that iterates over a list of patterns and matches each one
individually. This has the unfortunate effect of not being very fast. With the
built-in {{URLPatternList}} implementers can use an optimized implementation for
matching under the hood which can drastically improve performance over the naive
userland implementation.

Each {{URLPatternList}} has an associated <dfn for=URLPatternList>pattern list</dfn>, a [=list=] of {{URLPattern}}s.

<div algorithm>
The <dfn constructor for=URLPatternList lt="URLPatternList(patterns)">new URLPatternList(|patterns|)</dfn> constructor steps are:

1. [=list/For each=] |pattern| in |patterns|, run the following steps:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Doesn't this imply that the pattern list is traversed as an array and is potentially slower? #30 (comment)

Copy link

@bathos bathos Jun 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The iteration steps here and elsewhere don’t appear to be observable, so engines can potentially optimize them however they see fit, right? Spec steps usually aim for the simplest and clearest explanation of observable behaviors, not the most efficient ones (because observable behaviors are the only things they can actually specify, further complexity is noise).

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see, thanks for the explanation!

1. If [=this=]'s [=URLPatternList/pattern list=] [=list/contains=] |pattern|, throw a {{TypeError}}.
1. [=list/Append=] the |pattern| to [=this=]'s [=URLPatternList/pattern list=].
1. If [=this=]'s [=URLPatternList/pattern list=] is empty, throw a {{TypeError}}.

Issue: The patterns need to be in a "least -> most significant" sort order so
implementers can efficiently use a radix tree under the hood. Enforcing /
sorting the patterns in this order depends on
<a href=https://github.com/WICG/urlpattern/issues/61>https://github.com/WICG/urlpattern/issues/61</a>.
</div>

<div>
The <dfn method for=URLPatternList>test(|input|, |baseURL|)</dfn> method steps are:

1. [=list/For each=] |pattern| in [=this=]'s [=URLPatternList/pattern list=], run the following steps:
1. Let |result| be the result of [=match=] given |pattern|, |input|, and |baseURL| if given.
1. If |result| is null, [=continue=].
1. Return true.
1. Return false.
</div>

<div>
The <dfn method for=URLPatternList>match(|input|, |baseURL|)</dfn> method steps are:

1. [=list/For each=] |pattern| in [=this=]'s [=URLPatternList/pattern list=], run the following steps:
1. Let |result| be the result of [=match=] given |pattern|, |input|, and |baseURL| if given.
1. If |result| is null, [=continue=].
1. Set |result|'s {{URLPatternListResult/pattern}} to |pattern|.
1. Return |result|.
1. Return null.
</div>

<h2 id=patterns>Patterns</h2>

A <dfn>pattern string</dfn> is a string that is written to match a set of target strings. A <dfn for="pattern string">well formed</dfn> pattern string conforms to a particular pattern syntax. This pattern syntax is directly based on the syntax used by the popular [path-to-regexp](https://github.com/pillarjs/path-to-regexp) JavaScript library.
Expand Down