1. URLパターン
1.1. はじめに
URLパターンは、複数のコンポーネントから構成されており、それぞれが パターンを表し、対応するURLのコンポーネントに対してマッチングされます。
各コンポーネントごとに文字列を使用して構築したり、簡易表記文字列から構築することができます。オプションで基準URLに対して相対的に解決することもできます。
簡易表記 "https://example.com/:category/*
" は、以下のコンポーネントに対応します:
- protocol
- "
https
" - username
- "
*
" - password
- "
*
" - hostname
- "
example.com
" - port
- ""
- pathname
- "
/:category/*
" - search
- "
*
" - hash
- "
*
"
次のURLにマッチします:
-
https://example.com/products/
-
https://example.com/blog/our-greatest-product-ever
次のURLにはマッチしません:
-
https://example.com/
-
http://example.com/products/
-
https://example.com:8443/blog/our-greatest-product-ever
このパターンは比較的単純で、ほとんどのコンポーネントが正確な文字列でマッチするか、任意の文字列("*
")を許容します。 pathname
コンポーネントは少なくとも2つの/
区切りのパスコンポーネントを持つパスにマッチし、最初のものが"category
"としてキャプチャされます。
簡易表記 "http{s}?://{:subdomain.}?shop.example/products/:id([0-9]+)#reviews
"
は、以下のコンポーネントに対応します:
- protocol
- "
http{s}?
" - username
- "
*
" - password
- "
*
" - hostname
- "
{:subdomain.}?shop.example
" - port
- ""
- pathname
- "
/products/:id([0-9]+)
" - search
- ""
- hash
- "
reviews
"
次のURLにマッチします:
-
https://shop.example/products/74205#reviews
-
https://kathryn@voyager.shop.example/products/74656#reviews
-
http://insecure.shop.example/products/1701#reviews
次のURLにはマッチしません:
-
https://shop.example/products/2000
-
http://shop.example:8080/products/0#reviews
-
https://nx.shop.example/products/01?speed=5#reviews
-
https://shop.example/products/chair#reviews
このパターンはより複雑で、以下を含みます:
簡易表記 "../admin/*
" に基準URL "https://discussion.example/forum/?page=2
"
を使用した場合、以下のコンポーネントに対応します:
- protocol
- "
https
" - username
- "
*
" - password
- "
*
" - hostname
- "
discussion.example
" - port
- ""
- pathname
- "
/admin/*
" - search
- "
*
" - hash
- "
*
"
次のURLにマッチします:
-
https://discussion.example/admin/
-
https://edd:librarian@discussion.example/admin/update?id=1
次のURLにはマッチしません:
-
https://discussion.example/forum/admin/
-
http://discussion.example:8080/admin/update?id=1
このパターンは、パス名が基準URLに対してどのように解決されるか、つまり相対URLのような挙動を示しています。
1.2. URLPattern
クラス
typedef (USVString or URLPatternInit ); [
URLPatternInput Exposed =(Window ,Worker )]interface {
URLPattern constructor (URLPatternInput ,
input USVString ,
baseURL optional URLPatternOptions = {});
options constructor (optional URLPatternInput = {},
input optional URLPatternOptions = {});
options boolean test (optional URLPatternInput = {},
input optional USVString );
baseURL URLPatternResult ?exec (optional URLPatternInput = {},
input optional USVString );
baseURL readonly attribute USVString protocol ;readonly attribute USVString username ;readonly attribute USVString password ;readonly attribute USVString hostname ;readonly attribute USVString port ;readonly attribute USVString pathname ;readonly attribute USVString search ;readonly attribute USVString hash ;readonly attribute boolean hasRegExpGroups ; };dictionary {
URLPatternInit USVString ;
protocol USVString ;
username USVString ;
password USVString ;
hostname USVString ;
port USVString ;
pathname USVString ;
search USVString ;
hash USVString ; };
baseURL dictionary {
URLPatternOptions boolean =
ignoreCase false ; };dictionary {
URLPatternResult sequence <URLPatternInput >;
inputs URLPatternComponentResult ;
protocol URLPatternComponentResult ;
username URLPatternComponentResult ;
password URLPatternComponentResult ;
hostname URLPatternComponentResult ;
port URLPatternComponentResult ;
pathname URLPatternComponentResult ;
search URLPatternComponentResult ; };
hash dictionary {
URLPatternComponentResult USVString ;
input record <USVString , (USVString or undefined )>; };
groups
各URLPattern
は関連付けられたURLパターン(URLパターン)を持ちます。
urlPattern = new
URLPattern
(input)- 新しい
URLPattern
オブジェクトを構築します。 inputは各URLコンポーネント(例:hostname, pathnameなど)ごとに個別のパターンを含むオブジェクトです。省略されたコンポーネントはワイルドカードパターンがデフォルトとなります。さらに、inputには欠落しているコンポーネントの静的テキストパターンを提供するbaseURL
プロパティを含めることができます。 urlPattern = new
URLPattern
(patternString, baseURL)- 新しい
URLPattern
オブジェクトを構築します。 patternStringは1つ以上のコンポーネントに対するパターン構文を含むURL文字列です。 baseURLが指定されている場合、patternStringは相対指定が可能です。このコンストラクタは少なくとも空文字列値を常にセットし、コンポーネントをワイルドカードパターンにデフォルトしません。 urlPattern = new
URLPattern
(input, options)- 新しい
URLPattern
オブジェクトを構築します。optionsはコンポーネントのマッチ方法に影響する追加設定オプションを含むオブジェクトです。現在はignoreCase
プロパティのみを持ち、trueにすると大文字小文字を区別しないマッチングが有効になります。デフォルト、つまりoptions引数がない場合、マッチングは常に大文字小文字を区別します。
urlPattern = new
URLPattern
(patternString, baseURL, options)- 新しい
URLPattern
オブジェクトを構築します。このオーバーロードは、patternStringオブジェクトからパターンを構築する際に、個々のコンポーネントや基準URLのパターンを記述するURLPatternOptions
オブジェクトをサポートします。 matches = urlPattern.
test
(input)- urlPatternが指定した引数にマッチするかテストします。inputは各URLコンポーネント(例:hostname,
pathnameなど)を表す文字列を含むオブジェクトです。省略されたコンポーネントは空文字列として扱われます。さらに、inputには欠落したコンポーネントの値を提供する
baseURL
プロパティを含めることができます。urlPatternがコンポーネント単位でinputにマッチすればtrueを返し、そうでなければfalseを返します。 matches = urlPattern.
test
(url, baseURL)- urlPatternが指定した引数にマッチするかテストします。urlはURL文字列です。baseURLが指定された場合、urlは相対指定が可能です。
urlPatternがコンポーネント単位でinputにマッチすればtrueを返し、そうでなければfalseを返します。
result = urlPattern.
exec
(input)- urlPatternを指定した引数に対して実行します。inputは各URLコンポーネント(例:hostname,
pathnameなど)を表す文字列を含むオブジェクトです。省略されたコンポーネントは空文字列として扱われます。さらに、inputには欠落したコンポーネントの値を提供するbaseURLプロパティを含めることができます。
urlPatternがコンポーネント単位でinputにマッチした場合、結果を含むオブジェクトが返されます。マッチしたグループ値はresultオブジェクト内の各コンポーネントのグループオブジェクト(例:
matches.pathname.groups.id
)に格納されます。マッチしなかった場合、resultはnullとなります。 result = urlPattern.
exec
(url, baseURL)- urlPatternを指定した引数に対して実行します。urlはURL文字列です。baseURLが指定された場合、inputは相対指定が可能です。
urlPatternがコンポーネント単位でinputにマッチした場合、結果を含むオブジェクトが返されます。マッチしたグループ値はresultオブジェクト内の各コンポーネントのグループオブジェクト(例:
matches.pathname.groups.id
)に格納されます。マッチしなかった場合、resultはnullとなります。 urlPattern.
protocol
-
urlPatternの正規化されたプロトコルパターン文字列を返します。
urlPattern.
username
-
urlPatternの正規化されたユーザー名パターン文字列を返します。
urlPattern.
password
-
urlPatternの正規化されたパスワードパターン文字列を返します。
urlPattern.
hostname
-
urlPatternの正規化されたホスト名パターン文字列を返します。
urlPattern.
port
-
urlPatternの正規化されたポートパターン文字列を返します。
urlPattern.
pathname
-
urlPatternの正規化されたパス名パターン文字列を返します。
urlPattern.
search
-
urlPatternの正規化された検索パターン文字列を返します。
urlPattern.
hash
-
urlPatternの正規化されたハッシュパターン文字列を返します。
urlPattern.
hasRegExpGroups
-
urlPatternが1つ以上の正規表現グループを含むかどうかを返します。
new URLPattern(input, baseURL, options)
コンストラクタの手順は以下の通りです:
-
initializeをthis、input、baseURL、optionsで実行します。
new URLPattern(input, options)
コンストラクタの手順は以下の通りです:
-
initializeをthis、input、null、optionsで実行します。
URLPattern
に対して、URLPattern
this、URLPatternInput
input、文字列またはnullbaseURL、URLPatternOptions
optionsの手順は以下の通りです:
-
thisの関連付けられたURLパターンに、createの結果(input、baseURL、options)をセットします。
protocol
getterの手順は以下の通りです:
username
getterの手順は以下の通りです:
password
getterの手順は以下の通りです:
hostname
getterの手順は以下の通りです:
port
getterの手順は以下の通りです:
-
thisの関連付けられたURLパターンのportコンポーネントのパターン文字列を返します。
pathname
getterの手順は以下の通りです:
search
getterの手順は以下の通りです:
hash
getterの手順は以下の通りです:
-
thisの関連付けられたURLパターンのhashコンポーネントのパターン文字列を返します。
hasRegExpGroups
getterの手順は以下の通りです:
-
もしthisの関連URLパターンが正規表現グループを持つ場合、trueを返す。
-
falseを返します。
test(input, baseURL)
メソッドの手順は以下の通り:
exec(input, baseURL)
メソッドの手順は以下の通りです:
-
matchの結果(thisの関連付けられたURLパターン、input、(あれば)baseURL)を返す。
1.3. URLパターン構造体
-
protocolコンポーネント、コンポーネント
-
usernameコンポーネント、コンポーネント
-
passwordコンポーネント、コンポーネント
-
hostnameコンポーネント、コンポーネント
-
portコンポーネント、コンポーネント
-
pathnameコンポーネント、コンポーネント
-
searchコンポーネント、コンポーネント
-
hashコンポーネント、コンポーネント
-
パターン文字列、well formedなパターン文字列
-
正規表現、
RegExp
-
グループ名リスト、文字列のリスト
-
正規表現グループを持つか、真偽値
1.4. 高レベルの操作
URLPatternInput
input、文字列またはnullbaseURL、およびURLPatternOptions
optionsで行う場合:
-
initをnullにする。
-
inputがスカラー値文字列の場合:
-
それ以外の場合:
-
アサート: inputは
URLPatternInit
である。 -
baseURLがnullでない場合、
TypeError
を投げる。 -
initにinputを設定する。
-
-
processedInitにURLPatternInitを処理するの結果(init, "
pattern
", null, null, null, null, null, null, null, null)を設定する。 -
« "
protocol
", "username
", "password
", "hostname
", "port
", "pathname
", "search
", "hash
" »の各componentNameについて: -
processedInit["
protocol
"] が特別なスキームであり、processedInit["port
"] がデフォルトポートをASCII数字で表す文字列の場合、processedInit["port
"]を空文字列に設定する。 -
urlPatternに新しいURLパターンを作成する。
-
urlPatternのprotocolコンポーネントにprocessedInit["
protocol
"]、プロトコルを正規化する、デフォルトオプションを使ってコンポーネントをコンパイルする結果を設定する。 -
urlPatternのusernameコンポーネントにprocessedInit["
username
"]、ユーザー名を正規化する、デフォルトオプションでコンポーネントをコンパイルする結果を設定する。 -
urlPatternのpasswordコンポーネントにprocessedInit["
password
"]、パスワードを正規化する、デフォルトオプションでコンポーネントをコンパイルする結果を設定する。 -
processedInit["
hostname
"]についてhostnameパターンがIPv6アドレスかの結果がtrueであれば、urlPatternのhostnameコンポーネントにprocessedInit["hostname
"]、IPv6ホスト名を正規化する、ホスト名オプションでコンポーネントをコンパイルする結果を設定する。 -
そうでなければ、urlPatternのhostnameコンポーネントにprocessedInit["
hostname
"]、ホスト名を正規化する、ホスト名オプションでコンポーネントをコンパイルする結果を設定する。 -
urlPatternのportコンポーネントにprocessedInit["
port
"]、ポートを正規化する、デフォルトオプションでコンポーネントをコンパイルする結果を設定する。 -
compileOptionsにデフォルトオプションのコピーを作成し、ignore caseプロパティにoptions["
ignoreCase
"]を設定する。 -
urlPatternのprotocolコンポーネントについてprotocolコンポーネントが特別なスキームにマッチするかの結果がtrueなら:
-
pathCompileOptionsにpathnameオプションのコピーを作成し、ignore caseプロパティにoptions["
ignoreCase
"]を設定する。 -
urlPatternのpathnameコンポーネントにprocessedInit["
pathname
"]、パス名を正規化する、pathCompileOptionsでコンポーネントをコンパイルする結果を設定する。
-
-
そうでなければ、urlPatternのpathnameコンポーネントにprocessedInit["
pathname
"]、不透明なパス名を正規化する、compileOptionsでコンポーネントをコンパイルする結果を設定する。 -
urlPatternのsearchコンポーネントにprocessedInit["
search
"]、検索を正規化する、compileOptionsでコンポーネントをコンパイルする結果を設定する。 -
urlPatternのhashコンポーネントにprocessedInit["
hash
"]、ハッシュを正規化する、compileOptionsでコンポーネントをコンパイルする結果を設定する。 -
urlPatternを返す。
URLPatternInput
または URL
input、省略可能な文字列 baseURLString を指定して次の手順を実行します:
-
protocol を空文字列にする。
-
username を空文字列にする。
-
password を空文字列にする。
-
hostname を空文字列にする。
-
port を空文字列にする。
-
pathname を空文字列にする。
-
search を空文字列にする。
-
hash を空文字列にする。
-
inputs を空のリストにする。
-
それ以外の場合は、appendでinputをinputsへ追加する。
-
inputが
URLPatternInit
であれば:-
baseURLStringが指定されている場合は
TypeError
を投げる。 -
applyResultにinput、"url"、protocol、username、password、hostname、port、pathname、search、hashでURLPatternInitを処理するの結果を設定する。例外が発生した場合はキャッチし、nullを返す。
-
protocolにapplyResult["
protocol
"]を設定する。 -
usernameにapplyResult["
username
"]を設定する。 -
passwordにapplyResult["
password
"]を設定する。 -
hostnameにapplyResult["
hostname
"]を設定する。 -
portにapplyResult["
port
"]を設定する。 -
pathnameにapplyResult["
pathname
"]を設定する。 -
searchにapplyResult["
search
"]を設定する。 -
hashにapplyResult["
hash
"]を設定する。
-
-
それ以外の場合:
-
protocolExecResultにRegExpBuiltinExec(urlPatternのprotocolコンポーネントの正規表現, protocol)を設定する。
-
usernameExecResultにRegExpBuiltinExec(urlPatternのusernameコンポーネントの正規表現, username)を設定する。
-
passwordExecResultにRegExpBuiltinExec(urlPatternのpasswordコンポーネントの正規表現, password)を設定する。
-
hostnameExecResultにRegExpBuiltinExec(urlPatternのhostnameコンポーネントの正規表現, hostname)を設定する。
-
portExecResultにRegExpBuiltinExec(urlPatternのportコンポーネントの正規表現, port)を設定する。
-
pathnameExecResultにRegExpBuiltinExec(urlPatternのpathnameコンポーネントの正規表現, pathname)を設定する。
-
searchExecResultにRegExpBuiltinExec(urlPatternのsearchコンポーネントの正規表現, search)を設定する。
-
hashExecResultにRegExpBuiltinExec(urlPatternのhashコンポーネントの正規表現, hash)を設定する。
-
いずれかのExecResultがnullならnullを返す。
-
resultに新しい
URLPatternResult
を設定する。 -
result["
inputs
"]にinputsを設定する。 -
result["
protocol
"]にコンポーネントマッチ結果を作成する(urlPatternのprotocolコンポーネント, protocol, protocolExecResult)の結果を設定する。 -
result["
username
"]にコンポーネントマッチ結果を作成する(urlPatternのusernameコンポーネント, username, usernameExecResult)の結果を設定する。 -
result["
password
"]にコンポーネントマッチ結果を作成する(urlPatternのpasswordコンポーネント, password, passwordExecResult)の結果を設定する。 -
result["
hostname
"]にコンポーネントマッチ結果を作成する(urlPatternのhostnameコンポーネント, hostname, hostnameExecResult)の結果を設定する。 -
result["
port
"]にコンポーネントマッチ結果を作成する(urlPatternのportコンポーネント, port, portExecResult)の結果を設定する。 -
result["
pathname
"]にコンポーネントマッチ結果を作成する(urlPatternのpathnameコンポーネント, pathname, pathnameExecResult)の結果を設定する。 -
result["
search
"]にコンポーネントマッチ結果を作成する(urlPatternのsearchコンポーネント, search, searchExecResult)の結果を設定する。 -
result["
hash
"]にコンポーネントマッチ結果を作成する(urlPatternのhashコンポーネント, hash, hashExecResult)の結果を設定する。 -
resultを返す。
-
urlPatternのprotocolコンポーネントの正規表現グループを持つかがtrueならtrueを返す。
-
urlPatternのusernameコンポーネントの正規表現グループを持つかがtrueならtrueを返す。
-
urlPatternのpasswordコンポーネントの正規表現グループを持つかがtrueならtrueを返す。
-
urlPatternのhostnameコンポーネントの正規表現グループを持つかがtrueならtrueを返す。
-
urlPatternのportコンポーネントの正規表現グループを持つかがtrueならtrueを返す。
-
urlPatternのpathnameコンポーネントの正規表現グループを持つかがtrueならtrueを返す。
-
urlPatternのsearchコンポーネントの正規表現グループを持つかがtrueならtrueを返す。
-
urlPatternのhashコンポーネントの正規表現グループを持つかがtrueならtrueを返す。
-
falseを返す。
1.5. 内部仕様
-
part listにinput、options、encoding callbackでパターン文字列をパースするの結果を設定する。
-
(regular expression string, name list)にpart list、optionsで正規表現と名前リストを生成するの結果を設定する。
-
flagsを空文字列にする。
-
optionsのignore caseがtrueなら、flagsに"
vi
"を設定する。 -
そうでなければflagsに"
v
"を設定する。 -
regular expressionにRegExpCreate(regular expression string, flags)の結果を設定する。例外が発生した場合はキャッチし、
TypeError
を投げる。仕様はすべてのマッチングに正規表現を使用しますが、これは必須ではありません。実装はpart listに対して直接マッチングしても構いません(例えばカスタム正規表現グループがない場合)。ただしカスタム正規表現がある場合は、コンポーネントをコンパイルするで即座に評価され、無効な場合はエラーを投げることが重要です。
-
pattern stringにpart list、optionsでパターン文字列を生成するの結果を設定する。
-
has regexp groupsをfalseにする。
-
各partをpart listについて:
-
コンポーネントを新規作成し、パターン文字列にpattern string、正規表現にregular expression、グループ名リストにname list、正規表現グループを持つかにhas regexp groupsを設定して返す。
-
resultに新しい
URLPatternComponentResult
を設定する。 -
result["
input
"]にinputを設定する。 -
indexを1にする。
-
indexがGet(execResult, "
length
")未満の間: -
result["
groups
"]にgroupsを設定する。 -
resultを返す。
-
dummyInputに"
https://dummy.invalid/
"を設定する。 -
dummyInputで基本URLパーサを実行した結果を返す。
デフォルトオプションは、optionsの構造体であり、区切りコードポイントを空文字列、プレフィックスコードポイントを空文字列として設定します。
ホスト名オプションは、optionsの構造体であり、区切りコードポイントを".
"、プレフィックスコードポイントを空文字列として設定します。
パス名オプションは、optionsの構造体であり、区切りコードポイントを"/
"、プレフィックスコードポイントを"/
"として設定します。
-
各schemeをspecial scheme listについて:
-
test resultにRegExpBuiltinExec(protocol componentの正規表現, scheme)を設定する。
-
test resultがnullでなければtrueを返す。
-
-
falseを返す。
1.6. コンストラクタ文字列のパース
コンストラクタ文字列パーサは、構造体です。
コンストラクタ文字列パーサは、関連付けられたinput(文字列)を持ち、作成時に設定されなければなりません。
コンストラクタ文字列パーサは、関連付けられたtoken list(トークンリスト)を持ち、作成時に設定されなければなりません。
コンストラクタ文字列パーサは、関連付けられたresult(URLPatternInit
)を持ち、初期値は新しいURLPatternInit
です。
コンストラクタ文字列パーサは、関連付けられたcomponent start(数値)を持ち、初期値は0です。
コンストラクタ文字列パーサは、関連付けられたtoken index(数値)を持ち、初期値は0です。
コンストラクタ文字列パーサは、関連付けられたtoken increment(数値)を持ち、初期値は1です。
コンストラクタ文字列パーサは、関連付けられたgroup depth(数値)を持ち、初期値は0です。
コンストラクタ文字列パーサは、関連付けられたhostname IPv6 bracket depth(数値)を持ち、 初期値は0です。
コンストラクタ文字列パーサは、関連付けられたprotocol matches a special scheme flag(真偽値)を持ち、初期値はfalseです。
コンストラクタ文字列パーサは、関連付けられたstate(文字列)を持ち、初期値は"init
"です。次のいずれかでなければなりません:
- "
init
" - "
protocol
" - "
authority
" - "
username
" - "
password
" - "
hostname
" - "
port
" - "
pathname
" - "
search
" - "
hash
" - "
done
"
URLPatternのコンストラクタ文字列アルゴリズムは、基本URLパーサのアルゴリズムと非常に似ていますが、いくつかの違いにより直接利用はできません。
まず、URLPatternのコンストラクタ文字列パーサは"lenient
"tokenize policyで生成されたトークンを操作します。対して基本URLパーサはコードポイントを操作します。トークンで操作することで、URLPatternのコンストラクタ文字列パーサは、重要なパターン構文となるコードポイントと、URLコンポーネントの区切りになりうるコードポイントを容易に区別できます。例えば、"https://a.c:hmm.example.com:8080
"の":hmm
"のような名前付きグループをポート番号と混同せず簡単に扱うことができます。
次に、URLPatternのコンストラクタ文字列パーサは、基本URLパーサのようにすべてのコードポイントにURL正規化を適用しない必要があります。代わりに、各コンポーネントのパターン文字列を後でコンパイルする際に、安全だと分かっている部分だけ正規化します。
最後に、URLPatternのコンストラクタ文字列パーサは基本URLパーサのステートマシンの一部を扱いません。例えば、バックスラッシュはすべてパターン文字とみなされ、過剰なエスケープが必要となるため特別扱いしません。また、このパーサはファイルURLのホスト名など、URLパースアルゴリズムのより特殊な部分は扱わない場合があります。このパーサの目的は、最も一般的なURLを扱いつつ、ニッチなケースは代わりにURLPatternInit
コンストラクタで対応できるようにすることです。
コンストラクタ文字列アルゴリズムでは、pathname、search、hashは前のコンポーネントが指定されていて後のコンポーネントが省略されている場合にワイルドカードとなります。例えば
"https://example.com/foo
" は任意のsearchと任意のhashにマッチします。同様に、"https://example.com
"
はそのオリジン上の任意のURLにマッチします。これはURLPatternInitを処理するの注記にある、より具体的なコンポーネントの概念に類似しています(例えばsearchはpathnameより具体的)が、コンストラクタ構文ではより具体的なコンポーネントのみを指定して、より抽象的なコンポーネントを省略できるケースは少数です。
usernameとpasswordコンポーネントは、明示的に指定しない限り常にワイルドカードとなります。
hostnameが指定され、portが指定されていない場合、portはデフォルトポートとみなされます。任意のポートにマッチさせたい場合は :*
を明示的に記述する必要があります。例えば
"https://*
" はポート443上の任意のHTTPSオリジン、"https://*:*
" は任意のポート上の任意のHTTPSオリジンです。
-
parserに新しいコンストラクタ文字列パーサを作成し、inputにinput、token listにinputと"
lenient
"でtokenizeした結果を設定する。 -
While parserのtoken indexがparserのtoken listのサイズ未満の場合:
-
parserのtoken incrementを1に設定する。
parseループの各イテレーションで、parserのtoken indexはtoken increment分だけ増加します。通常は1ですが、場合によっては0に設定されることがあります。token incrementはループの先頭で常に1にリセットされます。
-
parserのtoken list[parserのtoken index]のtypeが"
end
"の場合:-
"
init
"stateで文字列末尾に到達した場合、プロトコールの終端が見つからず、相対URLPatternのコンストラクタ文字列である必要があります。-
rewindをparserで実行する。
次に、相対パターンがどのコンポーネントから始まるか判定します。相対pathnameが最も一般的ですが、URLやURLPatternのコンストラクタ文字列はsearchやhashコンポーネントから始まることもあります。
-
is a hash prefixをparserで実行した結果がtrueなら、change stateをparser、"
hash
"および1で実行する。 -
それ以外でis a search prefixをparserで実行した結果がtrueなら:
-
change stateをparser、"
search
"および1で実行する。
-
-
それ以外:
-
change stateをparser、"
pathname
"および0で実行する。
-
-
parserのtoken indexをtoken increment分だけ増やす。
-
-
"
authority
"stateで文字列末尾に到達した場合、"@
"が見つからず、usernameやpasswordはありません。-
rewind and set stateをparser、"
hostname
"で実行する。 -
parserのtoken indexをtoken increment分だけ増やす。
-
-
change stateをparser、"
done
"および0で実行する。
-
-
is a group openをparserで実行した結果がtrueの場合:
"
{ ... }
"パターングループ内のコードポイントはすべて無視されます。パターングループ内にURLコンポーネント境界を許すのは不適切です(例: "https://example.c{om/fo}o
")。well formedなパターン文字列ではサポートされていませんが、ネストされたグループにも対応しパーサの混乱を避けます。このロジックはregexpや名前付きグループには不要です。これらはtoken化アルゴリズムで単一トークンにまとめられるためです。
-
parserのgroup depthを1増やす。
-
parserのtoken indexをtoken increment分だけ増やす。
-
-
parserのgroup depthが0より大きい場合:
-
is a group closeをparserで実行した結果がtrueなら、parserのgroup depthを1減らす。
-
それ以外:
-
parserのtoken indexをtoken increment分だけ増やす。
-
-
-
parserのstateごとに以下の手順を実行:
- "
init
" -
-
is a protocol suffixをparserで実行しtrueなら:
-
rewind and set stateをparserと"
protocol
"で実行する。
-
-
- "
protocol
" -
-
is a protocol suffixをparserで実行しtrueなら:
-
compute protocol matches a special scheme flagをparserで実行する。
プロトコールコンポーネントを即座にコンパイルし、特別なスキームにマッチするか判定します。マッチする場合は特別なルールが適用されます。たとえばpathnameが"
/
"になるか、username/password/hostname/portコンポーネントを探すかどうか決まります。authority slashesもこれらのコンポーネント探索に影響します。そうでなければ「不透明パスURL」としてpathnameへ進みます。 -
next stateに"
pathname
"を設定する。 -
skipに1を設定する。
-
next is authority slashesをparserで実行しtrueなら:
-
next stateに"
authority
"を設定する。 -
skipに3を設定する。
-
-
それ以外でparserのprotocol matches a special scheme flagがtrueなら、next stateに"
authority
"を設定する。 -
change stateをparser、next state、skipで実行する。
-
-
- "
authority
" -
-
is an identity terminatorをparserで実行しtrueなら、rewind and set stateをparser、"
username
"で実行する。 -
それ以外で以下のいずれかがtrueなら:
- is a pathname startをparserで実行した結果
- is a search prefixをparserで実行した結果
- is a hash prefixをparserで実行した結果
の場合、rewind and set stateをparser、"
hostname
"で実行する。
-
- "
username
" -
-
is a password prefixをparserで実行しtrueなら、change stateをparser、"
password
"および1で実行する。 -
それ以外でis an identity terminatorをparserで実行しtrueなら、change stateをparser、"
hostname
"および1で実行する。
-
- "
password
" -
-
is an identity terminatorをparserで実行しtrueなら、change stateをparser、"
hostname
"および1で実行する。
-
- "
hostname
" -
-
is an IPv6 openをparserで実行しtrueなら、parserのhostname IPv6 bracket depthを1増やす。
-
それ以外でis an IPv6 closeをparserで実行しtrueなら、parserのhostname IPv6 bracket depthを1減らす。
-
それ以外でis a port prefixをparserで実行し、かつparserのhostname IPv6 bracket depthが0なら、change stateをparser、"
port
"および1で実行する。 -
それ以外でis a pathname startをparserで実行しtrueなら、change stateをparser、"
pathname
"および0で実行する。 -
それ以外でis a search prefixをparserで実行しtrueなら、change stateをparser、"
search
"および1で実行する。 -
それ以外でis a hash prefixをparserで実行しtrueなら、change stateをparser、"
hash
"および1で実行する。
-
- "
port
" -
-
is a pathname startをparserで実行しtrueなら、change stateをparser、"
pathname
"および0で実行する。 -
それ以外でis a search prefixをparserで実行しtrueなら、change stateをparser、"
search
"および1で実行する。 -
それ以外でis a hash prefixをparserで実行しtrueなら、change stateをparser、"
hash
"および1で実行する。
-
- "
pathname
" -
-
is a search prefixをparserで実行しtrueなら、change stateをparser、"
search
"および1で実行する。 -
それ以外でis a hash prefixをparserで実行しtrueなら、change stateをparser、"
hash
"および1で実行する。
-
- "
search
" -
-
is a hash prefixをparserで実行しtrueなら、change stateをparser、"
hash
"および1で実行する。
-
- "
hash
" -
-
何もしない。
-
- "
done
" -
-
Assert: このステップには到達しません。
-
- "
-
parserのtoken indexをtoken increment分だけ増やす。
-
-
parserのresultが"
hostname
"を含み、かつ"port
"を含まない場合、parserのresult["port
"]に空文字列を設定する。これは特例です。著者がportを指定しない場合、通常はデフォルトポートを意図しています。任意のポートを許可する場合はワイルドカードを明示する必要があります。例えば"https://example.com/*
"は"https://example.com:8443/
"で始まるURL(異なるオリジン)にはマッチしません。 -
parserのresultを返す。
-
parserのstateが"
init
"、"authority
"、"done
"以外の場合、 parserのresult[parserのstate]にコンポーネント文字列を作成するの結果を設定する。 -
parserのstateが"
init
"でなく、new stateが"done
"でない場合:-
parserのstateが"
protocol
"、 "authority
"、 "username
"、 または"password
"、 かつnew stateが"port
"、"pathname
"、 "search
"、 または"hash
"であり、 parserのresult["hostname
"] が存在しない場合、parserのresult["hostname
"] に空文字列を設定する。 -
parserのstateが"
protocol
"、 "authority
"、 "username
"、 "password
"、 "hostname
"、 または"port
"、 かつnew stateが"search
"または"hash
"であり、 parserのresult["pathname
"] が存在しない場合:-
parserのprotocol matches a special scheme flagがtrueなら、 parserのresult["
pathname
"] に"/
"を設定する。
-
-
parserのstateが"
protocol
"、 "authority
"、 "username
"、 "password
"、 "hostname
"、 "port
"、 または"pathname
"、 かつnew stateが"hash
"であり、 parserのresult["search
"] が存在しない場合、 parserのresult["search
"] に空文字列を設定する。
-
-
parserのstateにnew stateを設定する。
-
parserのtoken indexをskip分だけ増やす。
-
parserのcomponent startに parserのtoken indexを設定する。
-
parserのtoken incrementを0に設定する。
-
parserのtoken indexにparserの component startを設定する。
-
parserのtoken incrementを0に設定する。
-
indexがparserのtoken listのサイズ未満なら、 parserのtoken list[index]を返す。
-
アサート: parserのtoken listのサイズは1以上。
-
last indexにparserのtoken listのサイズ−1を設定する。
-
tokenにparserのtoken list[last index]を設定する。
-
tokenを返す。
-
tokenに安全なトークンを取得するをparser、indexで実行した結果を設定する。
-
tokenのvalueがvalueでなければfalseを返す。
-
以下のいずれかがtrueの場合:
- tokenのtypeが"
char
"である。 - tokenのtypeが"
escaped-char
"である。 - tokenのtypeが"
invalid-char
"である。
場合はtrueを返す。
- tokenのtypeが"
-
falseを返す。
-
特殊でないパターン文字か判定するをparser、parserのtoken index、"
:
"で実行した結果を返す。
-
特殊でないパターン文字か判定するをparser、parserのtoken index+1、"
/
"で実行した結果がfalseならfalseを返す。 -
特殊でないパターン文字か判定するをparser、parserのtoken index+2、"
/
"で実行した結果がfalseならfalseを返す。 -
trueを返す。
-
特殊でないパターン文字か判定するをparser、parserのtoken index、"
@
"で実行した結果を返す。
-
特殊でないパターン文字か判定するをparser、parserのtoken index、"
:
"で実行した結果を返す。
-
特殊でないパターン文字か判定するをparser、parserのtoken index、"
:
"で実行した結果を返す。
-
特殊でないパターン文字か判定するをparser、parserのtoken index、"
/
"で実行した結果を返す。
-
特殊でないパターン文字か判定するをparser、parserのtoken index、"
?
"で実行した結果がtrueならtrueを返す。 -
parserのtoken list[parserのtoken index]のvalueが"
?
"でなければfalseを返す。 -
previous indexにparserのtoken index−1を設定する。
-
previous indexが0未満ならtrueを返す。
-
previous tokenに安全なトークンを取得するをparser、previous indexで実行した結果を設定する。
-
以下のいずれかがtrueならfalseを返す:
-
trueを返す。
-
特殊でないパターン文字か判定するをparser、parserのtoken index、"
#
"で実行した結果を返す。
-
parserのtoken list[parserのtoken index]のtypeが"
open
"ならtrueを返す。 -
それ以外はfalseを返す。
-
parserのtoken list[parserのtoken index]のtypeが"
close
"ならtrueを返す。 -
それ以外はfalseを返す。
-
特殊でないパターン文字か判定するをparser、parserのtoken index、"
[
"で実行した結果を返す。
-
特殊でないパターン文字か判定するをparser、parserのtoken index、"
]
"で実行した結果を返す。
-
アサート: parserのtoken indexはparserのtoken listのサイズ未満。
-
tokenにparserのtoken list[parserのtoken index]を設定する。
-
component start tokenに安全なトークンを取得するをparser、parserのcomponent startで実行した結果を設定する。
-
component start input indexにcomponent start tokenのindexを設定する。
-
end indexにtokenのindexを設定する。
-
parserのinputのcomponent start input indexからend indexまでのコードポイント部分文字列を返す。
-
protocol stringにコンポーネント文字列を作成するをparserで実行した結果を設定する。
-
protocol componentにコンポーネントをコンパイルするをprotocol string、プロトコルを正規化する、デフォルトオプションで実行した結果を設定する。
-
protocolコンポーネントが特別なスキームにマッチするかをprotocol componentで実行しtrueなら、parserのprotocol matches a special scheme flagにtrueを設定する。
2. パターン文字列
パターン文字列は、対象となる文字列の集合にマッチするように記述された文字列です。well formedなパターン文字列は特定のパターン構文に従います。このパターン構文は、人気のあるJavaScriptライブラリ path-to-regexp の構文に直接基づいています。
パースすることで、パートリストが生成され、パターン文字列がマッチするためにコンポーネント文字列に何が順番に現れるべきかを説明します。
/
、hostnameなら.
)までマッチします。例えば、pathnameのパターン
"/blog/:title
" は "/blog/hello-world
" にはマッチしますが "/blog/2012/02
"
にはマッチしません。
括弧で囲んだ正規表現を使うこともでき、pathnameのパターン "/blog/:year(\d+)/:month(\d+)
" は
"/blog/2012/02
" にマッチします。
グループはオプションや繰り返しにすることもできます。例えば、pathnameのパターン "/products/:id?
"
は "/products
" と "/products/2
" の両方にマッチします("/products/
"
にはマッチしません)。pathnameではグループは自動的に先頭に/
が必要ですが、これを避けたい場合は明示的に区切ることができ、"/products/{:id}?
"
のように記述します。
フルワイルドカード*
も使え、例えばpathnameパターン "/products/*
" のようにできるだけ多くマッチさせることができます。
2.1. パターン文字列のパース
2.1.1. トークン
トークンリストは、リストであり、ゼロ個以上のトークン構造体を含みます。
トークンは、構造体であり、 パターン文字列内の一つの字句トークンを表します。
トークンには関連付けられたtype(文字列)があり、初期値は"invalid-char
"です。次のいずれかでなければなりません:
- "
open
" - このトークンはU+007B(
{
)コードポイントを表します。 - "
close
" - このトークンはU+007D(
}
)コードポイントを表します。 - "
regexp
" - このトークンは"
(<正規表現>)
"形式の文字列を表します。正規表現はASCIIコードポイントのみで構成されている必要があります。 - "
name
" - このトークンは"
:<name>
"形式の文字列を表します。name値はJavaScript識別子として許容されるコードポイントに制限されます。 - "
char
" - このトークンは特別な構文的意味を持たない有効なパターンコードポイントを表します。
- "
escaped-char
" - このトークンはバックスラッシュでエスケープされたコードポイント(例:
"
\<char>
")を表します。 - "
other-modifier
" - このトークンは、マッチンググループ修飾子(U+003F(
?
)、U+002B(+
))を表します。 - "
asterisk
" - このトークンはU+002A(
*
)コードポイントを表し、ワイルドカードマッチンググループまたはマッチンググループ修飾子となります。 - "
end
" - このトークンはパターン文字列の終端を表します。
- "
invalid-char
" - このトークンはパターン内で無効なコードポイントを表します。これはコードポイント自体が原因の場合もあれば、パターン内で他の構文要素との相対的位置が原因の場合もあります。
トークンには関連付けられたindex(数値)があり、初期値は0です。これはパターン文字列内でこのトークンが表す最初のコードポイントの位置です。
トークンには関連付けられたvalue(文字列)があり、初期値は空文字列です。これはパターン文字列内でこのトークンが表すコードポイントを含みます。
2.1.2. トークン化
トークン化ポリシーは、"strict
" または "lenient
"のいずれかでなければならない文字列です。
トークナイザは、構造体です。
トークナイザには関連付けられたinput(パターン文字列、初期値は空文字列)があります。
トークナイザには関連付けられたpolicy(トークン化ポリシー、初期値は"strict
")があります。
トークナイザには関連付けられたtoken list(トークンリスト、初期値は空のリスト)があります。
トークナイザには関連付けられたindex(数値、初期値は0)があります。
トークナイザには関連付けられたnext index(数値、初期値は0)があります。
トークナイザには関連付けられたcode point(Unicodeコードポイント、初期値はnull)があります。
-
tokenizerに新しいトークナイザを作成する。
-
tokenizerのinputにinputを設定する。
-
tokenizerのpolicyにpolicyを設定する。
-
tokenizerのindexがtokenizerのinputのコードポイント長未満の間:
-
次のコードポイントを取得するをtokenizer、tokenizerのindexで実行する。
-
tokenizerのcode pointがU+002A(
*
)の場合:-
デフォルト位置と長さでトークンを追加するをtokenizer、"
asterisk
"で実行する。
-
-
tokenizerのcode pointがU+002B(
+
)またはU+003F(?
)の場合:-
デフォルト位置と長さでトークンを追加するをtokenizer、"
other-modifier
"で実行する。
-
-
tokenizerのcode pointがU+005C(
\
)の場合:-
tokenizerのindexがtokenizerのinputのコードポイント長−1と等しい場合:
-
トークン化エラー処理をtokenizer、tokenizerのnext index、tokenizerのindexで実行する。
-
-
escaped indexにtokenizerのnext indexを設定する。
-
次のコードポイントを取得するをtokenizerで実行する。
-
デフォルト長さでトークンを追加するをtokenizer、"
escaped-char
"、tokenizerのnext index、escaped indexで実行する。
-
-
tokenizerのcode pointがU+007B(
{
)の場合:-
デフォルト位置と長さでトークンを追加するをtokenizer、"
open
"で実行する。
-
-
tokenizerのcode pointがU+007D(
}
)の場合:-
デフォルト位置と長さでトークンを追加するをtokenizer、"
close
"で実行する。
-
-
tokenizerのcode pointがU+003A(
:
)の場合:-
name positionにtokenizerのnext indexを設定する。
-
name startにname positionを設定する。
-
name positionがtokenizerのinputのコードポイント長未満の間:
-
次のコードポイントを取得するをtokenizer、name positionで実行する。
-
first code pointがname position==name startならtrue、そうでなければfalse。
-
valid code pointに有効なnameコードポイントか判定をtokenizerのcode point、first code pointで実行した結果を設定する。
-
valid code pointがfalseならbreak。
-
name positionにtokenizerのnext indexを設定する。
-
-
name positionがname start以下の場合:
-
トークン化エラー処理をtokenizer、name start、tokenizerのindexで実行する。
-
-
デフォルト長さでトークンを追加するをtokenizer、"
name
"、name position、name startで実行する。
-
-
tokenizerのcode pointがU+0028(
(
)の場合:-
depthに1を設定する。
-
regexp positionにtokenizerのnext indexを設定する。
-
regexp startにregexp positionを設定する。
-
errorにfalseを設定する。
-
regexp positionがtokenizerのinputのコードポイント長未満の間:
-
次のコードポイントを取得するをtokenizer、regexp positionで実行する。
-
tokenizerのcode pointがASCIIコードポイントでなければ:
-
トークン化エラー処理をtokenizer、regexp start、tokenizerのindexで実行する。
-
errorにtrueを設定する。
-
-
regexp position==regexp startかつtokenizerのcode pointがU+003F(
?
)の場合:-
トークン化エラー処理をtokenizer、regexp start、tokenizerのindexで実行する。
-
errorにtrueを設定する。
-
-
tokenizerのcode pointがU+005C(
\
)の場合:-
regexp position==tokenizerのinputのコードポイント長−1の場合:
-
トークン化エラー処理をtokenizer、regexp start、tokenizerのindexで実行する。
-
errorにtrueを設定する。
-
-
次のコードポイントを取得するをtokenizerで実行する。
-
tokenizerのcode pointがASCIIコードポイントでなければ:
-
トークン化エラー処理をtokenizer、regexp start、tokenizerのindexで実行する。
-
errorにtrueを設定する。
-
-
regexp positionにtokenizerのnext indexを設定する。
-
-
tokenizerのcode pointがU+0029(
)
)の場合:-
depthを1減らす。
-
depthが0の場合:
-
regexp positionにtokenizerのnext indexを設定する。
-
-
-
それ以外でtokenizerのcode pointがU+0028(
(
)の場合:-
depthを1増やす。
-
regexp position==tokenizerのinputのコードポイント長−1の場合:
-
トークン化エラー処理をtokenizer、regexp start、tokenizerのindexで実行する。
-
errorにtrueを設定する。
-
-
temporary positionにtokenizerのnext indexを設定する。
-
次のコードポイントを取得するをtokenizerで実行する。
-
tokenizerのcode pointがU+003F(
?
)でない場合:-
トークン化エラー処理をtokenizer、regexp start、tokenizerのindexで実行する。
-
errorにtrueを設定する。
-
-
tokenizerのnext indexにtemporary positionを設定する。
-
-
regexp positionにtokenizerのnext indexを設定する。
-
-
errorがtrueならcontinue。
-
depthが0でなければ:
-
トークン化エラー処理をtokenizer、regexp start、tokenizerのindexで実行する。
-
-
regexp lengthにregexp position−regexp start−1を設定する。
-
regexp lengthが0の場合:
-
トークン化エラー処理をtokenizer、regexp start、tokenizerのindexで実行する。
-
-
トークンを追加するをtokenizer、"
regexp
"、regexp position、regexp start、regexp lengthで実行する。
-
-
デフォルト位置と長さでトークンを追加するをtokenizer、"
char
"で実行する。
-
-
デフォルト長さでトークンを追加するをtokenizer、"
end
"、tokenizerのindex、tokenizerのindexで実行する。 -
tokenizerのtoken listを返す。
-
tokenizerのcode pointに、tokenizerのinputのtokenizerのnext indexで示される位置のUnicodeコードポイントを設定する。
-
tokenizerのnext indexを1増やす。
-
tokenizerのnext indexにindexを設定する。
-
次のコードポイントを取得するをtokenizerで実行する。
-
tokenに新しいトークンを作成する。
-
tokenのtypeにtypeを設定する。
-
tokenのvalueに、tokenizerのinput内のvalue positionからvalue length分のコードポイント部分文字列を設定する。
-
appendでtokenをtokenizerのtoken listの末尾に追加する。
-
tokenizerのindexにnext positionを設定する。
-
computed lengthにnext position−value positionを設定する。
-
トークンを追加するをtokenizer、type、next position、value position、computed lengthで実行する。
-
デフォルト長さでトークンを追加するをtokenizer、type、tokenizerのnext index、tokenizerのindexで実行する。
-
デフォルト長さでトークンを追加するをtokenizer、"
invalid-char
"、next position、value positionで実行する。
-
firstがtrueなら、code pointがIdentifierStartコードポイント集合に含まれるかどうかをチェックした結果を返す。
-
それ以外の場合、code pointがIdentifierPartコードポイント集合に含まれるかどうかをチェックした結果を返す。
2.1.3. パーツ
パートは、パーサーの構造体であり、1つのパターン文字列の一部を表します。最大1つのマッチンググループ、固定テキストのプレフィックス、固定テキストのサフィックス、修飾子を含むことができます。最小では、1つの固定テキスト文字列または1つのマッチンググループのみを含むこともできます。
パートには、関連付けられたタイプ(文字列)があり、作成時に設定する必要があります。次のいずれかでなければなりません:
- "
fixed-text
" - パートは単純な固定テキスト文字列を表します。
- "
regexp
" - パートはカスタム正規表現によるマッチンググループを表します。
- "
segment-wildcard
" - パートは、次のセパレーターコードポイントまでのコードポイントにマッチするマッチンググループを表します。これは通常、カスタム正規表現を持たない「
:foo
」のような名前付きグループで使用されます。 - "
full-wildcard
" - パートは、すべてのコードポイントにグリーディにマッチするマッチンググループを表します。これは通常、「
*
」ワイルドカードマッチンググループで使用されます。
パートには、関連付けられた値(文字列)があり、作成時に設定する必要があります。
パートには、関連付けられた修飾子(文字列)があり、作成時に設定する必要があります。次のいずれかでなければなりません:
- "
none
" - パートには修飾子がありません。
- "
optional
" - パートには、U+003F(
?
)コードポイントによって示されるオプションの修飾子があります。 - "
zero-or-more
" - パートには、U+002A(
*
)コードポイントによって示される「0回以上」の修飾子があります。 - "
one-or-more
" - パートには、U+002B(
+
)コードポイントによって示される「1回以上」の修飾子があります。
パートには、関連付けられた名前(文字列)があり、初期値は空文字列です。
パートには、関連付けられたプレフィックス(文字列)があり、初期値は空文字列です。
パートには、関連付けられたサフィックス(文字列)があり、初期値は空文字列です。
2.1.4. オプション
オプション 構造体は、パターン文字列の動作を制御するさまざまな設定を含みます。これらのオプションは元々path-to-regexpから来ています。現行標準では、URLPattern仕様内で変更されるオプションのみを含み、他のオプションは除外します。比較のために、この仕様はpath-to-regexpと同様にstrict
、start
、end
が常にfalseとなります。
オプションには、関連付けられたデリミターコードポイント(文字列)があり、作成時に設定する必要があります。1つのASCIIコードポイントまたは空文字列でなければなりません。このコードポイントはセグメントセパレーターとして扱われ、デフォルトで「:foo
」の名前付きグループがどこまでマッチするかを決定するために使用されます。例えば、デリミターコードポイントが「/
」の場合、「/:foo
」は「/bar
」にマッチしますが、「/bar/baz
」にはマッチしません。デリミターコードポイントが空文字列の場合、上記のパターンは両方の文字列にマッチします。
オプションには、関連付けられたプレフィックスコードポイント(文字列)があり、作成時に設定する必要があります。1つのASCIIコードポイントまたは空文字列でなければなりません。このコードポイントは、マッチグループの直前に現れた場合、自動プレフィックスとして扱われます。これは、マッチグループがオプションまたは繰り返しに変更された場合に重要です。例えば、プレフィックスコードポイントが「/
」の場合、「/foo/:bar?/baz
」では「:bar
」の前の「/
」が、名前付きグループとともにオプションのプレフィックスとして扱われます。したがって、この例のパターンは「/foo/baz
」にもマッチします。
オプションには、関連付けられた大文字・小文字を無視する(ブール値)があり、作成時に設定する必要があります。デフォルトはfalseです。設定値(trueまたはfalse)に応じて、このフラグは大文字・小文字を区別するかどうかを制御します。比較のために、このフラグはpath-to-regexpのsensitive
オプションの否定として考えることができます。
2.1.5. パース
パターンパーサーは、構造体です。
パターンパーサーには、関連付けられたトークンリスト(トークンリスト)があり、初期値は空のリストです。
パターンパーサーには、関連付けられたエンコーディングコールバック(エンコーディングコールバック)があり、作成時に設定する必要があります。
パターンパーサーには、関連付けられたセグメントワイルドカード正規表現(文字列)があり、作成時に設定する必要があります。
パターンパーサーには、関連付けられたパートリスト(パートリスト)があり、初期値は空のリストです。
パターンパーサーには、関連付けられた保留中の固定値(文字列)があり、初期値は空文字列です。
パターンパーサーには、関連付けられたインデックス(数値)があり、初期値は0です。
パターンパーサーには、関連付けられた次の数値名(数値)があり、初期値は0です。
-
parserを新しいパターンパーサーとして生成し、そのエンコーディングコールバックをencoding callbackに設定し、セグメントワイルドカード正規表現をgenerate a segment wildcard regexpをoptionsで実行した結果に設定する。
-
parserのインデックスがparserのトークンリストのサイズより小さい間:
-
char tokenをtry to consume a tokenをparserと"
char
"で実行した結果とする。 -
name tokenをtry to consume a tokenをparserと"
name
"で実行した結果とする。 -
regexp or wildcard tokenをtry to consume a regexp or wildcard tokenをparserとname tokenで実行した結果とする。
-
もしname tokenがnullでない、またはregexp or wildcard tokenがnullでない場合:
マッチグループがある場合は、パートを直ちに追加する必要があります。
-
prefixを空文字列とする。
-
もしchar tokenがnullでなければ、prefixをchar tokenの値に設定する。
-
もしprefixが空文字列でなく、かつoptionsのプレフィックスコードポイントでない場合:
-
parserの保留中の固定値の末尾にprefixを追加する。
-
prefixを空文字列に設定する。
-
-
maybe add a part from the pending fixed valueをparserで実行する。
-
modifier tokenをtry to consume a modifier tokenをparserで実行した結果とする。
-
add a partをparser、prefix、name token、 regexp or wildcard token、空文字列、およびmodifier tokenで実行する。
-
続行。
-
-
fixed tokenをchar tokenとする。
マッチグループがない場合は、固定テキストをバッファリングする必要があります。できる限り多くのテキストを収集し、"
fixed-text
"パートとして追加します。 -
もしfixed tokenがnullなら、fixed tokenをtry to consume a tokenをparserと"
escaped-char
"で実行した結果に設定する。 -
もしfixed tokenがnullでなければ:
-
open tokenをtry to consume a tokenをparserと"
open
"で実行した結果とする。 -
もしopen tokenがnullでなければ:
-
prefixをconsume textをparserで実行した結果とする。
-
name tokenをtry to consume a tokenをparserと"
name
"で実行した結果とする。 -
regexp or wildcard tokenをtry to consume a regexp or wildcard tokenをparserとname tokenで実行した結果とする。
-
suffixをconsume textをparserで実行した結果とする。
-
consume a required tokenをparserと"
close
"で実行する。 -
modifier tokenをtry to consume a modifier tokenをparserで実行した結果とする。
-
add a partをparser、prefix、name token、 regexp or wildcard token、suffix、およびmodifier tokenで実行する。
-
続行。
-
-
maybe add a part from the pending fixed valueをparserで実行する。
-
consume a required tokenをparserと"
end
"で実行する。
-
-
parserのパートリストを返す。
フルワイルドカード正規表現値は文字列".*
"です。
-
resultを"
[^
"とする。 -
resultの末尾に、optionsのデリミターコードポイントをescape a regexp stringで実行した結果を追加する。
-
resultの末尾に"
]+?
"を追加する。 -
resultを返す。
-
tokenをトークンを消費しようとするをparserと"
other-modifier
"で実行した結果とする。 -
もしtokenがnullでなければ、tokenを返す。
-
tokenをトークンを消費しようとするをparserと"
asterisk
"で実行した結果に設定する。 -
tokenを返す。
-
tokenをトークンを消費しようとするをparserと"
regexp
"で実行した結果とする。 -
もしname tokenがnullかつtokenがnullなら、tokenをトークンを消費しようとするをparserと"
asterisk
"で実行した結果に設定する。 -
tokenを返す。
-
resultをトークンを消費しようとするをparserとtypeで実行した結果とする。
-
もしresultがnullなら、
TypeError
を投げる。 -
resultを返す。
-
resultを空文字列とする。
-
無限ループ:
-
tokenをトークンを消費しようとするをparserと"
char
"で実行した結果とする。 -
もしtokenがnullなら、tokenをトークンを消費しようとするをparserと"
escaped-char
"で実行した結果に設定する。 -
もしtokenがnullなら、break。
-
tokenの値をresultの末尾に追加する。
-
-
resultを返す。
-
modifierを"
none
"とする。 -
もしmodifier tokenがnullでなければ:
-
そうでなくmodifier tokenの値が"
*
"ならmodifierを"zero-or-more
"に設定する。 -
そうでなくmodifier tokenの値が"
+
"ならmodifierを"one-or-more
"に設定する。
-
もしname tokenがnullかつregexp or wildcard tokenがnullかつmodifierが"
none
"なら:これは"
{foo}
"グループ化です。これを保留中の固定値に追加し、他のテキストと結合します。-
parserの保留中の固定値の末尾にprefixを追加する。
-
返す。
-
-
保留中の固定値からパートを追加するかもしれないをparserで実行する。
-
もしname tokenがnullかつregexp or wildcard tokenがnullなら:
これは"
{foo}?
"グループ化です。修飾子があるので、他のテキストと結合できません。直ちにパートとして追加します。-
アサート:suffixは空文字列。
-
もしprefixが空文字列なら、返す。
-
encoded valueをparserのエンコーディングコールバックをprefixで実行した結果とする。
-
partを新しいパートとして、typeは"
fixed-text
"、valueはencoded value、modifierはmodifierに設定する。 -
返す。
-
-
regexp valueを空文字列とする。
次にregexp or wildcard tokenを正規表現に変換します。
-
もしregexp or wildcard tokenがnullなら、regexp valueをparserのセグメントワイルドカード正規表現に設定する。
-
そうでなくregexp or wildcard tokenのtypeが"
asterisk
"なら、regexp valueをフルワイルドカード正規表現値に設定する。 -
それ以外の場合は、regexp valueをregexp or wildcard tokenの値に設定する。
-
typeを"
regexp
"に設定する。次にregexp valueをパートtypeに変換します。まず正規表現にすることで、"
regexp
"トークンと"name
"や"asterisk
"トークンが同様に扱われます。 -
もしregexp valueがparserのセグメントワイルドカード正規表現なら:
-
typeを"
segment-wildcard
"に設定する。 -
regexp valueを空文字列に設定する。
-
-
そうでなくregexp valueがフルワイルドカード正規表現値なら:
-
typeを"
full-wildcard
"に設定する。 -
regexp valueを空文字列に設定する。
-
-
nameを空文字列とする。
-
もしname tokenがnullでなければ、nameをname tokenの値に設定する。
-
そうでなくregexp or wildcard tokenがnullでなければ:
-
もし重複した名前かどうかをparserとnameで実行した結果がtrueなら、
TypeError
を投げる。 -
encoded prefixをparserのエンコーディングコールバックをprefixで実行した結果とする。
最後に固定テキスト値をエンコードし、パートを作成します。
-
encoded suffixをparserのエンコーディングコールバックをsuffixで実行した結果とする。
-
partを新しいパートとして、typeはtype、valueはregexp value、modifierはmodifier、nameはname、prefixはencoded prefix、suffixはencoded suffixに設定する。
2.2. パートリストを正規表現に変換する
-
resultを"
^
"とする。 -
name listを新しいリストとする。
-
各partをpart listについて:
-
もしpartのtypeが"
fixed-text
"なら:-
もしpartのmodifierが"
none
"なら、escape a regexp stringをpartのvalueで実行した結果をresultの末尾に追加する。 -
そうでない場合:
修飾子のある"
fixed-text
"partは非捕捉グループを使用します。以下の形式になります。(?:<固定テキスト>)<修飾子>
-
resultの末尾に"
(?:
"を追加する。 -
escape a regexp stringをpartのvalueで実行した結果をresultの末尾に追加する。
-
resultの末尾に"
)
"を追加する。 -
convert a modifier to a stringをpartのmodifierで実行した結果をresultの末尾に追加する。
-
-
続行。
-
-
追加partのnameをname listの末尾に追加する。
一致グループ名のリストは、互換性のために並行リストで収集します。path-to-regexpと同じ振る舞いを維持するためです。正規表現の名前付きキャプチャグループに変換も可能ですが、アルゴリズムの複雑性からバグのリスクが高く、また生成した正規表現をウェブに公開する場合もpath-to-regexpとの互換性を維持したい意向があります。
-
regexp valueをpartのvalueとする。
-
もしpartのtypeが"
segment-wildcard
"なら、regexp valueをセグメントワイルドカード正規表現を生成するをoptionsで実行した結果に設定する。 -
そうでなくpartのtypeが"
full-wildcard
"なら、regexp valueをフルワイルドカード正規表現値に設定する。 -
もしpartのprefixが空文字列であり、かつpartのsuffixが空文字列なら:
プレフィックスやサフィックスがない場合、生成方法は修飾子によって異なります。修飾子がないかoptional修飾子のみの場合は以下の単純な形式を使用します:
(<regexp value>)<modifier>
繰り返し修飾子の場合はより複雑な形式になります:
((?:<regexp value>)<modifier>)
-
もしpartのmodifierが"
none
"または"optional
"なら:-
resultの末尾に"
(
"を追加する。 -
regexp valueをresultの末尾に追加する。
-
resultの末尾に"
)
"を追加する。 -
convert a modifier to a stringをpartのmodifierで実行した結果をresultの末尾に追加する。
-
-
そうでない場合:
-
resultの末尾に"
((?:
"を追加する。 -
regexp valueをresultの末尾に追加する。
-
resultの末尾に"
)
"を追加する。 -
convert a modifier to a stringをpartのmodifierで実行した結果をresultの末尾に追加する。
-
resultの末尾に"
)
"を追加する。
-
-
続行。
-
-
もしpartのmodifierが"
none
" または"optional
"なら:このセクションは、prefixやsuffixがある非繰り返しパートを扱います。内部キャプチャグループで主なregexp valueを含み、外部の非キャプチャグループはプレフィックスやサフィックスと組み合わせます。最終的に修飾子が適用されます。以下の形式となります。
(?:<prefix>(<regexp value>)<suffix>)<modifier>
-
resultの末尾に"
(?:
"を追加する。 -
escape a regexp stringをpartのprefixで実行した結果をresultの末尾に追加する。
-
resultの末尾に"
(
"を追加する。 -
regexp valueをresultの末尾に追加する。
-
resultの末尾に"
)
"を追加する。 -
escape a regexp stringをpartのsuffixで実行した結果をresultの末尾に追加する。
-
resultの末尾に"
)
"を追加する。 -
convert a modifier to a stringをpartのmodifierで実行した結果をresultの末尾に追加する。
-
続行。
-
-
アサート:partのmodifierが"
zero-or-more
"または"one-or-more
"である。 -
アサート:partのprefixが空文字列でない、またはpartのsuffixが空文字列でない。
プレフィックスやサフィックスのある繰り返しパートは非常に複雑です。最初のprefixと最後のsuffixは除外し、中間の繰り返し要素間には含みます。これを実現するため、prefixを除外した初期表現を提供し、その後prefix/suffixを含むoptionalな繰り返し要素を追加します。0回許可される場合は、最後にoptional修飾子を付加できます。最終的な形式は以下の通りです。
(?:<prefix>((?:<regexp value>)(?:<suffix><prefix>(?:<regexp value>))*)<suffix>)?
-
resultの末尾に"
(?:
"を追加する。 -
escape a regexp stringをpartのprefixで実行した結果をresultの末尾に追加する。
-
resultの末尾に"
((?:
"を追加する。 -
regexp valueをresultの末尾に追加する。
-
resultの末尾に"
)(?:
"を追加する。 -
escape a regexp stringをpartのsuffixで実行した結果をresultの末尾に追加する。
-
escape a regexp stringをpartのprefixで実行した結果をresultの末尾に追加する。
-
resultの末尾に"
(?:
"を追加する。 -
regexp valueをresultの末尾に追加する。
-
resultの末尾に"
))*)
"を追加する。 -
escape a regexp stringをpartのsuffixで実行した結果をresultの末尾に追加する。
-
resultの末尾に"
)
"を追加する。 -
もしpartのmodifierが"
zero-or-more
"なら、resultの末尾に"?
"を追加する。
-
-
resultの末尾に"
$
"を追加する。 -
(result, name list)を返す。
-
resultを空文字列とする。
-
indexを0とする。
-
indexがinputの長さより小さい間:
-
cをinput[index]とする。
-
indexを1増やす。
-
もしcが以下のいずれかであれば:
- U+002E (
.
); - U+002B (
+
); - U+002A (
*
); - U+003F (
?
); - U+005E (
^
); - U+0024 (
$
); - U+007B (
{
); - U+007D (
}
); - U+0028 (
(
); - U+0029 (
)
); - U+005B (
[
); - U+005D (
]
); - U+007C (
|
); - U+002F (
/
); または - U+005C (
\
),
なら、resultの末尾に"
\
"を追加する。 - U+002E (
-
cをresultの末尾に追加する。
-
-
resultを返す。
2.3. パートリストをパターン文字列に変換する
-
resultを空文字列とする。
-
index listをインデックス取得でpart listに対して得る。
-
各indexをindex listについて:
-
partをpart list[index]とする。
-
previous partをindexが0より大きければpart list[index - 1]、そうでなければnullとする。
-
next partをindexがindex listのサイズ - 1より小さければpart list[index + 1]、そうでなければnullとする。
-
もしpartのtypeが"
fixed-text
"なら:-
-
escape a pattern stringをpartのvalueで実行した結果をresultの末尾に追加する。
-
続行。
-
-
resultの末尾に"
{
"を追加する。 -
escape a pattern stringをpartのvalueで実行した結果をresultの末尾に追加する。
-
resultの末尾に"
}
"を追加する。 -
convert a modifier to a stringをpartのmodifierで実行した結果をresultの末尾に追加する。
-
続行。
-
-
needs groupingを以下のいずれかがtrueならtrue、そうでなければfalseとする:
- partのsuffixが空文字列でない。
- partのprefixが空文字列でなく、かつoptionsのprefix code pointでない。
-
以下がすべてtrueの場合:
- needs groupingがfalse
- custom nameがtrue
- partのtypeが"
segment-wildcard
" - partのmodifierが"
none
" - next partがnullでない
- next partのprefixが空文字列
- next partのsuffixが空文字列
-
もしnext partのtypeが"
fixed-text
"なら:-
is a valid name code pointをnext partのvalueの最初のコードポイントとfalseで実行した結果がtrueなら、needs groupingをtrueに設定する。
-
-
そうでない場合:
-
以下がすべてtrueの場合:
- needs groupingがfalse
- partのprefixが空文字列
- previous partがnullでない
- previous partのtypeが"
fixed-text
" - previous partのvalueの最後のコードポイントがoptionsのprefix code point
-
もしneeds groupingがtrueなら、resultの末尾に"
{
"を追加する。 -
escape a pattern stringをpartのprefixで実行した結果をresultの末尾に追加する。
-
もしcustom nameがtrueなら:
-
resultの末尾に"
:
"を追加する。 -
partのnameをresultの末尾に追加する。
-
-
-
resultの末尾に"
(
"を追加する。 -
partのvalueをresultの末尾に追加する。
-
resultの末尾に"
)
"を追加する。
-
-
そうでなくpartのtypeが"
segment-wildcard
"かつcustom nameがfalseなら:-
resultの末尾に"
(
"を追加する。 -
セグメントワイルドカード正規表現を生成するをoptionsで実行した結果をresultの末尾に追加する。
-
resultの末尾に"
)
"を追加する。
-
-
そうでなくpartのtypeが"
full-wildcard
"なら:-
もしcustom nameがfalseで、以下のいずれかがtrueの場合:
- previous partがnull
- previous partのtypeが"
fixed-text
" - previous partのmodifierが"
none
"でない - needs groupingがtrue
- partのprefixが空文字列でない
*
"を追加する。 -
そうでない場合:
-
resultの末尾に"
(
"を追加する。 -
フルワイルドカード正規表現値をresultの末尾に追加する。
-
resultの末尾に"
)
"を追加する。
-
-
-
以下がすべてtrueの場合:
- partのtypeが"
segment-wildcard
" - custom nameがtrue
- partのsuffixが空文字列でない
- is a valid name code pointをpartのsuffixの最初のコードポイントとfalseで実行した結果がtrue
\
)をresultの末尾に追加する。 - partのtypeが"
-
escape a pattern stringをpartのsuffixで実行した結果をresultの末尾に追加する。
-
もしneeds groupingがtrueなら、resultの末尾に"
}
"を追加する。 -
convert a modifier to a string をpartのmodifierで実行した結果をresultの末尾に追加する。
-
-
resultを返す。
-
もしmodifierが"
zero-or-more
"なら、"*
"を返す。 -
もしmodifierが"
optional
"なら、"?
"を返す。 -
もしmodifierが"
one-or-more
"なら、"+
"を返す。 -
空文字列を返す。
3. 正規化
3.1. エンコーディングコールバック
-
もしvalueが空文字列なら、valueを返す。
-
parseResultを基本URLパーサーをvalue+"
://dummy.invalid/
"で実行した結果とする。ここではstate overrideは使用しません。これは
protocol
のsetterにのみ適用される制約を強制するためです。パーサーには通常のエントリポイントを使い、ダミーURLでプロトコルを解析します。 -
もしparseResultが失敗なら、
TypeError
を投げる。 -
parseResultのschemeを返す。
-
もしvalueが空文字列なら、valueを返す。
-
dummyURLをダミーURL生成で得る。
-
ユーザー名を設定するをdummyURLとvalueで実行する。
-
dummyURLのusernameを返す。
-
もしvalueが空文字列なら、valueを返す。
-
dummyURLをダミーURL生成で得る。
-
パスワードを設定するをdummyURLとvalueで実行する。
-
dummyURLのpasswordを返す。
-
もしvalueが空文字列なら、valueを返す。
-
dummyURLをダミーURL生成で得る。
-
parseResultを基本URLパーサーをvalue、dummyURLをurl、hostname stateをstate overrideで実行した結果とする。
-
もしparseResultが失敗なら、
TypeError
を投げる。
-
もしportValueが空文字列なら、portValueを返す。
-
dummyURLをダミーURL生成で得る。
-
もしprotocolValueが与えられていれば、dummyURLのschemeをprotocolValueに設定する。
これはURLレコードのschemeを設定することで、基本URLパーサーがデフォルトポートを認識・正規化できるようにします。
-
parseResultを基本URLパーサーをportValue、dummyURLをurl、port stateをstate overrideで実行した結果とする。
-
もしparseResultが失敗なら、
TypeError
を投げる。
-
もしvalueが空文字列なら、valueを返す。
-
最初のコードポイントがU+002F (
/
)ならleading slashをtrue、そうでなければfalseとする。 -
leading slashがfalseならmodified valueを"
/-
"、そうでなければ空文字列とする。URLパーサーは正規化されたパス名に自動で先頭スラッシュを付与しますが、このアルゴリズムはパス名の部分ごとに呼ばれるため、全体でスラッシュ付与が正しく機能しません。ここでは自前でスラッシュ+文字を挿入し、URLパーサーによるドットの誤解釈を防ぎます。下記でこの挿入文字を削除します。
実装によっては、URLパーサー自体でスラッシュ付与を無効化しても構いません。
-
modified valueの末尾にvalueを追加する。
-
dummyURLをダミーURL生成で得る。
-
基本URLパーサーをmodified value、dummyURLをurl、path start stateをstate overrideで実行する。
-
resultをURL path シリアライズでdummyURLを実行した結果とする。
-
leading slashがfalseなら、resultを2文字目以降の部分文字列にする。
-
resultを返す。
-
もしvalueが空文字列なら、valueを返す。
-
dummyURLをダミーURL生成で得る。
-
dummyURLのpathを空文字列に設定する。
-
parseResultをURLパースをvalue、dummyURLをurl、opaque path stateをstate overrideで実行した結果とする。
-
もしparseResultが失敗なら、
TypeError
を投げる。 -
URL path シリアライズでdummyURLを実行した結果を返す。
-
もしvalueが空文字列なら、valueを返す。
-
dummyURLをダミーURL生成で得る。
-
dummyURLのqueryを空文字列に設定する。
-
基本URLパーサーをvalue、dummyURLをurl、query stateをstate overrideで実行する。
-
dummyURLのqueryを返す。
-
もしvalueが空文字列なら、valueを返す。
-
dummyURLをダミーURL生成で得る。
-
dummyURLのfragmentを空文字列に設定する。
-
基本URLパーサーをvalue、dummyURLをurl、fragment stateをstate overrideで実行する。
-
dummyURLのfragmentを返す。
3.2.
URLPatternInit
の処理
URLPatternInit
init、文字列type、文字列またはnullprotocol、文字列またはnullusername、文字列またはnullpassword、文字列またはnullhostname、文字列またはnullport、文字列またはnullpathname、文字列またはnullsearch、そして文字列またはnullhashを与える:
-
resultを新しい
URLPatternInit
として生成する。 -
baseURLをnullとする。
-
base URLは追加の文脈として利用できますが、各コンポーネントについて、initにbase URLのコンポーネントより特定的なものが含まれている場合は継承されません。
コンポーネントがより特定的であるとは、以下の2つのリストの後ろに現れるほど特定的です(URL構文の順序に近い):
-
protocol, hostname, port, pathname, search, hash
-
protocol, hostname, port, username, password
ユーザー名とパスワードはURLPattern構築時にはbase URLから継承されません(test()やexec()の引数URLの場合は継承されます)。
-
もしbaseURLが失敗なら、
TypeError
を投げる。 -
もしinit["
protocol
"] が存在しなければ、result["protocol
"] をbase URL文字列の処理でbaseURLのschemeとtypeにより設定する。 -
もしtypeが"
pattern
"でなく、initがいずれも含まない場合(protocol、hostname、port、username)、result["username
"] をbase URL文字列の処理でbaseURLのusernameとtypeにより設定する。 -
もしtypeが"
pattern
"でなく、initがいずれも含まない場合(protocol、hostname、port、username、password)、result["password
"] をbase URL文字列の処理でbaseURLのpasswordとtypeにより設定する。 -
もしinitがprotocolとhostnameを含まない場合:
-
baseHostを空文字列とする。
-
result["
hostname
"] をbase URL文字列の処理でbaseHostとtypeにより設定する。
-
-
もしinitがprotocol、hostname、portを含まない場合:
-
もしinitがprotocol、hostname、port、pathnameを含まない場合、result["
pathname
"] をbase URL文字列の処理でURL pathシリアライズしたbaseURLとtypeで設定する。 -
もしinitがprotocol、hostname、port、pathname、searchを含まない場合:
-
baseQueryをbaseURLのqueryに設定する。
-
もしbaseQueryがnullなら、空文字列にする。
-
result["
search
"] をbase URL文字列の処理でbaseQueryとtypeで設定する。
-
-
もしinitがprotocol、hostname、port、pathname、search、hashを含まない場合:
-
baseFragmentをbaseURLのfragmentに設定する。
-
もしbaseFragmentがnullなら、空文字列にする。
-
result["
hash
"] をbase URL文字列の処理でbaseFragmentとtypeで設定する。
-
-
-
もしinit["
protocol
"] が存在するなら、result["protocol
"] をprocess protocol for initでinit["protocol
"]とtypeにより設定する。 -
もしinit["
username
"] が存在するなら、result["username
"] をprocess username for initでinit["username
"]とtypeにより設定する。 -
もしinit["
password
"] が存在するなら、result["password
"] をprocess password for initでinit["password
"]とtypeにより設定する。 -
もしinit["
hostname
"] が存在するなら、result["hostname
"] をprocess hostname for initでinit["hostname
"]とtypeにより設定する。 -
resultProtocolStringをresult["
protocol
"]が存在すればそれに、なければ空文字列とする。 -
もしinit["
port
"] が存在するなら、result["port
"] をprocess port for initでinit["port
"]、resultProtocolString、typeにより設定する。 -
-
以下がすべてtrueの場合:
- baseURLがnullでない
- baseURLに不透明パスがない
- is an absolute
pathnameをresult["
pathname
"]とtypeで実行した結果がfalse
の場合:
-
baseURLPathをbase URL文字列の処理でURL pathシリアライズしたbaseURLとtypeの結果に設定する。
-
slash indexをbaseURLPath内の最後のU+002F (
/
)コードポイントのインデックス(なければnull)とする。 -
もしslash indexがnullでなければ:
-
result["
pathname
"] をprocess pathname for initでresult["pathname
"]、resultProtocolString、typeにより設定する。
-
もしinit["
search
"] が存在するなら、result["search
"] をprocess search for initでinit["search
"]とtypeにより設定する。 -
もしinit["
hash
"] が存在するなら、result["hash
"] をprocess hash for initでinit["hash
"]とtypeにより設定する。 -
resultを返す。
-
アサート:inputはnullでない。
-
もしtypeが"
pattern
"でなければinputを返す。 -
パターン文字列をエスケープするをinputで実行した結果を返す。
-
もしinputが空文字列ならfalseを返す。
-
もしinput[0]がU+002F (
/
)ならtrueを返す。 -
もしtypeが"
url
"ならfalseを返す。 -
もしinputのコードポイント長が2未満ならfalseを返す。
-
もしinput[0]がU+005C (
\
)でinput[1]がU+002F (/
)ならtrueを返す。 -
もしinput[0]がU+007B (
{
)でinput[1]がU+002F (/
)ならtrueを返す。 -
falseを返す。
-
strippedValueを与えられたvalueから末尾のU+003A (
:
)を1つ削除したものとする。 -
もしtypeが"
pattern
"ならstrippedValueを返す。 -
プロトコルを正規化するをstrippedValueで実行した結果を返す。
-
もしtypeが"
pattern
"ならvalueを返す。 -
ユーザー名を正規化するをvalueで実行した結果を返す。
-
もしtypeが"
pattern
"ならvalueを返す。 -
パスワードを正規化するをvalueで実行した結果を返す。
-
もしtypeが"
pattern
"ならvalueを返す。 -
ホスト名を正規化するをvalueで実行した結果を返す。
-
もしtypeが"
pattern
"ならportValueを返す。 -
ポートを正規化するをportValueとprotocolValueで実行した結果を返す。
-
もしtypeが"
pattern
"ならpathnameValueを返す。 -
もしprotocolValueが特別なスキームまたは空文字列なら、パス名を正規化するをpathnameValueで実行した結果を返す。
protocolValueが空文字列の場合は、constructor dictionaryでprotocolが指定されていないことを示します。通常は空文字列の特別扱いはしませんが、この場合は最も一般的なパス名正規化に合わせ特別なスキームとして扱います。
-
不透明パス名を正規化するをpathnameValueで実行した結果を返す。
-
strippedValueを与えられたvalueから先頭のU+003F (
?
)を1つ削除したものとする。 -
もしtypeが"
pattern
"ならstrippedValueを返す。 -
検索部分を正規化するをstrippedValueで実行した結果を返す。
-
strippedValueを与えられたvalueから先頭のU+0023 (
#
)を1つ削除したものとする。 -
もしtypeが"
pattern
"ならstrippedValueを返す。 -
ハッシュを正規化するをstrippedValueで実行した結果を返す。
4. 他の仕様におけるURLパターンの利用
ウェブプラットフォームにおける一貫性を促進するため、他の文書が本仕様と統合される場合は、特別な理由がない限り下記のガイドラインに従うべきです。
-
省略記法を許容する。ほとんどの著者パターンは単純かつ直接的です。したがって、APIはこれら一般的なケースについて省略記法を受け入れ、著者が完全な
URLPattern
オブジェクトへ変換するための追加作業を不要にすべきです。 -
ベースURLを尊重する。URLは通常、その環境のベースURL(多くの場合、ドキュメントのベースURL)に相対して解析されますが、URLパターンも同様にこれを尊重すべきです。
URLPattern
のコンストラクタは例外であり、直接コンセプトを公開します。これはURLコンストラクタがベースURLを尊重しないのと同様です。 -
正規表現グループについて明確にする。一部のAPIでは、正規表現グループを含まないURLパターンのみを許容する方が有益です。たとえば、ユーザーエージェントが著者スクリプトを実行するスレッドやプロセスと異なる場所で実装することが予想される場合や、セキュリティ・パフォーマンスの観点からJavaScriptエンジンが通常は動作しない場合などです。この場合は、(has regexp groupsへの参照付きで)明示的に文書化し、なるべく早い段階(例:JavaScript例外を投げるなど)でエラーを報告すべきです。可能ならば、将来的な制約解除のためにフィーチャ検出可能にしてください。URLパターンの異なるサブセットを作成する際は、本仕様のエディターに相談してください。
-
どのURLがマッチするかを明確にする。例えば、フェッチ処理中のアルゴリズムはフラグメントのないURLを扱う場合が多いです。その場合、仕様はその旨を明示すべきで、マッチしないパターン(例:非空フラグメントを要求するなど)が使われた際に開発者警告を表示することを推奨する場合があります。
4.1. JavaScript APIとの統合
typedef (USVString or URLPatternInit or URLPattern );
URLPatternCompatible
JavaScript APIは以下すべてを受け入れるべきです:
-
URLPattern
オブジェクト -
パターン構築に必要なコンポーネントを指定する辞書型オブジェクト
-
文字列(コンストラクタ文字列構文)
これを達成するため、仕様はURLPatternCompatibleをoperationやdictionary memberの引数として受け付け、下記のアルゴリズムに従い、適切な環境設定オブジェクトのAPIベースURL等を利用してください。
URLPattern
オブジェクトをWeb IDL値から構築するためには、URLPatternCompatible
input、URLbaseURL、realmrealmを与え、次の手順を実行する:
-
もしinputの特定型が
URLPattern
なら:-
inputを返す。
-
-
それ以外の場合:
-
patternをrealmで新しい
URLPattern
とする。 -
patternの関連URLパターンを、Web IDL値からURLパターンを構築するでinputとbaseURLを渡した結果に設定する。
-
patternを返す。
-
このようにして、著者はほとんどのパターンを簡潔に指定でき、必要であればコンストラクタを使って非一般的なオプションにもアクセスできます。ベースURLの暗黙的利用はHTMLのURLの解析アルゴリズムと類似しており、現行標準の一貫性があります。[HTML]
4.2. JSONデータ形式との統合
URLパターンを含むJSONデータ形式では、JavaScript APIの振る舞いに倣い、以下の両方を受け入れるべきです:
-
パターン構築に必要なコンポーネントを指定するオブジェクト
-
文字列(コンストラクタ文字列構文)
仕様がInfra値(例:JSON文字列をInfra値へ解析後)を持つ場合は、適切なベースURL(通常はJSONリソースのURL)を使い、以下のアルゴリズムを使用してください。[INFRA]
-
serializedBaseURLをbaseURLの直列化とする。
-
もしrawPatternが文字列なら:
-
それ以外でrawPatternがmapなら:
-
initを «[ "
baseURL
" → serializedBaseURL ]»(URLPatternInit
型の辞書)とする。 -
各key→valueをrawPatternについて:
-
もしkeyが
URLPatternInit
の識別子でも継承辞書の識別子でもなく、かつvalueが文字列でなく、またそのメンバー型がUSVString
でなければ、nullを返す。今後URLPatternInit
に他型のメンバーが追加された場合は更新が必要です。将来、より緩いモードも有用なら導入される可能性があります。 -
init[key]をvalueに設定する。
-
-
URLパターン構築でinit、null、空のmapの結果を返す。
将来的には非空のオプションを追加する必要が出るかもしれません。
-
-
それ以外の場合はnullを返す。
仕様は、URLPatternOptions
のオプション受け入れやベースURLの上書きなどを許容できる余地を残しておくべきです。JSON
APIの場合はURLPattern
オブジェクトを直接構築できないためです。例えばSpeculation
Rulesでは、"relative_to
"キーによりJSONリソースのURLの代わりにドキュメントのベースURLを利用できます。[SPECULATION-RULES]
4.3. HTTPヘッダーフィールドとの統合
URLパターンを含むHTTPヘッダーは、コンストラクタ文字列構文による文字列を受け入れるべきです(構造化フィールドの一部として)。[RFC9651]
HTTPヘッダー仕様では、URLパターン(例:matchアルゴリズム)を使うべきであり、JavaScriptrealmを暗示するURLPattern
オブジェクトは使うべきではありません。
謝辞
編集者は次の方々に感謝します: Alex Russell、 Anne van Kesteren、 Asa Kusuma、 Blake Embrey、 Cyrus Kasaaian、 Daniel Murphy、 Darwin Huang、 Devlin Cronin、 Domenic Denicola、 Dominick Ng、 Jake Archibald、 Jeffrey Posnick、 Jeremy Roman、 Jimmy Shen、 Joe Gregorio、 Joshua Bell、 石橋健一(Kenichi Ishibashi)、 Kenji Baheux、 Kenneth Rohde Christiansen、 Kingsley Ngan、 Kinuko Yasuda、 L. David Baron、 Luca Casonato、 Łukasz Anforowicz、 島津誠(Makoto Shimazu)、 Marijn Kruisselbrink、 Matt Falkenhagen、 Matt Giuca、 Michael Landry、 R. Samuel Klatchko、 Rajesh Jagannathan、 Ralph Chelala、 Sangwhan Moon、 Sayan Pal、 Victor Costan、 柳沢義智(Yoshisato Yanagisawa)、および Youenn Fablet ―本仕様への貢献に対して。
特に、Blake Embrey 氏および他の pillarjs/path-to-regexp コントリビューターに感謝します。多くの人々に役立つ素晴らしいオープンソースライブラリを構築してくださいました。
また、Kenneth Rohde Christiansen 氏の polyfill の作業にも特別な感謝を表します。彼は変化する URLPattern
API に適応するため、多大な労力を費やしました。
本標準は、 Ben Kelly (Google, wanderview@chromium.org)、 Jeremy Roman (Google, jbroman@chromium.org)、および 宍戸俊哉(Shunya Shishido, Google, sisidovski@chromium.org) によって執筆されています。
知的財産権
Copyright © WHATWG (Apple, Google, Mozilla, Microsoft)。この著作物は クリエイティブ・コモンズ 表示 4.0 国際ライセンスのもとでライセンスされています。その一部がソースコードに組み込まれる場合、ソースコード部分はBSD 3-Clause ライセンスのもとでライセンスされます。
これは現行標準です。 特許審査版に関心のある方は現行標準レビュー草案をご覧ください。