From e2e472509c6245c72c71884e038311aa75c3be70 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Fri, 16 Feb 2024 02:06:53 +0000 Subject: [PATCH 01/26] Remove JavaScript realm dependency To allow the algorithms in the specification to be used outside of JavaScript, we need to remove dependency to JavaScript realm. This CL make a URLPattern object associated with an underlying URL Pattern struct, and makes algorithms to use it instead. Fixes https://github.com/whatwg/urlpattern/issues/217 --- spec.bs | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/spec.bs b/spec.bs index cec6cbe..22e8f29 100644 --- a/spec.bs +++ b/spec.bs @@ -25,7 +25,7 @@ spec: URL; urlPrefix: https://url.spec.whatwg.org/

The {{URLPattern}} class

-A {{URLPattern}} consists of several [=components=], each of which represents a [=/pattern string|pattern=] which could be matched against the corresponding component of a [=/URL=]. +A {{URLPattern}} has an associated [=URL Pattern=], which consists of several [=components=], each of which represents a [=/pattern string|pattern=] which could be matched against the corresponding component of a [=/URL=]. It can be constructed using a string for each component, or from a shorthand string. It can optionally be resolved relative to a base URL. @@ -224,21 +224,21 @@ dictionary URLPatternComponentResult { }; -Each {{URLPattern}} object has an associated protocol component, a [=component=], which must be set upon creation. +Each [=URL Pattern=] struct has an associated protocol component, a [=component=], which must be set upon creation. -Each {{URLPattern}} object has an associated username component, a [=component=], which must be set upon creation. +Each [=URL Pattern=] struct has an associated username component, a [=component=], which must be set upon creation. -Each {{URLPattern}} object has an associated password component, a [=component=], which must be set upon creation. +Each [=URL Pattern=] struct has an associated password component, a [=component=], which must be set upon creation. -Each {{URLPattern}} object has an associated hostname component, a [=component=], which must be set upon creation. +Each [=URL Pattern=] struct has an associated hostname component, a [=component=], which must be set upon creation. -Each {{URLPattern}} object has an associated port component, a [=component=], which must be set upon creation. +Each [=URL Pattern=] struct has an associated port component, a [=component=], which must be set upon creation. -Each {{URLPattern}} object has an associated pathname component, a [=component=], which must be set upon creation. +Each [=URL Pattern=] struct has an associated pathname component, a [=component=], which must be set upon creation. -Each {{URLPattern}} object has an associated search component, a [=component=], which must be set upon creation. +Each [=URL Pattern=] struct has an associated search component, a [=component=], which must be set upon creation. -Each {{URLPattern}} object has an associated hash component, a [=component=], which must be set upon creation. +Each [=URL Pattern=] struct has an associated hash component, a [=component=], which must be set upon creation.
|urlPattern| = new {{URLPattern/constructor(input, baseURL, options)|URLPattern}}(|input|)
@@ -338,17 +338,17 @@ Each {{URLPattern}} object has an associated hash component<
The new URLPattern(|input|, |baseURL|, |options|) constructor steps are: - 1. Run [=initialize=] given [=this=], |input|, |baseURL|, and |options|. + 1. Run [=initialize=] given [=this=]'s associated [=URL Pattern=], |input|, |baseURL|, and |options|.
The new URLPattern(|input|, |options|) constructor steps are: - 1. Run [=initialize=] given [=this=], |input|, null, and |options|. + 1. Run [=initialize=] given [=this=]'s associated [=URL Pattern=], |input|, null, and |options|.
- To initialize a {{URLPattern}} given a {{URLPattern}} |this|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: + To initialize a [=URL Pattern=] given a [=URL Pattern=] |this|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: 1. Let |init| be null. 1. If |input| is a [=scalar value string=] then: @@ -436,7 +436,7 @@ Each {{URLPattern}} object has an associated hash component<
The test(|input|, |baseURL|) method steps are: - 1. Let |result| be the result of [=URLPattern/match=] given [=this=], |input|, and |baseURL| if given. + 1. Let |result| be the result of [=URLPattern/match=] given [=this=]'s associated [=URL Pattern=], |input|, and |baseURL| if given. 1. If |result| is null, return false. 1. Return true.
@@ -444,12 +444,14 @@ Each {{URLPattern}} object has an associated hash component<
The exec(|input|, |baseURL|) method steps are: - 1. Return the result of [=URLPattern/match=] given [=this=], |input|, and |baseURL| if given. + 1. Return the result of [=URLPattern/match=] given [=this=]'s associated [=URL Pattern=], |input|, and |baseURL| if given.

Internals

-A {{URLPattern}} is associated with multiple component [=structs=]. +A {{URLPattern}} has an associated URL pattern [=structs=]. + +A [=URL pattern=] is associated with multiple component [=structs=]. A [=component=] has an associated pattern string, a [=pattern string/well formed=] [=/pattern string=], which must be set upon creation. @@ -477,8 +479,9 @@ A [=component=] has an associated has regexp groups, a
- A {{URLPattern}} |pattern| has regexp groups if the following steps return true: + A {{URLPattern}} |urlpattern| has regexp groups if the following steps return true: + 1. Let |pattern| be |urlpattern|'s associated [=URL Pattern=]. 1. If |pattern|'s [=URLPattern/protocol component=] [=component/has regexp groups=] is true, then return true. 1. If |pattern|'s [=URLPattern/username component=] [=component/has regexp groups=] is true, then return true. 1. If |pattern|'s [=URLPattern/password component=] [=component/has regexp groups=] is true, then return true. @@ -491,7 +494,7 @@ A [=component=] has an associated has regexp groups, a
- To perform a match given a {{URLPattern}} |urlpattern|, a {{URLPatternInput}} |input|, and an optional string |baseURLString|: + To perform a match given a [=URL Pattern=] |urlpattern|, a {{URLPatternInput}} |input|, and an optional string |baseURLString|: 1. Let |protocol| be the empty string. 1. Let |username| be the empty string. From 8fd2654f75e4b8378a844a5e57d690c88154579f Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Fri, 16 Feb 2024 04:33:47 +0000 Subject: [PATCH 02/26] Omit "struct" after [=URL Pattern=]. --- spec.bs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/spec.bs b/spec.bs index 22e8f29..8b5e7c4 100644 --- a/spec.bs +++ b/spec.bs @@ -224,21 +224,21 @@ dictionary URLPatternComponentResult { }; -Each [=URL Pattern=] struct has an associated protocol component, a [=component=], which must be set upon creation. +Each [=URL Pattern=] has an associated protocol component, a [=component=], which must be set upon creation. -Each [=URL Pattern=] struct has an associated username component, a [=component=], which must be set upon creation. +Each [=URL Pattern=] has an associated username component, a [=component=], which must be set upon creation. -Each [=URL Pattern=] struct has an associated password component, a [=component=], which must be set upon creation. +Each [=URL Pattern=] has an associated password component, a [=component=], which must be set upon creation. -Each [=URL Pattern=] struct has an associated hostname component, a [=component=], which must be set upon creation. +Each [=URL Pattern=] has an associated hostname component, a [=component=], which must be set upon creation. -Each [=URL Pattern=] struct has an associated port component, a [=component=], which must be set upon creation. +Each [=URL Pattern=] has an associated port component, a [=component=], which must be set upon creation. -Each [=URL Pattern=] struct has an associated pathname component, a [=component=], which must be set upon creation. +Each [=URL Pattern=] has an associated pathname component, a [=component=], which must be set upon creation. -Each [=URL Pattern=] struct has an associated search component, a [=component=], which must be set upon creation. +Each [=URL Pattern=] has an associated search component, a [=component=], which must be set upon creation. -Each [=URL Pattern=] struct has an associated hash component, a [=component=], which must be set upon creation. +Each [=URL Pattern=] has an associated hash component, a [=component=], which must be set upon creation.
|urlPattern| = new {{URLPattern/constructor(input, baseURL, options)|URLPattern}}(|input|)
From 5baf9006e42076aac9850f4e477592e512471fa7 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Fri, 16 Feb 2024 04:42:30 +0000 Subject: [PATCH 03/26] Make the create algorithm to avoid breaking the existing callers. --- spec.bs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/spec.bs b/spec.bs index 8b5e7c4..339a277 100644 --- a/spec.bs +++ b/spec.bs @@ -338,17 +338,21 @@ Each [=URL Pattern=] has an associated hash component,
The new URLPattern(|input|, |baseURL|, |options|) constructor steps are: - 1. Run [=initialize=] given [=this=]'s associated [=URL Pattern=], |input|, |baseURL|, and |options|. + 1. Run [=initialize=] given [=this=], |input|, |baseURL|, and |options|.
The new URLPattern(|input|, |options|) constructor steps are: - 1. Run [=initialize=] given [=this=]'s associated [=URL Pattern=], |input|, null, and |options|. + 1. Run [=initialize=] given [=this=], |input|, null, and |options|.
- To initialize a [=URL Pattern=] given a [=URL Pattern=] |this|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: + To initialize a {{URLPattern}} given a {{URLPattern}} |this|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|, Run [=create=] given |this|'s associated [=URL Pattern=], |input|, |baseURL|, and |options|. +
+ +
+ To create a [=URL Pattern=] given a [=URL Pattern=] |this|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: 1. Let |init| be null. 1. If |input| is a [=scalar value string=] then: From f2dc8dd345ce08636e6c26c5cca19baed49e8cc0 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Mon, 19 Feb 2024 01:31:58 +0000 Subject: [PATCH 04/26] Addressed comments. - Run -> run - renamed |this| to |urlPattern| --- spec.bs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/spec.bs b/spec.bs index 339a277..88ad42a 100644 --- a/spec.bs +++ b/spec.bs @@ -348,11 +348,11 @@ Each [=URL Pattern=] has an associated hash component,
- To initialize a {{URLPattern}} given a {{URLPattern}} |this|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|, Run [=create=] given |this|'s associated [=URL Pattern=], |input|, |baseURL|, and |options|. + To initialize a {{URLPattern}} given a {{URLPattern}} |this|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|, run [=create=] given |this|'s associated [=URL Pattern=], |input|, |baseURL|, and |options|.
- To create a [=URL Pattern=] given a [=URL Pattern=] |this|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: + To create a [=URL Pattern=] given a [=URL Pattern=] |urlPattern|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: 1. Let |init| be null. 1. If |input| is a [=scalar value string=] then: @@ -367,19 +367,19 @@ Each [=URL Pattern=] has an associated hash component, 1. [=list/For each=] |componentName| of « "{{URLPatternInit/protocol}}", "{{URLPatternInit/username}}", "{{URLPatternInit/password}}", "{{URLPatternInit/hostname}}", "{{URLPatternInit/port}}", "{{URLPatternInit/pathname}}", "{{URLPatternInit/search}}", "{{URLPatternInit/hash}}" »: 1. If |processedInit|[|componentName|] does not [=map/exist=], then [=map/set=] |processedInit|[|componentName|] to "`*`". 1. If |processedInit|["{{URLPatternInit/protocol}}"] is a [=special scheme=] and |processedInit|["{{URLPatternInit/port}}"] is a string which represents its corresponding [=default port=] in radix-10 using [=ASCII digits=] then set |processedInit|["{{URLPatternInit/port}}"] to the empty string. - 1. Set |this|'s [=URLPattern/protocol component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/protocol}}"], [=canonicalize a protocol=], and [=default options=]. - 1. Set |this|'s [=URLPattern/username component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/username}}"], [=canonicalize a username=], and [=default options=]. - 1. Set |this|'s [=URLPattern/password component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/password}}"], [=canonicalize a password=], and [=default options=]. - 1. If the result running [=hostname pattern is an IPv6 address=] given |processedInit|["{{URLPatternInit/hostname}}"] is true, then set |this|'s [=URLPattern/hostname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hostname}}"], [=canonicalize an IPv6 hostname=], and [=hostname options=]. - 1. Otherwise, set |this|'s [=URLPattern/hostname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hostname}}"], [=canonicalize a hostname=], and [=hostname options=]. - 1. Set |this|'s [=URLPattern/port component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/port}}"], [=canonicalize a port=], and [=default options=]. + 1. Set |urlPattern|'s [=URLPattern/protocol component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/protocol}}"], [=canonicalize a protocol=], and [=default options=]. + 1. Set |urlPattern|'s [=URLPattern/username component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/username}}"], [=canonicalize a username=], and [=default options=]. + 1. Set |urlPattern|'s [=URLPattern/password component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/password}}"], [=canonicalize a password=], and [=default options=]. + 1. If the result running [=hostname pattern is an IPv6 address=] given |processedInit|["{{URLPatternInit/hostname}}"] is true, then set |urlPattern|'s [=URLPattern/hostname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hostname}}"], [=canonicalize an IPv6 hostname=], and [=hostname options=]. + 1. Otherwise, set |urlPattern|'s [=URLPattern/hostname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hostname}}"], [=canonicalize a hostname=], and [=hostname options=]. + 1. Set |urlPattern|'s [=URLPattern/port component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/port}}"], [=canonicalize a port=], and [=default options=]. 1. Let |compileOptions| be a copy of the [=default options=] with the [=options/ignore case=] property set to |options|["{{URLPatternOptions/ignoreCase}}"]. - 1. If the result of running [=protocol component matches a special scheme=] given |this|'s [=URLPattern/protocol component=] is true, then: + 1. If the result of running [=protocol component matches a special scheme=] given |urlPattern|'s [=URLPattern/protocol component=] is true, then: 1. Let |pathCompileOptions| be copy of the [=pathname options=] with the [=options/ignore case=] property set to |options|["{{URLPatternOptions/ignoreCase}}"]. - 1. Set |this|'s [=URLPattern/pathname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/pathname}}"], [=canonicalize a pathname=], and |pathCompileOptions|. - 1. Otherwise set |this|'s [=URLPattern/pathname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/pathname}}"], [=canonicalize an opaque pathname=], and |compileOptions|. - 1. Set |this|'s [=URLPattern/search component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/search}}"], [=canonicalize a search=], and |compileOptions|. - 1. Set |this|'s [=URLPattern/hash component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hash}}"], [=canonicalize a hash=], and |compileOptions|. + 1. Set |urlPattern|'s [=URLPattern/pathname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/pathname}}"], [=canonicalize a pathname=], and |pathCompileOptions|. + 1. Otherwise set |urlPattern|'s [=URLPattern/pathname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/pathname}}"], [=canonicalize an opaque pathname=], and |compileOptions|. + 1. Set |urlPattern|'s [=URLPattern/search component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/search}}"], [=canonicalize a search=], and |compileOptions|. + 1. Set |urlPattern|'s [=URLPattern/hash component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hash}}"], [=canonicalize a hash=], and |compileOptions|.
From 9ef78bf7cc5d7a4dab979c22330c3cacbd7d5c5a Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Mon, 19 Feb 2024 06:35:56 +0000 Subject: [PATCH 05/26] Remove realm dependencies from other spec integrations --- spec.bs | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/spec.bs b/spec.bs index 88ad42a..f382647 100644 --- a/spec.bs +++ b/spec.bs @@ -1980,23 +1980,22 @@ JavaScript APIs should accept all of: To accomplish this, specifications should accept {{URLPatternCompatible}} as an argument to an [=operation=] or [=dictionary member=], and process it using the following algorithm, using the appropriate [=environment settings object=]'s [=environment settings object/API base URL=] or equivalent.
- To build a {{URLPattern}} from a Web IDL value {{URLPatternCompatible}} |input| given [=/URL=] |baseURL| and [=ECMAScript/realm=] |realm|, perform the following steps: + To build a [=URL Pattern=] from a Web IDL value {{URLPatternCompatible}} |input| given [=/URL=] |baseURL|, perform the following steps: 1. If the [=specific type=] of |input| is {{URLPattern}}: - 1. Return |input|. + 1. Return |input|'s associated [=URL Pattern=]. 1. Otherwise, if the [=specific type=] of |input| is {{URLPatternInit}}: 1. Let |init| be a [=map/clone=] of |input|. 1. If |init|["{{URLPatternInit/baseURL}}"] does not [=map/exist=], set it to the [=URL serializer|serialization=] of |baseURL|. - 1. Let |pattern| be a [=new=] {{URLPattern}} with |realm|. - 1. Run [=initialize=] given |pattern|, |init|, null, and an empty [=map=]. + 1. Let |pattern| be a new [=URL Pattern=]. + 1. Run [=create=] given |pattern|, |init|, null, and an empty [=map=]. 1. Return |pattern|. 1. Otherwise: 1. [=Assert=]: The [=specific type=] of |input| is {{USVString}}. - 1. Let |pattern| be a [=new=] {{URLPattern}} with |realm|. - 1. Run [=initialize=] given |pattern|, |input|, the [=URL serializer|serialization=] of |baseURL|, and an empty [=map=]. + 1. Let |pattern| be a new [=URL Pattern=]. + 1. Run [=create=] given |pattern|, |input|, the [=URL serializer|serialization=] of |baseURL|, and an empty [=map=]. 1. Return |pattern|. -

Ideally we wouldn't need a realm here. If we extricate the URL pattern concept from the {{URLPattern}} interface, we won't anymore.

This allows authors to concisely specify most patterns, and use the constructor to access uncommon options if necessary. The implicit use of the base URL is similar to, and consistent with, HTML's [=parse a URL=] algorithm. [[HTML]] @@ -2010,12 +2009,12 @@ JSON data formats which include URL patterns should mirror the behavior of - To build a {{URLPattern}} from an Infra value |rawPattern| given [=/URL=] |baseURL| and [=ECMAScript/realm=] |realm|, perform the following steps. + To build a [=URL Pattern=] from an Infra value |rawPattern| given [=/URL=] |baseURL|, perform the following steps. 1. Let |serializedBaseURL| be the [=URL serializer|serialization=] of |baseURL|. 1. If |rawPattern| is a [=string=], then: - 1. Let |pattern| be a [=new=] {{URLPattern}} with |realm|. - 1. Run [=initialize=] given |pattern|, |rawPattern|, |serializedBaseURL|, and an empty [=map=]. + 1. Let |pattern| be a new [=URL Pattern=]. + 1. Run [=create=] given |pattern|, |rawPattern|, |serializedBaseURL|, and an empty [=map=].
It may become necessary in the future to plumb non-empty options here.
1. Return |pattern|. @@ -2027,17 +2026,16 @@ If a specification has an Infra value (e.g., after using [=parse a JSON string t
This will need to be updated if {{URLPatternInit}} gains members of other types.
A future version of this specification might also have a less strict mode, if that proves useful to other specifications.
1. Set |init|[|key|] to |value|. - 1. Let |pattern| be a [=new=] {{URLPattern}} with |realm|. - 1. Run [=initialize=] given |pattern|, |init|, null, and an empty [=map=]. + 1. Let |pattern| be a new [=URL Pattern=]. + 1. Run [=create=] given |pattern|, |init|, null, and an empty [=map=].
It may become necessary in the future to plumb non-empty options here.
1. Return |pattern|. 1. Otherwise, return null. -

Ideally we wouldn't need a realm here. If we extricate the URL pattern concept from the {{URLPattern}} interface, we won't anymore.

-Specifications may wish to leave room in their formats to accept options for {{URLPatternOptions}}, override the base URL, or similar, since it is not possible to construct a {{URLPattern}} object directly in this case, unlike in a JavaScript API. For example, Speculation Rules accepts a "`relative_to`" key which can be used to switch to using the [=document base URL=] instead of the JSON resource's URL. [[SPECULATION-RULES]] +Specifications may wish to leave room in their formats to accept options for {{URLPatternOptions}}, override the base URL, or similar, since it is not possible to construct a [=URL Pattern=] directly in this case, unlike in a JavaScript API. For example, Speculation Rules accepts a "`relative_to`" key which can be used to switch to using the [=document base URL=] instead of the JSON resource's URL. [[SPECULATION-RULES]]

Acknowledgments

@@ -2076,7 +2074,8 @@ Rajesh Jagannathan, Ralph Chelala, Sangwhan Moon, Sayan Pal, -Victor Costan, and +Victor Costan +Yoshisato Yanagisawa, and Youenn Fablet for their contributors to this specification. From d188a8d907cb3319919d683c233cd271c9e59f9f Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Wed, 21 Feb 2024 18:31:29 +0900 Subject: [PATCH 06/26] Update spec.bs Co-authored-by: Domenic Denicola --- spec.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.bs b/spec.bs index f382647..93e6176 100644 --- a/spec.bs +++ b/spec.bs @@ -2074,7 +2074,7 @@ Rajesh Jagannathan, Ralph Chelala, Sangwhan Moon, Sayan Pal, -Victor Costan +Victor Costan, Yoshisato Yanagisawa, and Youenn Fablet for their contributors to this specification. From 32acfe3ce35e45f72ca25e2a78b378e080c2b949 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Wed, 21 Feb 2024 09:04:53 +0000 Subject: [PATCH 07/26] Rename [=URL Pattern=] to [=URL pattern=] --- spec.bs | 46 +++++++++++++++++++++++----------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/spec.bs b/spec.bs index 93e6176..c65ca27 100644 --- a/spec.bs +++ b/spec.bs @@ -25,7 +25,7 @@ spec: URL; urlPrefix: https://url.spec.whatwg.org/

The {{URLPattern}} class

-A {{URLPattern}} has an associated [=URL Pattern=], which consists of several [=components=], each of which represents a [=/pattern string|pattern=] which could be matched against the corresponding component of a [=/URL=]. +A {{URLPattern}} has an associated [=URL pattern=], which consists of several [=components=], each of which represents a [=/pattern string|pattern=] which could be matched against the corresponding component of a [=/URL=]. It can be constructed using a string for each component, or from a shorthand string. It can optionally be resolved relative to a base URL. @@ -224,21 +224,21 @@ dictionary URLPatternComponentResult { }; -Each [=URL Pattern=] has an associated protocol component, a [=component=], which must be set upon creation. +Each [=URL pattern=] has an associated protocol component, a [=component=], which must be set upon creation. -Each [=URL Pattern=] has an associated username component, a [=component=], which must be set upon creation. +Each [=URL pattern=] has an associated username component, a [=component=], which must be set upon creation. -Each [=URL Pattern=] has an associated password component, a [=component=], which must be set upon creation. +Each [=URL pattern=] has an associated password component, a [=component=], which must be set upon creation. -Each [=URL Pattern=] has an associated hostname component, a [=component=], which must be set upon creation. +Each [=URL pattern=] has an associated hostname component, a [=component=], which must be set upon creation. -Each [=URL Pattern=] has an associated port component, a [=component=], which must be set upon creation. +Each [=URL pattern=] has an associated port component, a [=component=], which must be set upon creation. -Each [=URL Pattern=] has an associated pathname component, a [=component=], which must be set upon creation. +Each [=URL pattern=] has an associated pathname component, a [=component=], which must be set upon creation. -Each [=URL Pattern=] has an associated search component, a [=component=], which must be set upon creation. +Each [=URL pattern=] has an associated search component, a [=component=], which must be set upon creation. -Each [=URL Pattern=] has an associated hash component, a [=component=], which must be set upon creation. +Each [=URL pattern=] has an associated hash component, a [=component=], which must be set upon creation.
|urlPattern| = new {{URLPattern/constructor(input, baseURL, options)|URLPattern}}(|input|)
@@ -348,11 +348,11 @@ Each [=URL Pattern=] has an associated hash component,
- To initialize a {{URLPattern}} given a {{URLPattern}} |this|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|, run [=create=] given |this|'s associated [=URL Pattern=], |input|, |baseURL|, and |options|. + To initialize a {{URLPattern}} given a {{URLPattern}} |this|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|, run [=create=] given |this|'s associated [=URL pattern=], |input|, |baseURL|, and |options|.
- To create a [=URL Pattern=] given a [=URL Pattern=] |urlPattern|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: + To create a [=URL pattern=] given a [=URL pattern=] |urlPattern|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: 1. Let |init| be null. 1. If |input| is a [=scalar value string=] then: @@ -440,7 +440,7 @@ Each [=URL Pattern=] has an associated hash component,
The test(|input|, |baseURL|) method steps are: - 1. Let |result| be the result of [=URLPattern/match=] given [=this=]'s associated [=URL Pattern=], |input|, and |baseURL| if given. + 1. Let |result| be the result of [=URLPattern/match=] given [=this=]'s associated [=URL pattern=], |input|, and |baseURL| if given. 1. If |result| is null, return false. 1. Return true.
@@ -448,7 +448,7 @@ Each [=URL Pattern=] has an associated hash component,
The exec(|input|, |baseURL|) method steps are: - 1. Return the result of [=URLPattern/match=] given [=this=]'s associated [=URL Pattern=], |input|, and |baseURL| if given. + 1. Return the result of [=URLPattern/match=] given [=this=]'s associated [=URL pattern=], |input|, and |baseURL| if given.

Internals

@@ -485,7 +485,7 @@ A [=component=] has an associated has regexp groups, a
A {{URLPattern}} |urlpattern| has regexp groups if the following steps return true: - 1. Let |pattern| be |urlpattern|'s associated [=URL Pattern=]. + 1. Let |pattern| be |urlpattern|'s associated [=URL pattern=]. 1. If |pattern|'s [=URLPattern/protocol component=] [=component/has regexp groups=] is true, then return true. 1. If |pattern|'s [=URLPattern/username component=] [=component/has regexp groups=] is true, then return true. 1. If |pattern|'s [=URLPattern/password component=] [=component/has regexp groups=] is true, then return true. @@ -498,7 +498,7 @@ A [=component=] has an associated has regexp groups, a
- To perform a match given a [=URL Pattern=] |urlpattern|, a {{URLPatternInput}} |input|, and an optional string |baseURLString|: + To perform a match given a [=URL pattern=] |urlpattern|, a {{URLPatternInput}} |input|, and an optional string |baseURLString|: 1. Let |protocol| be the empty string. 1. Let |username| be the empty string. @@ -1980,19 +1980,19 @@ JavaScript APIs should accept all of: To accomplish this, specifications should accept {{URLPatternCompatible}} as an argument to an [=operation=] or [=dictionary member=], and process it using the following algorithm, using the appropriate [=environment settings object=]'s [=environment settings object/API base URL=] or equivalent.
- To build a [=URL Pattern=] from a Web IDL value {{URLPatternCompatible}} |input| given [=/URL=] |baseURL|, perform the following steps: + To build a [=URL pattern=] from a Web IDL value {{URLPatternCompatible}} |input| given [=/URL=] |baseURL|, perform the following steps: 1. If the [=specific type=] of |input| is {{URLPattern}}: - 1. Return |input|'s associated [=URL Pattern=]. + 1. Return |input|'s associated [=URL pattern=]. 1. Otherwise, if the [=specific type=] of |input| is {{URLPatternInit}}: 1. Let |init| be a [=map/clone=] of |input|. 1. If |init|["{{URLPatternInit/baseURL}}"] does not [=map/exist=], set it to the [=URL serializer|serialization=] of |baseURL|. - 1. Let |pattern| be a new [=URL Pattern=]. + 1. Let |pattern| be a new [=URL pattern=]. 1. Run [=create=] given |pattern|, |init|, null, and an empty [=map=]. 1. Return |pattern|. 1. Otherwise: 1. [=Assert=]: The [=specific type=] of |input| is {{USVString}}. - 1. Let |pattern| be a new [=URL Pattern=]. + 1. Let |pattern| be a new [=URL pattern=]. 1. Run [=create=] given |pattern|, |input|, the [=URL serializer|serialization=] of |baseURL|, and an empty [=map=]. 1. Return |pattern|. @@ -2009,11 +2009,11 @@ JSON data formats which include URL patterns should mirror the behavior of - To build a [=URL Pattern=] from an Infra value |rawPattern| given [=/URL=] |baseURL|, perform the following steps. + To build a [=URL pattern=] from an Infra value |rawPattern| given [=/URL=] |baseURL|, perform the following steps. 1. Let |serializedBaseURL| be the [=URL serializer|serialization=] of |baseURL|. 1. If |rawPattern| is a [=string=], then: - 1. Let |pattern| be a new [=URL Pattern=]. + 1. Let |pattern| be a new [=URL pattern=]. 1. Run [=create=] given |pattern|, |rawPattern|, |serializedBaseURL|, and an empty [=map=].
It may become necessary in the future to plumb non-empty options here.
@@ -2026,7 +2026,7 @@ If a specification has an Infra value (e.g., after using [=parse a JSON string t
This will need to be updated if {{URLPatternInit}} gains members of other types.
A future version of this specification might also have a less strict mode, if that proves useful to other specifications.
1. Set |init|[|key|] to |value|. - 1. Let |pattern| be a new [=URL Pattern=]. + 1. Let |pattern| be a new [=URL pattern=]. 1. Run [=create=] given |pattern|, |init|, null, and an empty [=map=].
It may become necessary in the future to plumb non-empty options here.
@@ -2035,7 +2035,7 @@ If a specification has an Infra value (e.g., after using [=parse a JSON string t
-Specifications may wish to leave room in their formats to accept options for {{URLPatternOptions}}, override the base URL, or similar, since it is not possible to construct a [=URL Pattern=] directly in this case, unlike in a JavaScript API. For example, Speculation Rules accepts a "`relative_to`" key which can be used to switch to using the [=document base URL=] instead of the JSON resource's URL. [[SPECULATION-RULES]] +Specifications may wish to leave room in their formats to accept options for {{URLPatternOptions}}, override the base URL, or similar, since it is not possible to construct a [=URL pattern=] directly in this case, unlike in a JavaScript API. For example, Speculation Rules accepts a "`relative_to`" key which can be used to switch to using the [=document base URL=] instead of the JSON resource's URL. [[SPECULATION-RULES]]

Acknowledgments

From 52c1032d604f5965044719878764beb93dcd5c62 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Wed, 21 Feb 2024 09:32:02 +0000 Subject: [PATCH 08/26] Another URLPattern to URL pattern rename. --- spec.bs | 172 +++++++++++++++++++++++++++----------------------------- 1 file changed, 82 insertions(+), 90 deletions(-) diff --git a/spec.bs b/spec.bs index c65ca27..10dc754 100644 --- a/spec.bs +++ b/spec.bs @@ -33,28 +33,28 @@ It can be constructed using a string for each component, or from a shorthand str

The shorthand "`https://example.com/:category/*`" corresponds to the following components:

-
[=URLPattern/protocol component|protocol=] +
[=URL pattern/protocol component|protocol=]
"`https`" -
[=URLPattern/username component|username=] +
[=URL pattern/username component|username=]
"`*`" -
[=URLPattern/password component|password=] +
[=URL pattern/password component|password=]
"`*`" -
[=URLPattern/hostname component|hostname=] +
[=URL pattern/hostname component|hostname=]
"`example.com`" -
[=URLPattern/port component|port=] +
[=URL pattern/port component|port=]
"" -
[=URLPattern/pathname component|pathname=] +
[=URL pattern/pathname component|pathname=]
"`/:category/*`" -
[=URLPattern/search component|search=] +
[=URL pattern/search component|search=]
"`*`" -
[=URLPattern/hash component|hash=] +
[=URL pattern/hash component|hash=]
"`*`"
@@ -78,28 +78,28 @@ It can be constructed using a string for each component, or from a shorthand str

The shorthand "`http{s}?://{:subdomain.}?shop.example/products/:id([0-9]+)#reviews`" corresponds to the following components:

-
[=URLPattern/protocol component|protocol=] +
[=URL pattern/protocol component|protocol=]
"`http{s}?`" -
[=URLPattern/username component|username=] +
[=URL pattern/username component|username=]
"`*`" -
[=URLPattern/password component|password=] +
[=URL pattern/password component|password=]
"`*`" -
[=URLPattern/hostname component|hostname=] +
[=URL pattern/hostname component|hostname=]
"`{:subdomain.}?shop.example`" -
[=URLPattern/port component|port=] +
[=URL pattern/port component|port=]
"" -
[=URLPattern/pathname component|pathname=] +
[=URL pattern/pathname component|pathname=]
"`/products/:id([0-9]+)`" -
[=URLPattern/search component|search=] +
[=URL pattern/search component|search=]
"" -
[=URLPattern/hash component|hash=] +
[=URL pattern/hash component|hash=]
"`reviews`"
@@ -125,28 +125,28 @@ It can be constructed using a string for each component, or from a shorthand str

The shorthand "`../admin/*`" with the base URL "`https://discussion.example/forum/?page=2`" corresponds to the following components:

-
[=URLPattern/protocol component|protocol=] +
[=URL pattern/protocol component|protocol=]
"`https`" -
[=URLPattern/username component|username=] +
[=URL pattern/username component|username=]
"`*`" -
[=URLPattern/password component|password=] +
[=URL pattern/password component|password=]
"`*`" -
[=URLPattern/hostname component|hostname=] +
[=URL pattern/hostname component|hostname=]
"`discussion.example`" -
[=URLPattern/port component|port=] +
[=URL pattern/port component|port=]
"" -
[=URLPattern/pathname component|pathname=] +
[=URL pattern/pathname component|pathname=]
"`/admin/*`" -
[=URLPattern/search component|search=] +
[=URL pattern/search component|search=]
"`*`" -
[=URLPattern/hash component|hash=] +
[=URL pattern/hash component|hash=]
"`*`"
@@ -224,21 +224,7 @@ dictionary URLPatternComponentResult { }; -Each [=URL pattern=] has an associated protocol component, a [=component=], which must be set upon creation. - -Each [=URL pattern=] has an associated username component, a [=component=], which must be set upon creation. - -Each [=URL pattern=] has an associated password component, a [=component=], which must be set upon creation. - -Each [=URL pattern=] has an associated hostname component, a [=component=], which must be set upon creation. - -Each [=URL pattern=] has an associated port component, a [=component=], which must be set upon creation. - -Each [=URL pattern=] has an associated pathname component, a [=component=], which must be set upon creation. - -Each [=URL pattern=] has an associated search component, a [=component=], which must be set upon creation. - -Each [=URL pattern=] has an associated hash component, a [=component=], which must be set upon creation. +Each {{URLPattern}} has an associated URL pattern, a [=URL pattern=].
|urlPattern| = new {{URLPattern/constructor(input, baseURL, options)|URLPattern}}(|input|)
@@ -367,67 +353,67 @@ Each [=URL pattern=] has an associated hash component, 1. [=list/For each=] |componentName| of « "{{URLPatternInit/protocol}}", "{{URLPatternInit/username}}", "{{URLPatternInit/password}}", "{{URLPatternInit/hostname}}", "{{URLPatternInit/port}}", "{{URLPatternInit/pathname}}", "{{URLPatternInit/search}}", "{{URLPatternInit/hash}}" »: 1. If |processedInit|[|componentName|] does not [=map/exist=], then [=map/set=] |processedInit|[|componentName|] to "`*`". 1. If |processedInit|["{{URLPatternInit/protocol}}"] is a [=special scheme=] and |processedInit|["{{URLPatternInit/port}}"] is a string which represents its corresponding [=default port=] in radix-10 using [=ASCII digits=] then set |processedInit|["{{URLPatternInit/port}}"] to the empty string. - 1. Set |urlPattern|'s [=URLPattern/protocol component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/protocol}}"], [=canonicalize a protocol=], and [=default options=]. - 1. Set |urlPattern|'s [=URLPattern/username component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/username}}"], [=canonicalize a username=], and [=default options=]. - 1. Set |urlPattern|'s [=URLPattern/password component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/password}}"], [=canonicalize a password=], and [=default options=]. - 1. If the result running [=hostname pattern is an IPv6 address=] given |processedInit|["{{URLPatternInit/hostname}}"] is true, then set |urlPattern|'s [=URLPattern/hostname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hostname}}"], [=canonicalize an IPv6 hostname=], and [=hostname options=]. - 1. Otherwise, set |urlPattern|'s [=URLPattern/hostname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hostname}}"], [=canonicalize a hostname=], and [=hostname options=]. - 1. Set |urlPattern|'s [=URLPattern/port component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/port}}"], [=canonicalize a port=], and [=default options=]. + 1. Set |urlPattern|'s [=URL pattern/protocol component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/protocol}}"], [=canonicalize a protocol=], and [=default options=]. + 1. Set |urlPattern|'s [=URL pattern/username component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/username}}"], [=canonicalize a username=], and [=default options=]. + 1. Set |urlPattern|'s [=URL pattern/password component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/password}}"], [=canonicalize a password=], and [=default options=]. + 1. If the result running [=hostname pattern is an IPv6 address=] given |processedInit|["{{URLPatternInit/hostname}}"] is true, then set |urlPattern|'s [=URL pattern/hostname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hostname}}"], [=canonicalize an IPv6 hostname=], and [=hostname options=]. + 1. Otherwise, set |urlPattern|'s [=URL pattern/hostname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hostname}}"], [=canonicalize a hostname=], and [=hostname options=]. + 1. Set |urlPattern|'s [=URL pattern/port component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/port}}"], [=canonicalize a port=], and [=default options=]. 1. Let |compileOptions| be a copy of the [=default options=] with the [=options/ignore case=] property set to |options|["{{URLPatternOptions/ignoreCase}}"]. - 1. If the result of running [=protocol component matches a special scheme=] given |urlPattern|'s [=URLPattern/protocol component=] is true, then: + 1. If the result of running [=protocol component matches a special scheme=] given |urlPattern|'s [=URL pattern/protocol component=] is true, then: 1. Let |pathCompileOptions| be copy of the [=pathname options=] with the [=options/ignore case=] property set to |options|["{{URLPatternOptions/ignoreCase}}"]. - 1. Set |urlPattern|'s [=URLPattern/pathname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/pathname}}"], [=canonicalize a pathname=], and |pathCompileOptions|. - 1. Otherwise set |urlPattern|'s [=URLPattern/pathname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/pathname}}"], [=canonicalize an opaque pathname=], and |compileOptions|. - 1. Set |urlPattern|'s [=URLPattern/search component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/search}}"], [=canonicalize a search=], and |compileOptions|. - 1. Set |urlPattern|'s [=URLPattern/hash component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hash}}"], [=canonicalize a hash=], and |compileOptions|. + 1. Set |urlPattern|'s [=URL pattern/pathname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/pathname}}"], [=canonicalize a pathname=], and |pathCompileOptions|. + 1. Otherwise set |urlPattern|'s [=URL pattern/pathname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/pathname}}"], [=canonicalize an opaque pathname=], and |compileOptions|. + 1. Set |urlPattern|'s [=URL pattern/search component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/search}}"], [=canonicalize a search=], and |compileOptions|. + 1. Set |urlPattern|'s [=URL pattern/hash component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hash}}"], [=canonicalize a hash=], and |compileOptions|.
The protocol getter steps are: - 1. Return [=this=]'s [=URLPattern/protocol component=]'s [=component/pattern string=]. + 1. Return [=this=]'s [=URL pattern/protocol component=]'s [=component/pattern string=].
The username getter steps are: - 1. Return [=this=]'s [=URLPattern/username component=]'s [=component/pattern string=]. + 1. Return [=this=]'s [=URL pattern/username component=]'s [=component/pattern string=].
The password getter steps are: - 1. Return [=this=]'s [=URLPattern/password component=]'s [=component/pattern string=]. + 1. Return [=this=]'s [=URL pattern/password component=]'s [=component/pattern string=].
The hostname getter steps are: - 1. Return [=this=]'s [=URLPattern/hostname component=]'s [=component/pattern string=]. + 1. Return [=this=]'s [=URL pattern/hostname component=]'s [=component/pattern string=].
The port getter steps are: - 1. Return [=this=]'s [=URLPattern/port component=]'s [=component/pattern string=]. + 1. Return [=this=]'s [=URL pattern/port component=]'s [=component/pattern string=].
The pathname getter steps are: - 1. Return [=this=]'s [=URLPattern/pathname component=]'s [=component/pattern string=]. + 1. Return [=this=]'s [=URL pattern/pathname component=]'s [=component/pattern string=].
The search getter steps are: - 1. Return [=this=]'s [=URLPattern/search component=]'s [=component/pattern string=]. + 1. Return [=this=]'s [=URL pattern/search component=]'s [=component/pattern string=].
The hash getter steps are: - 1. Return [=this=]'s [=URLPattern/hash component=]'s [=component/pattern string=]. + 1. Return [=this=]'s [=URL pattern/hash component=]'s [=component/pattern string=].
@@ -453,17 +439,23 @@ Each [=URL pattern=] has an associated hash component,

Internals

-A {{URLPattern}} has an associated URL pattern [=structs=]. - -A [=URL pattern=] is associated with multiple component [=structs=]. - -A [=component=] has an associated pattern string, a [=pattern string/well formed=] [=/pattern string=], which must be set upon creation. +A URL pattern is a [=struct=] with the following [=struct/items=]: -A [=component=] has an associated regular expression, a {{RegExp}}, which must be set upon creation. +* A protocol component, a [=component=] +* A username component, a [=component=] +* A password component, a [=component=] +* A hostname component, a [=component=] +* A port component, a [=component=] +* A pathname component, a [=component=] +* A search component, a [=component=] +* A hash component, a [=component=] -A [=component=] has an associated group name list, a [=list=] of strings, which must be set upon creation. +A component is a [=struct=] with the following [=struct/items=]: -A [=component=] has an associated has regexp groups, a [=boolean=], which must be set upon creation. +* A pattern string, a [=pattern string/well formed=] [=/pattern string=], which must be set upon creation. +* A regular expression, a {{RegExp}}, which must be set upon creation. +* A group name list, a [=list=] of strings, which must be set upon creation. +* A has regexp groups, a [=boolean=], which must be set upon creation.
To compile a component given a string |input|, [=/encoding callback=] |encoding callback|, and [=/options=] |options|: @@ -486,14 +478,14 @@ A [=component=] has an associated has regexp groups, a A {{URLPattern}} |urlpattern| has regexp groups if the following steps return true: 1. Let |pattern| be |urlpattern|'s associated [=URL pattern=]. - 1. If |pattern|'s [=URLPattern/protocol component=] [=component/has regexp groups=] is true, then return true. - 1. If |pattern|'s [=URLPattern/username component=] [=component/has regexp groups=] is true, then return true. - 1. If |pattern|'s [=URLPattern/password component=] [=component/has regexp groups=] is true, then return true. - 1. If |pattern|'s [=URLPattern/hostname component=] [=component/has regexp groups=] is true, then return true. - 1. If |pattern|'s [=URLPattern/port component=] [=component/has regexp groups=] is true, then return true. - 1. If |pattern|'s [=URLPattern/pathname component=] [=component/has regexp groups=] is true, then return true. - 1. If |pattern|'s [=URLPattern/search component=] [=component/has regexp groups=] is true, then return true. - 1. If |pattern|'s [=URLPattern/hash component=] [=component/has regexp groups=] is true, then return true. + 1. If |pattern|'s [=URL pattern/protocol component=] [=component/has regexp groups=] is true, then return true. + 1. If |pattern|'s [=URL pattern/username component=] [=component/has regexp groups=] is true, then return true. + 1. If |pattern|'s [=URL pattern/password component=] [=component/has regexp groups=] is true, then return true. + 1. If |pattern|'s [=URL pattern/hostname component=] [=component/has regexp groups=] is true, then return true. + 1. If |pattern|'s [=URL pattern/port component=] [=component/has regexp groups=] is true, then return true. + 1. If |pattern|'s [=URL pattern/pathname component=] [=component/has regexp groups=] is true, then return true. + 1. If |pattern|'s [=URL pattern/search component=] [=component/has regexp groups=] is true, then return true. + 1. If |pattern|'s [=URL pattern/hash component=] [=component/has regexp groups=] is true, then return true. 1. Return false.
@@ -537,25 +529,25 @@ A [=component=] has an associated has regexp groups, a 1. Set |pathname| to the result of [=URL path serializing=] |url|. 1. Set |search| to |url|'s [=url/query=] or the empty string if the value is null. 1. Set |hash| to |url|'s [=url/fragment=] or the empty string if the value is null. - 1. Let |protocolExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URLPattern/protocol component=]'s [=component/regular expression=], |protocol|). - 1. Let |usernameExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URLPattern/username component=]'s [=component/regular expression=], |username|). - 1. Let |passwordExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URLPattern/password component=]'s [=component/regular expression=], |password|). - 1. Let |hostnameExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URLPattern/hostname component=]'s [=component/regular expression=], |hostname|). - 1. Let |portExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URLPattern/port component=]'s [=component/regular expression=], |port|). - 1. Let |pathnameExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URLPattern/pathname component=]'s [=component/regular expression=], |pathname|). - 1. Let |searchExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URLPattern/search component=]'s [=component/regular expression=], |search|). - 1. Let |hashExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URLPattern/hash component=]'s [=component/regular expression=], |hash|). + 1. Let |protocolExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URL pattern/protocol component=]'s [=component/regular expression=], |protocol|). + 1. Let |usernameExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URL pattern/username component=]'s [=component/regular expression=], |username|). + 1. Let |passwordExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URL pattern/password component=]'s [=component/regular expression=], |password|). + 1. Let |hostnameExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URL pattern/hostname component=]'s [=component/regular expression=], |hostname|). + 1. Let |portExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URL pattern/port component=]'s [=component/regular expression=], |port|). + 1. Let |pathnameExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URL pattern/pathname component=]'s [=component/regular expression=], |pathname|). + 1. Let |searchExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URL pattern/search component=]'s [=component/regular expression=], |search|). + 1. Let |hashExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URL pattern/hash component=]'s [=component/regular expression=], |hash|). 1. If |protocolExecResult|, |usernameExecResult|, |passwordExecResult|, |hostnameExecResult|, |portExecResult|, |pathnameExecResult|, |searchExecResult|, or |hashExecResult| are null then return null. 1. Let |result| be a new {{URLPatternResult}}. 1. Set |result|["{{URLPatternResult/inputs}}"] to |inputs|. - 1. Set |result|["{{URLPatternResult/protocol}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URLPattern/protocol component=], |protocol|, and |protocolExecResult|. - 1. Set |result|["{{URLPatternResult/username}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URLPattern/username component=], |username|, and |usernameExecResult|. - 1. Set |result|["{{URLPatternResult/password}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URLPattern/password component=], |password|, and |passwordExecResult|. - 1. Set |result|["{{URLPatternResult/hostname}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URLPattern/hostname component=], |hostname|, and |hostnameExecResult|. - 1. Set |result|["{{URLPatternResult/port}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URLPattern/port component=], |port|, and |portExecResult|. - 1. Set |result|["{{URLPatternResult/pathname}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URLPattern/pathname component=], |pathname|, and |pathnameExecResult|. - 1. Set |result|["{{URLPatternResult/search}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URLPattern/search component=], |search|, and |searchExecResult|. - 1. Set |result|["{{URLPatternResult/hash}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URLPattern/hash component=], |hash|, and |hashExecResult|. + 1. Set |result|["{{URLPatternResult/protocol}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URL pattern/protocol component=], |protocol|, and |protocolExecResult|. + 1. Set |result|["{{URLPatternResult/username}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URL pattern/username component=], |username|, and |usernameExecResult|. + 1. Set |result|["{{URLPatternResult/password}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URL pattern/password component=], |password|, and |passwordExecResult|. + 1. Set |result|["{{URLPatternResult/hostname}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URL pattern/hostname component=], |hostname|, and |hostnameExecResult|. + 1. Set |result|["{{URLPatternResult/port}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URL pattern/port component=], |port|, and |portExecResult|. + 1. Set |result|["{{URLPatternResult/pathname}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URL pattern/pathname component=], |pathname|, and |pathnameExecResult|. + 1. Set |result|["{{URLPatternResult/search}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URL pattern/search component=], |search|, and |searchExecResult|. + 1. Set |result|["{{URLPatternResult/hash}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URL pattern/hash component=], |hash|, and |hashExecResult|. 1. Return |result|.
From 0d5c24dd0204a28c92c028c6f5da5a29f4a42247 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Wed, 21 Feb 2024 09:38:07 +0000 Subject: [PATCH 09/26] Move match as URL pattern's function --- spec.bs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/spec.bs b/spec.bs index 10dc754..ca56058 100644 --- a/spec.bs +++ b/spec.bs @@ -338,7 +338,7 @@ Each {{URLPattern}} has an associated URL pattern, a
- To create a [=URL pattern=] given a [=URL pattern=] |urlPattern|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: + To create a [=URL pattern=] given a [=URL pattern=] |urlPattern|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: 1. Let |init| be null. 1. If |input| is a [=scalar value string=] then: @@ -426,7 +426,7 @@ Each {{URLPattern}} has an associated URL pattern, a
The test(|input|, |baseURL|) method steps are: - 1. Let |result| be the result of [=URLPattern/match=] given [=this=]'s associated [=URL pattern=], |input|, and |baseURL| if given. + 1. Let |result| be the result of [=URL pattern/match=] given [=this=]'s [=URLPattern/associated URL pattern=], |input|, and |baseURL| if given. 1. If |result| is null, return false. 1. Return true.
@@ -434,7 +434,7 @@ Each {{URLPattern}} has an associated URL pattern, a
The exec(|input|, |baseURL|) method steps are: - 1. Return the result of [=URLPattern/match=] given [=this=]'s associated [=URL pattern=], |input|, and |baseURL| if given. + 1. Return the result of [=URL pattern/match=] given [=this=]'s [=URLPattern/associated URL pattern=], |input|, and |baseURL| if given.

Internals

@@ -477,7 +477,7 @@ A component is a [=struct=] with the following [=struct/items=]:
A {{URLPattern}} |urlpattern| has regexp groups if the following steps return true: - 1. Let |pattern| be |urlpattern|'s associated [=URL pattern=]. + 1. Let |pattern| be |urlpattern|'s [=URLPattern/associated URL pattern=]. 1. If |pattern|'s [=URL pattern/protocol component=] [=component/has regexp groups=] is true, then return true. 1. If |pattern|'s [=URL pattern/username component=] [=component/has regexp groups=] is true, then return true. 1. If |pattern|'s [=URL pattern/password component=] [=component/has regexp groups=] is true, then return true. @@ -490,7 +490,7 @@ A component is a [=struct=] with the following [=struct/items=]:
- To perform a match given a [=URL pattern=] |urlpattern|, a {{URLPatternInput}} |input|, and an optional string |baseURLString|: + To perform a match given a [=URL pattern=] |urlpattern|, a {{URLPatternInput}} |input|, and an optional string |baseURLString|: 1. Let |protocol| be the empty string. 1. Let |username| be the empty string. From fa9383e864223e6cb95ec5902dd21514f36a9346 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Wed, 21 Feb 2024 09:49:57 +0000 Subject: [PATCH 10/26] Also updated has regexp groups --- spec.bs | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/spec.bs b/spec.bs index ca56058..10b9ad1 100644 --- a/spec.bs +++ b/spec.bs @@ -419,7 +419,7 @@ Each {{URLPattern}} has an associated URL pattern, a
The hasRegExpGroups getter steps are: - 1. If [=this=] [=URLPattern/has regexp groups=], then return true. + 1. If [=this=]'s [=URLPattern/associated URL pattern=]'s [=URL pattern/has regexp groups=], then return true. 1. Return false.
@@ -475,17 +475,16 @@ A component is a [=struct=] with the following [=struct/items=]:
- A {{URLPattern}} |urlpattern| has regexp groups if the following steps return true: + A [=URL pattern=] |urlpattern| has regexp groups if the following steps return true: - 1. Let |pattern| be |urlpattern|'s [=URLPattern/associated URL pattern=]. - 1. If |pattern|'s [=URL pattern/protocol component=] [=component/has regexp groups=] is true, then return true. - 1. If |pattern|'s [=URL pattern/username component=] [=component/has regexp groups=] is true, then return true. - 1. If |pattern|'s [=URL pattern/password component=] [=component/has regexp groups=] is true, then return true. - 1. If |pattern|'s [=URL pattern/hostname component=] [=component/has regexp groups=] is true, then return true. - 1. If |pattern|'s [=URL pattern/port component=] [=component/has regexp groups=] is true, then return true. - 1. If |pattern|'s [=URL pattern/pathname component=] [=component/has regexp groups=] is true, then return true. - 1. If |pattern|'s [=URL pattern/search component=] [=component/has regexp groups=] is true, then return true. - 1. If |pattern|'s [=URL pattern/hash component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlpattern|'s [=URL pattern/protocol component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlpattern|'s [=URL pattern/username component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlpattern|'s [=URL pattern/password component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlpattern|'s [=URL pattern/hostname component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlpattern|'s [=URL pattern/port component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlpattern|'s [=URL pattern/pathname component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlpattern|'s [=URL pattern/search component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlpattern|'s [=URL pattern/hash component=] [=component/has regexp groups=] is true, then return true. 1. Return false.
@@ -1955,7 +1954,7 @@ To promote consistency on the web platform, other documents integrating with thi 1. **Accept shorthands**. Most author patterns will be simple and straightforward. Accordingly, APIs should accept shorthands for those common cases and avoid the need for authors to take additional steps to transform these into complete {{URLPattern}} objects. 1. **Respect the base URL**. Just as URLs are generally parsed relative to a base URL for their environment (most commonly, a [=document base URL=]), URL patterns should respect this as well. The {{URLPattern}} constructor itself is an exception because it directly exposes the concept itself, similar to how the
URL constructor does not respect the base URL even though the rest of the platform does. -1. **Be clear about regexp groups**. Some APIs may benefit from only allowing URL patterns which do not [=URLPattern/has regexp groups|have regexp groups=], for example, because user agents are likely to implement them in a different thread or process from those executing author script, and because of security or performance concerns, a JavaScript engine would not ordinarily run there. If so, this should be clearly documented (with reference to [=URLPattern/has regexp groups=]) and the operation should report an error as soon as possible (e.g., by throwing a JavaScript exception). If possible, this should be feature-detectable to allow for the possibility of this constraint being lifted in the future. Avoid creating different subsets of URL patterns without consulting the editors of this specification. +1. **Be clear about regexp groups**. Some APIs may benefit from only allowing URL patterns which do not [=URL pattern/has regexp groups|have regexp groups=], for example, because user agents are likely to implement them in a different thread or process from those executing author script, and because of security or performance concerns, a JavaScript engine would not ordinarily run there. If so, this should be clearly documented (with reference to [=URL pattern/has regexp groups=]) and the operation should report an error as soon as possible (e.g., by throwing a JavaScript exception). If possible, this should be feature-detectable to allow for the possibility of this constraint being lifted in the future. Avoid creating different subsets of URL patterns without consulting the editors of this specification. 1. **Be clear about what URLs will be matched**. For instance, algorithms during fetching are likely to operate on URLs with no [=url/fragment=]. If so, the specification should be clear that this is the case, and may advise showing a developer warning if a pattern which cannot match (e.g., because it requires a non-empty fragment) is used.

Integrating with JavaScript APIs

From a365f6dd04e0b1fafa1bca9b93216fe65e688a86 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Thu, 22 Feb 2024 09:00:44 +0000 Subject: [PATCH 11/26] Use associated URL pattern instead of URLPattern itself in algorithms --- spec.bs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/spec.bs b/spec.bs index 10b9ad1..67bd9da 100644 --- a/spec.bs +++ b/spec.bs @@ -371,49 +371,49 @@ Each {{URLPattern}} has an associated URL pattern, a
The protocol getter steps are: - 1. Return [=this=]'s [=URL pattern/protocol component=]'s [=component/pattern string=]. + 1. Return [=this=]'s [=URLPattern/associated URL pattern=]'s [=URL pattern/protocol component=]'s [=component/pattern string=].
The username getter steps are: - 1. Return [=this=]'s [=URL pattern/username component=]'s [=component/pattern string=]. + 1. Return [=this=]'s [=URLPattern/associated URL pattern=]'s [=URL pattern/username component=]'s [=component/pattern string=].
The password getter steps are: - 1. Return [=this=]'s [=URL pattern/password component=]'s [=component/pattern string=]. + 1. Return [=this=]'s [=URLPattern/associated URL pattern=]'s [=URL pattern/password component=]'s [=component/pattern string=].
The hostname getter steps are: - 1. Return [=this=]'s [=URL pattern/hostname component=]'s [=component/pattern string=]. + 1. Return [=this=]'s [=URLPattern/associated URL pattern=]'s [=URL pattern/hostname component=]'s [=component/pattern string=].
The port getter steps are: - 1. Return [=this=]'s [=URL pattern/port component=]'s [=component/pattern string=]. + 1. Return [=this=]'s [=URLPattern/associated URL pattern=]'s [=URL pattern/port component=]'s [=component/pattern string=].
The pathname getter steps are: - 1. Return [=this=]'s [=URL pattern/pathname component=]'s [=component/pattern string=]. + 1. Return [=this=]'s [=URLPattern/associated URL pattern=]'s [=URL pattern/pathname component=]'s [=component/pattern string=].
The search getter steps are: - 1. Return [=this=]'s [=URL pattern/search component=]'s [=component/pattern string=]. + 1. Return [=this=]'s [=URLPattern/associated URL pattern=]'s [=URL pattern/search component=]'s [=component/pattern string=].
The hash getter steps are: - 1. Return [=this=]'s [=URL pattern/hash component=]'s [=component/pattern string=]. + 1. Return [=this=]'s [=URLPattern/associated URL pattern=]'s [=URL pattern/hash component=]'s [=component/pattern string=].
From 46a8a0548f283415eedf7591285d4abb03a3709d Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Thu, 22 Feb 2024 09:21:47 +0000 Subject: [PATCH 12/26] Revise [=create=] to return a created [=URL pattern=] --- spec.bs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/spec.bs b/spec.bs index 67bd9da..b2cf9d8 100644 --- a/spec.bs +++ b/spec.bs @@ -334,11 +334,11 @@ Each {{URLPattern}} has an associated URL pattern, a
- To initialize a {{URLPattern}} given a {{URLPattern}} |this|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|, run [=create=] given |this|'s associated [=URL pattern=], |input|, |baseURL|, and |options|. + To initialize a {{URLPattern}} given a {{URLPattern}} |this|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|, set |this|'s [=URLPattern/associated URL pattern=] to the result of running [=create=] given |input|, |baseURL|, and |options|.
- To create a [=URL pattern=] given a [=URL pattern=] |urlPattern|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: + To create a [=URL pattern=] given a {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: 1. Let |init| be null. 1. If |input| is a [=scalar value string=] then: @@ -353,6 +353,7 @@ Each {{URLPattern}} has an associated URL pattern, a 1. [=list/For each=] |componentName| of « "{{URLPatternInit/protocol}}", "{{URLPatternInit/username}}", "{{URLPatternInit/password}}", "{{URLPatternInit/hostname}}", "{{URLPatternInit/port}}", "{{URLPatternInit/pathname}}", "{{URLPatternInit/search}}", "{{URLPatternInit/hash}}" »: 1. If |processedInit|[|componentName|] does not [=map/exist=], then [=map/set=] |processedInit|[|componentName|] to "`*`". 1. If |processedInit|["{{URLPatternInit/protocol}}"] is a [=special scheme=] and |processedInit|["{{URLPatternInit/port}}"] is a string which represents its corresponding [=default port=] in radix-10 using [=ASCII digits=] then set |processedInit|["{{URLPatternInit/port}}"] to the empty string. + 1. Let |urlPattern| be a new [=URL pattern=]. 1. Set |urlPattern|'s [=URL pattern/protocol component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/protocol}}"], [=canonicalize a protocol=], and [=default options=]. 1. Set |urlPattern|'s [=URL pattern/username component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/username}}"], [=canonicalize a username=], and [=default options=]. 1. Set |urlPattern|'s [=URL pattern/password component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/password}}"], [=canonicalize a password=], and [=default options=]. @@ -366,6 +367,7 @@ Each {{URLPattern}} has an associated URL pattern, a 1. Otherwise set |urlPattern|'s [=URL pattern/pathname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/pathname}}"], [=canonicalize an opaque pathname=], and |compileOptions|. 1. Set |urlPattern|'s [=URL pattern/search component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/search}}"], [=canonicalize a search=], and |compileOptions|. 1. Set |urlPattern|'s [=URL pattern/hash component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hash}}"], [=canonicalize a hash=], and |compileOptions|. + 1. Return |urlPattern|.
@@ -1974,7 +1976,7 @@ To accomplish this, specifications should accept {{URLPatternCompatible}} as an To build a [=URL pattern=] from a Web IDL value {{URLPatternCompatible}} |input| given [=/URL=] |baseURL|, perform the following steps: 1. If the [=specific type=] of |input| is {{URLPattern}}: - 1. Return |input|'s associated [=URL pattern=]. + 1. Return |input|'s [=URLPattern/associated URL pattern=]. 1. Otherwise, if the [=specific type=] of |input| is {{URLPatternInit}}: 1. Let |init| be a [=map/clone=] of |input|. 1. If |init|["{{URLPatternInit/baseURL}}"] does not [=map/exist=], set it to the [=URL serializer|serialization=] of |baseURL|. From 0914443daad8c770e99be28797990216222b1033 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa Date: Thu, 22 Feb 2024 10:17:23 +0000 Subject: [PATCH 13/26] Applied the suggested change on URLPattern class. - The URLPattern class -> "URL patterns" - Introduce an "Introduction" subsection to contain the introductory text and examples - Introduce a "The URLPattern class" subsection to contain the IDL and method definitions - Introduce "The URL pattern struct" subsection to contain the struct definition - Introduce "High-level operations" to contain "create", "match", "has regexp groups" - Everything else can continue living in "Internals" and "Constructor string parsing" - Rename "Patterns" to "Pattern strings" to be slightly less confusing as a sibling of "URL patterns" --- spec.bs | 136 ++++++++++++++++++++++++++++++-------------------------- 1 file changed, 73 insertions(+), 63 deletions(-) diff --git a/spec.bs b/spec.bs index b2cf9d8..6591b6e 100644 --- a/spec.bs +++ b/spec.bs @@ -23,7 +23,9 @@ spec: URL; urlPrefix: https://url.spec.whatwg.org/ text: serialize an integer; url: #serialize-an-integer -

The {{URLPattern}} class

+

The URL patterns

+ +

Intrdocution

A {{URLPattern}} has an associated [=URL pattern=], which consists of several [=components=], each of which represents a [=/pattern string|pattern=] which could be matched against the corresponding component of a [=/URL=]. @@ -165,6 +167,8 @@ It can be constructed using a string for each component, or from a shorthand str
+

The {{URLPattern}} class

+ typedef (USVString or URLPatternInit) URLPatternInput; @@ -334,40 +338,9 @@ Each {{URLPattern}} has an <dfn for="URLPattern">associated URL pattern</dfn>, a </div> <div algorithm> - To <dfn for=URLPattern>initialize</dfn> a {{URLPattern}} given a {{URLPattern}} |this|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|, set |this|'s [=URLPattern/associated URL pattern=] to the result of running [=create=] given |input|, |baseURL|, and |options|. -</div> - -<div algorithm> - To <dfn for="URL pattern">create</dfn> a [=URL pattern=] given a {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: + To <dfn for=URLPattern>initialize</dfn> a {{URLPattern}} given a {{URLPattern}} |this|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: - 1. Let |init| be null. - 1. If |input| is a [=scalar value string=] then: - 1. Set |init| to the result of running [=parse a constructor string=] given |input|. - 1. If |baseURL| is null and |init|["{{URLPatternInit/protocol}}"] does not [=map/exist=], then throw a {{TypeError}}. - 1. If |baseURL| is not null, [=map/set=] |init|["{{URLPatternInit/baseURL}}"] to |baseURL|. - 1. Otherwise: - 1. [=Assert=]: |input| is a {{URLPatternInit}}. - 1. If |baseURL| is not null, then throw a {{TypeError}}. - 1. Set |init| to |input|. - 1. Let |processedInit| be the result of [=process a URLPatternInit=] given |init|, "`pattern`", null, null, null, null, null, null, null, and null. - 1. [=list/For each=] |componentName| of « "{{URLPatternInit/protocol}}", "{{URLPatternInit/username}}", "{{URLPatternInit/password}}", "{{URLPatternInit/hostname}}", "{{URLPatternInit/port}}", "{{URLPatternInit/pathname}}", "{{URLPatternInit/search}}", "{{URLPatternInit/hash}}" »: - 1. If |processedInit|[|componentName|] does not [=map/exist=], then [=map/set=] |processedInit|[|componentName|] to "`*`". - 1. If |processedInit|["{{URLPatternInit/protocol}}"] is a [=special scheme=] and |processedInit|["{{URLPatternInit/port}}"] is a string which represents its corresponding [=default port=] in radix-10 using [=ASCII digits=] then set |processedInit|["{{URLPatternInit/port}}"] to the empty string. - 1. Let |urlPattern| be a new [=URL pattern=]. - 1. Set |urlPattern|'s [=URL pattern/protocol component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/protocol}}"], [=canonicalize a protocol=], and [=default options=]. - 1. Set |urlPattern|'s [=URL pattern/username component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/username}}"], [=canonicalize a username=], and [=default options=]. - 1. Set |urlPattern|'s [=URL pattern/password component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/password}}"], [=canonicalize a password=], and [=default options=]. - 1. If the result running [=hostname pattern is an IPv6 address=] given |processedInit|["{{URLPatternInit/hostname}}"] is true, then set |urlPattern|'s [=URL pattern/hostname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hostname}}"], [=canonicalize an IPv6 hostname=], and [=hostname options=]. - 1. Otherwise, set |urlPattern|'s [=URL pattern/hostname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hostname}}"], [=canonicalize a hostname=], and [=hostname options=]. - 1. Set |urlPattern|'s [=URL pattern/port component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/port}}"], [=canonicalize a port=], and [=default options=]. - 1. Let |compileOptions| be a copy of the [=default options=] with the [=options/ignore case=] property set to |options|["{{URLPatternOptions/ignoreCase}}"]. - 1. If the result of running [=protocol component matches a special scheme=] given |urlPattern|'s [=URL pattern/protocol component=] is true, then: - 1. Let |pathCompileOptions| be copy of the [=pathname options=] with the [=options/ignore case=] property set to |options|["{{URLPatternOptions/ignoreCase}}"]. - 1. Set |urlPattern|'s [=URL pattern/pathname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/pathname}}"], [=canonicalize a pathname=], and |pathCompileOptions|. - 1. Otherwise set |urlPattern|'s [=URL pattern/pathname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/pathname}}"], [=canonicalize an opaque pathname=], and |compileOptions|. - 1. Set |urlPattern|'s [=URL pattern/search component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/search}}"], [=canonicalize a search=], and |compileOptions|. - 1. Set |urlPattern|'s [=URL pattern/hash component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hash}}"], [=canonicalize a hash=], and |compileOptions|. - 1. Return |urlPattern|. + 1. Set |this|'s [=URLPattern/associated URL pattern=] to the result of running [=create=] given |input|, |baseURL|, and |options|. </div> <div algorithm> @@ -439,7 +412,7 @@ Each {{URLPattern}} has an <dfn for="URLPattern">associated URL pattern</dfn>, a 1. Return the result of [=URL pattern/match=] given [=this=]'s [=URLPattern/associated URL pattern=], |input|, and |baseURL| if given. </div> -<h3 id=urlpattern-internals>Internals</h3> +<h3 id=url-pattern-struct>The URL pattern struct</h3> A <dfn>URL pattern</dfn> is a [=struct=] with the following [=struct/items=]: @@ -459,35 +432,39 @@ A <dfn>component</dfn> is a [=struct=] with the following [=struct/items=]: * A <dfn for=component>group name list</dfn>, a [=list=] of strings, which must be set upon creation. * A <dfn for=component>has regexp groups</dfn>, a [=boolean=], which must be set upon creation. -<div algorithm> - To <dfn>compile a component</dfn> given a string |input|, [=/encoding callback=] |encoding callback|, and [=/options=] |options|: - - 1. Let |part list| be the result of running [=parse a pattern string=] given |input|, |options|, and |encoding callback|. - 1. Let (|regular expression string|, |name list|) be the result of running [=generate a regular expression and name list=] given |part list| and |options|. - 1. Let |flags| be an empty string. - 1. If |options|'s [=options/ignore case=] is true then set |flags| to "`vi`". - 1. Otherwise set |flags| to "`v`" - 1. Let |regular expression| be [$RegExpCreate$](|regular expression string|, |flags|). If this throws an exception, catch it, and throw a {{TypeError}}. - <p class="note">The specification uses regular expressions to perform all matching, but this is not mandated. Implementations are free to perform matching directly against the [=/part list=] when possible; e.g. when there are no custom regexp matching groups. If there are custom regular expressions, however, its important that they be immediately evaluated in the [=compile a component=] algorithm so an error can be thrown if they are invalid. - 1. Let |pattern string| be the result of running [=generate a pattern string=] given |part list| and |options|. - 1. Let |has regexp groups| be false. - 1. [=list/For each=] |part| of |part list|: - 1. If |part|'s [=part/type=] is "<a for=part/type>`regexp`</a>", then set |has regexp groups| to true. - 1. Return a new [=component=] whose [=component/pattern string=] is |pattern string|, [=component/regular expression=] is |regular expression|, [=component/group name list=] is |name list|, and [=component/has regexp groups=] is |has regexp groups|. -</div> +<h3 id=high-level-operations>High-level operations</h3> <div algorithm> - A [=URL pattern=] |urlpattern| <dfn export for="URL pattern">has regexp groups</dfn> if the following steps return true: + To <dfn for="URL pattern">create</dfn> a [=URL pattern=] given a {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: - 1. If |urlpattern|'s [=URL pattern/protocol component=] [=component/has regexp groups=] is true, then return true. - 1. If |urlpattern|'s [=URL pattern/username component=] [=component/has regexp groups=] is true, then return true. - 1. If |urlpattern|'s [=URL pattern/password component=] [=component/has regexp groups=] is true, then return true. - 1. If |urlpattern|'s [=URL pattern/hostname component=] [=component/has regexp groups=] is true, then return true. - 1. If |urlpattern|'s [=URL pattern/port component=] [=component/has regexp groups=] is true, then return true. - 1. If |urlpattern|'s [=URL pattern/pathname component=] [=component/has regexp groups=] is true, then return true. - 1. If |urlpattern|'s [=URL pattern/search component=] [=component/has regexp groups=] is true, then return true. - 1. If |urlpattern|'s [=URL pattern/hash component=] [=component/has regexp groups=] is true, then return true. - 1. Return false. + 1. Let |init| be null. + 1. If |input| is a [=scalar value string=] then: + 1. Set |init| to the result of running [=parse a constructor string=] given |input|. + 1. If |baseURL| is null and |init|["{{URLPatternInit/protocol}}"] does not [=map/exist=], then throw a {{TypeError}}. + 1. If |baseURL| is not null, [=map/set=] |init|["{{URLPatternInit/baseURL}}"] to |baseURL|. + 1. Otherwise: + 1. [=Assert=]: |input| is a {{URLPatternInit}}. + 1. If |baseURL| is not null, then throw a {{TypeError}}. + 1. Set |init| to |input|. + 1. Let |processedInit| be the result of [=process a URLPatternInit=] given |init|, "`pattern`", null, null, null, null, null, null, null, and null. + 1. [=list/For each=] |componentName| of « "{{URLPatternInit/protocol}}", "{{URLPatternInit/username}}", "{{URLPatternInit/password}}", "{{URLPatternInit/hostname}}", "{{URLPatternInit/port}}", "{{URLPatternInit/pathname}}", "{{URLPatternInit/search}}", "{{URLPatternInit/hash}}" »: + 1. If |processedInit|[|componentName|] does not [=map/exist=], then [=map/set=] |processedInit|[|componentName|] to "`*`". + 1. If |processedInit|["{{URLPatternInit/protocol}}"] is a [=special scheme=] and |processedInit|["{{URLPatternInit/port}}"] is a string which represents its corresponding [=default port=] in radix-10 using [=ASCII digits=] then set |processedInit|["{{URLPatternInit/port}}"] to the empty string. + 1. Let |urlPattern| be a new [=URL pattern=]. + 1. Set |urlPattern|'s [=URL pattern/protocol component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/protocol}}"], [=canonicalize a protocol=], and [=default options=]. + 1. Set |urlPattern|'s [=URL pattern/username component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/username}}"], [=canonicalize a username=], and [=default options=]. + 1. Set |urlPattern|'s [=URL pattern/password component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/password}}"], [=canonicalize a password=], and [=default options=]. + 1. If the result running [=hostname pattern is an IPv6 address=] given |processedInit|["{{URLPatternInit/hostname}}"] is true, then set |urlPattern|'s [=URL pattern/hostname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hostname}}"], [=canonicalize an IPv6 hostname=], and [=hostname options=]. + 1. Otherwise, set |urlPattern|'s [=URL pattern/hostname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hostname}}"], [=canonicalize a hostname=], and [=hostname options=]. + 1. Set |urlPattern|'s [=URL pattern/port component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/port}}"], [=canonicalize a port=], and [=default options=]. + 1. Let |compileOptions| be a copy of the [=default options=] with the [=options/ignore case=] property set to |options|["{{URLPatternOptions/ignoreCase}}"]. + 1. If the result of running [=protocol component matches a special scheme=] given |urlPattern|'s [=URL pattern/protocol component=] is true, then: + 1. Let |pathCompileOptions| be copy of the [=pathname options=] with the [=options/ignore case=] property set to |options|["{{URLPatternOptions/ignoreCase}}"]. + 1. Set |urlPattern|'s [=URL pattern/pathname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/pathname}}"], [=canonicalize a pathname=], and |pathCompileOptions|. + 1. Otherwise set |urlPattern|'s [=URL pattern/pathname component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/pathname}}"], [=canonicalize an opaque pathname=], and |compileOptions|. + 1. Set |urlPattern|'s [=URL pattern/search component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/search}}"], [=canonicalize a search=], and |compileOptions|. + 1. Set |urlPattern|'s [=URL pattern/hash component=] to the result of [=compiling a component=] given |processedInit|["{{URLPatternInit/hash}}"], [=canonicalize a hash=], and |compileOptions|. + 1. Return |urlPattern|. </div> <div algorithm> @@ -552,6 +529,39 @@ A <dfn>component</dfn> is a [=struct=] with the following [=struct/items=]: 1. Return |result|. </div> +<div algorithm> + A [=URL pattern=] |urlpattern| <dfn export for="URL pattern">has regexp groups</dfn> if the following steps return true: + + 1. If |urlpattern|'s [=URL pattern/protocol component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlpattern|'s [=URL pattern/username component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlpattern|'s [=URL pattern/password component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlpattern|'s [=URL pattern/hostname component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlpattern|'s [=URL pattern/port component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlpattern|'s [=URL pattern/pathname component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlpattern|'s [=URL pattern/search component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlpattern|'s [=URL pattern/hash component=] [=component/has regexp groups=] is true, then return true. + 1. Return false. +</div> + +<h3 id=urlpattern-internals>Internals</h3> + +<div algorithm> + To <dfn>compile a component</dfn> given a string |input|, [=/encoding callback=] |encoding callback|, and [=/options=] |options|: + + 1. Let |part list| be the result of running [=parse a pattern string=] given |input|, |options|, and |encoding callback|. + 1. Let (|regular expression string|, |name list|) be the result of running [=generate a regular expression and name list=] given |part list| and |options|. + 1. Let |flags| be an empty string. + 1. If |options|'s [=options/ignore case=] is true then set |flags| to "`vi`". + 1. Otherwise set |flags| to "`v`" + 1. Let |regular expression| be [$RegExpCreate$](|regular expression string|, |flags|). If this throws an exception, catch it, and throw a {{TypeError}}. + <p class="note">The specification uses regular expressions to perform all matching, but this is not mandated. Implementations are free to perform matching directly against the [=/part list=] when possible; e.g. when there are no custom regexp matching groups. If there are custom regular expressions, however, its important that they be immediately evaluated in the [=compile a component=] algorithm so an error can be thrown if they are invalid. + 1. Let |pattern string| be the result of running [=generate a pattern string=] given |part list| and |options|. + 1. Let |has regexp groups| be false. + 1. [=list/For each=] |part| of |part list|: + 1. If |part|'s [=part/type=] is "<a for=part/type>`regexp`</a>", then set |has regexp groups| to true. + 1. Return a new [=component=] whose [=component/pattern string=] is |pattern string|, [=component/regular expression=] is |regular expression|, [=component/group name list=] is |name list|, and [=component/has regexp groups=] is |has regexp groups|. +</div> + <div algorithm> To <dfn>create a component match result</dfn> given a [=component=] |component|, a string |input|, and an array representing the output of [$RegExpBuiltinExec$] |execResult|: @@ -926,7 +936,7 @@ 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=patterns>Patterns</h2> +<h2 id=pattern-strings>Pattern strings</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. @@ -942,7 +952,7 @@ It can be [=parse a pattern string|parsed=] to produce a [=/part list=] which de A full wildcard `*` can also be used to match as much as possible, as in the pathname pattern "`/products/*`". </div> -<h3 id=parsing-patterns>Parsing patterns</h3> +<h3 id=parsing-pattern-strings>Parsing pattern strings</h3> <h4 id=tokens>Tokens</h4> From e7b873d24a11994b814488a9fb900712dc2a0a32 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa <yyanagisawa@chromium.org> Date: Thu, 22 Feb 2024 10:21:18 +0000 Subject: [PATCH 14/26] Minor fix. --- spec.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.bs b/spec.bs index 6591b6e..c5b17d4 100644 --- a/spec.bs +++ b/spec.bs @@ -23,7 +23,7 @@ spec: URL; urlPrefix: https://url.spec.whatwg.org/ text: serialize an integer; url: #serialize-an-integer </pre> -<h2 id=urlpatterns>The URL patterns</h2> +<h2 id=urlpatterns>URL patterns</h2> <h3 id=introduction>Intrdocution</h3> From 84f8a34a6f22d2968f878ef564d8e70431a14f50 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa <yyanagisawa@chromium.org> Date: Thu, 22 Feb 2024 10:25:51 +0000 Subject: [PATCH 15/26] Make create exported --- spec.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.bs b/spec.bs index c5b17d4..098e4d6 100644 --- a/spec.bs +++ b/spec.bs @@ -435,7 +435,7 @@ A <dfn>component</dfn> is a [=struct=] with the following [=struct/items=]: <h3 id=high-level-operations>High-level operations</h3> <div algorithm> - To <dfn for="URL pattern">create</dfn> a [=URL pattern=] given a {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: + To <dfn export for="URL pattern">create</dfn> a [=URL pattern=] given a {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: 1. Let |init| be null. 1. If |input| is a [=scalar value string=] then: From 6a3c376cabbdbd4129e502bcb29ad3a455fb5bae Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa <yoshisato.yanagisawa@gmail.com> Date: Mon, 26 Feb 2024 10:21:55 +0900 Subject: [PATCH 16/26] Update spec.bs Co-authored-by: Jeremy Roman <jeremy@jeremyroman.com> --- spec.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.bs b/spec.bs index 098e4d6..9aa1fec 100644 --- a/spec.bs +++ b/spec.bs @@ -25,7 +25,7 @@ spec: URL; urlPrefix: https://url.spec.whatwg.org/ <h2 id=urlpatterns>URL patterns</h2> -<h3 id=introduction>Intrdocution</h3> +<h3 id=introduction>Introduction</h3> A {{URLPattern}} has an associated [=URL pattern=], which consists of several [=components=], each of which represents a [=/pattern string|pattern=] which could be matched against the corresponding component of a [=/URL=]. From 29ef4bda1c2b61b241cdeee1bd0a6a85b5d8c881 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa <yoshisato.yanagisawa@gmail.com> Date: Mon, 26 Feb 2024 10:24:18 +0900 Subject: [PATCH 17/26] Update spec.bs Co-authored-by: Jeremy Roman <jeremy@jeremyroman.com> --- spec.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.bs b/spec.bs index 9aa1fec..9b5e015 100644 --- a/spec.bs +++ b/spec.bs @@ -416,7 +416,7 @@ Each {{URLPattern}} has an <dfn for="URLPattern">associated URL pattern</dfn>, a A <dfn>URL pattern</dfn> is a [=struct=] with the following [=struct/items=]: -* A <dfn for="URL pattern">protocol component</dfn>, a [=component=] +* <dfn for="URL pattern">protocol component</dfn>, a [=component=] * A <dfn for="URL pattern">username component</dfn>, a [=component=] * A <dfn for="URL pattern">password component</dfn>, a [=component=] * A <dfn for="URL pattern">hostname component</dfn>, a [=component=] From 4fa6e48f6396ca479301b673cf17ce6c6a7183a4 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa <yyanagisawa@chromium.org> Date: Mon, 26 Feb 2024 01:30:24 +0000 Subject: [PATCH 18/26] Omit the beginning "A" from items. --- spec.bs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/spec.bs b/spec.bs index 9b5e015..807aad9 100644 --- a/spec.bs +++ b/spec.bs @@ -417,20 +417,20 @@ Each {{URLPattern}} has an <dfn for="URLPattern">associated URL pattern</dfn>, a A <dfn>URL pattern</dfn> is a [=struct=] with the following [=struct/items=]: * <dfn for="URL pattern">protocol component</dfn>, a [=component=] -* A <dfn for="URL pattern">username component</dfn>, a [=component=] -* A <dfn for="URL pattern">password component</dfn>, a [=component=] -* A <dfn for="URL pattern">hostname component</dfn>, a [=component=] -* A <dfn for="URL pattern">port component</dfn>, a [=component=] -* A <dfn for="URL pattern">pathname component</dfn>, a [=component=] -* A <dfn for="URL pattern">search component</dfn>, a [=component=] -* A <dfn for="URL pattern">hash component</dfn>, a [=component=] +* <dfn for="URL pattern">username component</dfn>, a [=component=] +* <dfn for="URL pattern">password component</dfn>, a [=component=] +* <dfn for="URL pattern">hostname component</dfn>, a [=component=] +* <dfn for="URL pattern">port component</dfn>, a [=component=] +* <dfn for="URL pattern">pathname component</dfn>, a [=component=] +* <dfn for="URL pattern">search component</dfn>, a [=component=] +* <dfn for="URL pattern">hash component</dfn>, a [=component=] A <dfn>component</dfn> is a [=struct=] with the following [=struct/items=]: -* A <dfn for=component>pattern string</dfn>, a [=pattern string/well formed=] [=/pattern string=], which must be set upon creation. -* A <dfn for=component>regular expression</dfn>, a {{RegExp}}, which must be set upon creation. -* A <dfn for=component>group name list</dfn>, a [=list=] of strings, which must be set upon creation. -* A <dfn for=component>has regexp groups</dfn>, a [=boolean=], which must be set upon creation. +* <dfn for=component>pattern string</dfn>, a [=pattern string/well formed=] [=/pattern string=], which must be set upon creation. +* <dfn for=component>regular expression</dfn>, a {{RegExp}}, which must be set upon creation. +* <dfn for=component>group name list</dfn>, a [=list=] of strings, which must be set upon creation. +* <dfn for=component>has regexp groups</dfn>, a [=boolean=], which must be set upon creation. <h3 id=high-level-operations>High-level operations</h3> From 80759517743e0e6e0c64e74edee5030fa91e7df6 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa <yyanagisawa@chromium.org> Date: Mon, 26 Feb 2024 01:40:35 +0000 Subject: [PATCH 19/26] Hold on mentioning about {{URLPattern}} in the introduction. --- spec.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.bs b/spec.bs index 807aad9..b5fafdd 100644 --- a/spec.bs +++ b/spec.bs @@ -27,7 +27,7 @@ spec: URL; urlPrefix: https://url.spec.whatwg.org/ <h3 id=introduction>Introduction</h3> -A {{URLPattern}} has an associated [=URL pattern=], which consists of several [=components=], each of which represents a [=/pattern string|pattern=] which could be matched against the corresponding component of a [=/URL=]. +A [=URL pattern=] consists of several [=components=], each of which represents a [=/pattern string|pattern=] which could be matched against the corresponding component of a [=/URL=]. It can be constructed using a string for each component, or from a shorthand string. It can optionally be resolved relative to a base URL. From 9311ab298a2438fa2feab81dbe08bf04b399d985 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa <yyanagisawa@chromium.org> Date: Mon, 26 Feb 2024 04:34:36 +0000 Subject: [PATCH 20/26] Remove ", which must be set upon creation." --- spec.bs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec.bs b/spec.bs index b5fafdd..3b5e9cc 100644 --- a/spec.bs +++ b/spec.bs @@ -427,10 +427,10 @@ A <dfn>URL pattern</dfn> is a [=struct=] with the following [=struct/items=]: A <dfn>component</dfn> is a [=struct=] with the following [=struct/items=]: -* <dfn for=component>pattern string</dfn>, a [=pattern string/well formed=] [=/pattern string=], which must be set upon creation. -* <dfn for=component>regular expression</dfn>, a {{RegExp}}, which must be set upon creation. -* <dfn for=component>group name list</dfn>, a [=list=] of strings, which must be set upon creation. -* <dfn for=component>has regexp groups</dfn>, a [=boolean=], which must be set upon creation. +* <dfn for=component>pattern string</dfn>, a [=pattern string/well formed=] [=/pattern string=] +* <dfn for=component>regular expression</dfn>, a {{RegExp}} +* <dfn for=component>group name list</dfn>, a [=list=] of strings +* <dfn for=component>has regexp groups</dfn>, a [=boolean=] <h3 id=high-level-operations>High-level operations</h3> From d51ad85c21f6fbfed3acd8ecc48c54988a7ed750 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa <yyanagisawa@chromium.org> Date: Mon, 26 Feb 2024 04:51:32 +0000 Subject: [PATCH 21/26] Combine three steps. Also, fixed the way to call [=create=] because it won't take |pattern| any more. --- spec.bs | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/spec.bs b/spec.bs index 3b5e9cc..a4f99fb 100644 --- a/spec.bs +++ b/spec.bs @@ -1990,14 +1990,10 @@ To accomplish this, specifications should accept {{URLPatternCompatible}} as an 1. Otherwise, if the [=specific type=] of |input| is {{URLPatternInit}}: 1. Let |init| be a [=map/clone=] of |input|. 1. If |init|["{{URLPatternInit/baseURL}}"] does not [=map/exist=], set it to the [=URL serializer|serialization=] of |baseURL|. - 1. Let |pattern| be a new [=URL pattern=]. - 1. Run [=create=] given |pattern|, |init|, null, and an empty [=map=]. - 1. Return |pattern|. + 1. Return the result of [=creating=] a URL pattern given |init|, null, and an empty [=map=]. 1. Otherwise: 1. [=Assert=]: The [=specific type=] of |input| is {{USVString}}. - 1. Let |pattern| be a new [=URL pattern=]. - 1. Run [=create=] given |pattern|, |input|, the [=URL serializer|serialization=] of |baseURL|, and an empty [=map=]. - 1. Return |pattern|. + 1. Return the result of [=creating=] a URL pattern given |input|, the [=URL serializer|serialization=] of |baseURL|, and an empty [=map=]. </div> @@ -2016,11 +2012,10 @@ If a specification has an Infra value (e.g., after using [=parse a JSON string t 1. Let |serializedBaseURL| be the [=URL serializer|serialization=] of |baseURL|. 1. If |rawPattern| is a [=string=], then: - 1. Let |pattern| be a new [=URL pattern=]. - 1. Run [=create=] given |pattern|, |rawPattern|, |serializedBaseURL|, and an empty [=map=]. + 1. Return the result of [=creating=] a URL pattern given |rawPattern|, |serializedBaseURL|, and an empty [=map=]. <div class="note">It may become necessary in the future to plumb non-empty options here.</div> - 1. Return |pattern|. + 1. Otherwise, if |rawPattern| is a [=map=], then: 1. Let |init| be «[ "{{URLPatternInit/baseURL}}" → |serializedBaseURL| ]», representing a dictionary of type {{URLPatternInit}}. 1. [=map/For each=] |key| → |value| of |rawPattern|: @@ -2029,11 +2024,10 @@ If a specification has an Infra value (e.g., after using [=parse a JSON string t <div class="note">This will need to be updated if {{URLPatternInit}} gains members of other types.</div> <div class="note">A future version of this specification might also have a less strict mode, if that proves useful to other specifications.</div> 1. Set |init|[|key|] to |value|. - 1. Let |pattern| be a new [=URL pattern=]. - 1. Run [=create=] given |pattern|, |init|, null, and an empty [=map=]. + 1. Return the result of [=creating=] a URL pattern given |pattern|, |init|, null, and an empty [=map=]. <div class="note">It may become necessary in the future to plumb non-empty options here.</div> - 1. Return |pattern|. + 1. Otherwise, return null. </div> From 17d8a181f6e7d62577709013e48b2086d932b000 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa <yyanagisawa@chromium.org> Date: Mon, 26 Feb 2024 04:57:33 +0000 Subject: [PATCH 22/26] Revert the update on {{URLPattern}} to [=URL pattern=] I changed like so by mistake. In this context, we would want to say that it is not relevant to create a URLPattern object as a JSON input. We need to say that because unlike JavaScript API, JSON API cannot take a URLPattern object itself, which has URLPatternOptions. --- spec.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.bs b/spec.bs index a4f99fb..fe645b8 100644 --- a/spec.bs +++ b/spec.bs @@ -2032,7 +2032,7 @@ If a specification has an Infra value (e.g., after using [=parse a JSON string t </div> -Specifications may wish to leave room in their formats to accept options for {{URLPatternOptions}}, override the base URL, or similar, since it is not possible to construct a [=URL pattern=] directly in this case, unlike in a JavaScript API. For example, <cite>Speculation Rules</cite> accepts a "`relative_to`" key which can be used to switch to using the [=document base URL=] instead of the JSON resource's URL. [[SPECULATION-RULES]] +Specifications may wish to leave room in their formats to accept options for {{URLPatternOptions}}, override the base URL, or similar, since it is not possible to construct a {{URLPattern}} object directly in this case, unlike in a JavaScript API. For example, <cite>Speculation Rules</cite> accepts a "`relative_to`" key which can be used to switch to using the [=document base URL=] instead of the JSON resource's URL. [[SPECULATION-RULES]] <h2 id=acknowledgments class=no-num>Acknowledgments</h2> From 4e893ec137eaf3978391559786b4937fda984c29 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa <yyanagisawa@chromium.org> Date: Mon, 26 Feb 2024 05:15:17 +0000 Subject: [PATCH 23/26] Rename from |urlpattern| to |urlPattern| --- spec.bs | 54 +++++++++++++++++++++++++++--------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/spec.bs b/spec.bs index fe645b8..7481eb4 100644 --- a/spec.bs +++ b/spec.bs @@ -468,7 +468,7 @@ A <dfn>component</dfn> is a [=struct=] with the following [=struct/items=]: </div> <div algorithm> - To perform a <dfn export for="URL pattern">match</dfn> given a [=URL pattern=] |urlpattern|, a {{URLPatternInput}} |input|, and an optional string |baseURLString|: + To perform a <dfn export for="URL pattern">match</dfn> given a [=URL pattern=] |urlPattern|, a {{URLPatternInput}} |input|, and an optional string |baseURLString|: 1. Let |protocol| be the empty string. 1. Let |username| be the empty string. @@ -507,39 +507,39 @@ A <dfn>component</dfn> is a [=struct=] with the following [=struct/items=]: 1. Set |pathname| to the result of [=URL path serializing=] |url|. 1. Set |search| to |url|'s [=url/query=] or the empty string if the value is null. 1. Set |hash| to |url|'s [=url/fragment=] or the empty string if the value is null. - 1. Let |protocolExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URL pattern/protocol component=]'s [=component/regular expression=], |protocol|). - 1. Let |usernameExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URL pattern/username component=]'s [=component/regular expression=], |username|). - 1. Let |passwordExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URL pattern/password component=]'s [=component/regular expression=], |password|). - 1. Let |hostnameExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URL pattern/hostname component=]'s [=component/regular expression=], |hostname|). - 1. Let |portExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URL pattern/port component=]'s [=component/regular expression=], |port|). - 1. Let |pathnameExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URL pattern/pathname component=]'s [=component/regular expression=], |pathname|). - 1. Let |searchExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URL pattern/search component=]'s [=component/regular expression=], |search|). - 1. Let |hashExecResult| be [$RegExpBuiltinExec$](|urlpattern|'s [=URL pattern/hash component=]'s [=component/regular expression=], |hash|). + 1. Let |protocolExecResult| be [$RegExpBuiltinExec$](|urlPattern|'s [=URL pattern/protocol component=]'s [=component/regular expression=], |protocol|). + 1. Let |usernameExecResult| be [$RegExpBuiltinExec$](|urlPattern|'s [=URL pattern/username component=]'s [=component/regular expression=], |username|). + 1. Let |passwordExecResult| be [$RegExpBuiltinExec$](|urlPattern|'s [=URL pattern/password component=]'s [=component/regular expression=], |password|). + 1. Let |hostnameExecResult| be [$RegExpBuiltinExec$](|urlPattern|'s [=URL pattern/hostname component=]'s [=component/regular expression=], |hostname|). + 1. Let |portExecResult| be [$RegExpBuiltinExec$](|urlPattern|'s [=URL pattern/port component=]'s [=component/regular expression=], |port|). + 1. Let |pathnameExecResult| be [$RegExpBuiltinExec$](|urlPattern|'s [=URL pattern/pathname component=]'s [=component/regular expression=], |pathname|). + 1. Let |searchExecResult| be [$RegExpBuiltinExec$](|urlPattern|'s [=URL pattern/search component=]'s [=component/regular expression=], |search|). + 1. Let |hashExecResult| be [$RegExpBuiltinExec$](|urlPattern|'s [=URL pattern/hash component=]'s [=component/regular expression=], |hash|). 1. If |protocolExecResult|, |usernameExecResult|, |passwordExecResult|, |hostnameExecResult|, |portExecResult|, |pathnameExecResult|, |searchExecResult|, or |hashExecResult| are null then return null. 1. Let |result| be a new {{URLPatternResult}}. 1. Set |result|["{{URLPatternResult/inputs}}"] to |inputs|. - 1. Set |result|["{{URLPatternResult/protocol}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URL pattern/protocol component=], |protocol|, and |protocolExecResult|. - 1. Set |result|["{{URLPatternResult/username}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URL pattern/username component=], |username|, and |usernameExecResult|. - 1. Set |result|["{{URLPatternResult/password}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URL pattern/password component=], |password|, and |passwordExecResult|. - 1. Set |result|["{{URLPatternResult/hostname}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URL pattern/hostname component=], |hostname|, and |hostnameExecResult|. - 1. Set |result|["{{URLPatternResult/port}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URL pattern/port component=], |port|, and |portExecResult|. - 1. Set |result|["{{URLPatternResult/pathname}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URL pattern/pathname component=], |pathname|, and |pathnameExecResult|. - 1. Set |result|["{{URLPatternResult/search}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URL pattern/search component=], |search|, and |searchExecResult|. - 1. Set |result|["{{URLPatternResult/hash}}"] to the result of [=creating a component match result=] given |urlpattern|'s [=URL pattern/hash component=], |hash|, and |hashExecResult|. + 1. Set |result|["{{URLPatternResult/protocol}}"] to the result of [=creating a component match result=] given |urlPattern|'s [=URL pattern/protocol component=], |protocol|, and |protocolExecResult|. + 1. Set |result|["{{URLPatternResult/username}}"] to the result of [=creating a component match result=] given |urlPattern|'s [=URL pattern/username component=], |username|, and |usernameExecResult|. + 1. Set |result|["{{URLPatternResult/password}}"] to the result of [=creating a component match result=] given |urlPattern|'s [=URL pattern/password component=], |password|, and |passwordExecResult|. + 1. Set |result|["{{URLPatternResult/hostname}}"] to the result of [=creating a component match result=] given |urlPattern|'s [=URL pattern/hostname component=], |hostname|, and |hostnameExecResult|. + 1. Set |result|["{{URLPatternResult/port}}"] to the result of [=creating a component match result=] given |urlPattern|'s [=URL pattern/port component=], |port|, and |portExecResult|. + 1. Set |result|["{{URLPatternResult/pathname}}"] to the result of [=creating a component match result=] given |urlPattern|'s [=URL pattern/pathname component=], |pathname|, and |pathnameExecResult|. + 1. Set |result|["{{URLPatternResult/search}}"] to the result of [=creating a component match result=] given |urlPattern|'s [=URL pattern/search component=], |search|, and |searchExecResult|. + 1. Set |result|["{{URLPatternResult/hash}}"] to the result of [=creating a component match result=] given |urlPattern|'s [=URL pattern/hash component=], |hash|, and |hashExecResult|. 1. Return |result|. </div> <div algorithm> - A [=URL pattern=] |urlpattern| <dfn export for="URL pattern">has regexp groups</dfn> if the following steps return true: + A [=URL pattern=] |urlPattern| <dfn export for="URL pattern">has regexp groups</dfn> if the following steps return true: - 1. If |urlpattern|'s [=URL pattern/protocol component=] [=component/has regexp groups=] is true, then return true. - 1. If |urlpattern|'s [=URL pattern/username component=] [=component/has regexp groups=] is true, then return true. - 1. If |urlpattern|'s [=URL pattern/password component=] [=component/has regexp groups=] is true, then return true. - 1. If |urlpattern|'s [=URL pattern/hostname component=] [=component/has regexp groups=] is true, then return true. - 1. If |urlpattern|'s [=URL pattern/port component=] [=component/has regexp groups=] is true, then return true. - 1. If |urlpattern|'s [=URL pattern/pathname component=] [=component/has regexp groups=] is true, then return true. - 1. If |urlpattern|'s [=URL pattern/search component=] [=component/has regexp groups=] is true, then return true. - 1. If |urlpattern|'s [=URL pattern/hash component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlPattern|'s [=URL pattern/protocol component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlPattern|'s [=URL pattern/username component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlPattern|'s [=URL pattern/password component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlPattern|'s [=URL pattern/hostname component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlPattern|'s [=URL pattern/port component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlPattern|'s [=URL pattern/pathname component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlPattern|'s [=URL pattern/search component=] [=component/has regexp groups=] is true, then return true. + 1. If |urlPattern|'s [=URL pattern/hash component=] [=component/has regexp groups=] is true, then return true. 1. Return false. </div> @@ -2024,7 +2024,7 @@ If a specification has an Infra value (e.g., after using [=parse a JSON string t <div class="note">This will need to be updated if {{URLPatternInit}} gains members of other types.</div> <div class="note">A future version of this specification might also have a less strict mode, if that proves useful to other specifications.</div> 1. Set |init|[|key|] to |value|. - 1. Return the result of [=creating=] a URL pattern given |pattern|, |init|, null, and an empty [=map=]. + 1. Return the result of [=creating=] a URL pattern given |init|, null, and an empty [=map=]. <div class="note">It may become necessary in the future to plumb non-empty options here.</div> From bf7a7c05fcd959093afbb806dfb66e2cf44c7f29 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa <yyanagisawa@chromium.org> Date: Mon, 26 Feb 2024 05:49:12 +0000 Subject: [PATCH 24/26] Implement the algorithm to build {{URLPattern}} To allow the API to compare values in the API's attribute with '===', the way to use |realm| has been introduced. --- spec.bs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/spec.bs b/spec.bs index 7481eb4..cc6d678 100644 --- a/spec.bs +++ b/spec.bs @@ -1982,6 +1982,17 @@ JavaScript APIs should accept all of: To accomplish this, specifications should accept {{URLPatternCompatible}} as an argument to an [=operation=] or [=dictionary member=], and process it using the following algorithm, using the appropriate [=environment settings object=]'s [=environment settings object/API base URL=] or equivalent. +<div algorithm> + To <dfn export>build a {{URLPattern}} object from a Web IDL value</dfn> {{URLPatternCompatible}} |input| given [=/URL=] |baseURL| and [=ECMAScript/realm=] |realm|, perform the following steps: + + 1. If the [=specific type=] of |input| is {{URLPattern}}: + 1. Return |input|. + 1. Otherwise, + 1. Let |pattern| be a [=new=] {{URLPattern}} with |realm|. + 1. Set |pattern|'s [=URLPattern/associated URL pattern=] to the result of [=building a URL pattern from a Web IDL value=] given |input| and |baseURL|. + 1. Return |pattern|. +</div> + <div algorithm> To <dfn export>build a [=URL pattern=] from a Web IDL value</dfn> {{URLPatternCompatible}} |input| given [=/URL=] |baseURL|, perform the following steps: @@ -1994,7 +2005,6 @@ To accomplish this, specifications should accept {{URLPatternCompatible}} as an 1. Otherwise: 1. [=Assert=]: The [=specific type=] of |input| is {{USVString}}. 1. Return the result of [=creating=] a URL pattern given |input|, the [=URL serializer|serialization=] of |baseURL|, and an empty [=map=]. - </div> This allows authors to concisely specify most patterns, and use the <a constructor for="URLPattern">constructor</a> to access uncommon options if necessary. The implicit use of the base URL is similar to, and consistent with, <cite>HTML</cite>'s [=parse a URL=] algorithm. [[HTML]] From 0699d526e515a5a47b6651b78f00a53085ae00ff Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa <yoshisato.yanagisawa@gmail.com> Date: Tue, 27 Feb 2024 08:46:29 +0900 Subject: [PATCH 25/26] Update spec.bs Co-authored-by: Jeremy Roman <jeremy@jeremyroman.com> --- spec.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.bs b/spec.bs index cc6d678..2070238 100644 --- a/spec.bs +++ b/spec.bs @@ -1987,7 +1987,7 @@ To accomplish this, specifications should accept {{URLPatternCompatible}} as an 1. If the [=specific type=] of |input| is {{URLPattern}}: 1. Return |input|. - 1. Otherwise, + 1. Otherwise: 1. Let |pattern| be a [=new=] {{URLPattern}} with |realm|. 1. Set |pattern|'s [=URLPattern/associated URL pattern=] to the result of [=building a URL pattern from a Web IDL value=] given |input| and |baseURL|. 1. Return |pattern|. From 62f5ffaca7a923e56b3dd8f2ee2dd31ffedd8d77 Mon Sep 17 00:00:00 2001 From: Yoshisato Yanagisawa <yoshisato.yanagisawa@gmail.com> Date: Tue, 27 Feb 2024 16:17:13 +0900 Subject: [PATCH 26/26] Update spec.bs Co-authored-by: Domenic Denicola <d@domenic.me> --- spec.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.bs b/spec.bs index 2070238..a567e5a 100644 --- a/spec.bs +++ b/spec.bs @@ -340,7 +340,7 @@ Each {{URLPattern}} has an <dfn for="URLPattern">associated URL pattern</dfn>, a <div algorithm> To <dfn for=URLPattern>initialize</dfn> a {{URLPattern}} given a {{URLPattern}} |this|, {{URLPatternInput}} |input|, string or null |baseURL|, and {{URLPatternOptions}} |options|: - 1. Set |this|'s [=URLPattern/associated URL pattern=] to the result of running [=create=] given |input|, |baseURL|, and |options|. + 1. Set |this|'s [=URLPattern/associated URL pattern=] to the result of [=create=] given |input|, |baseURL|, and |options|. </div> <div algorithm>