From 621d041792912dfa18e52b7765934ca38fde7f22 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Wed, 18 Oct 2023 11:53:52 +0900 Subject: [PATCH 01/11] Apply spec-factory changes --- .editorconfig | 7 + .github/ISSUE_TEMPLATE/0-new-issue.yml | 17 ++ .github/ISSUE_TEMPLATE/1-new-feature.yml | 27 ++ .github/ISSUE_TEMPLATE/config.yml | 8 + .github/workflows/build.yml | 21 +- .gitignore | 4 +- .pr-preview.json | 7 +- LICENSE | 356 +++++++++++++++++++++++ LICENSE.md | 3 - Makefile | 42 ++- PULL_REQUEST_TEMPLATE.md | 21 ++ README.md | 33 +++ readme.md | 10 - spec.bs | 10 +- 14 files changed, 513 insertions(+), 53 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/0-new-issue.yml create mode 100644 .github/ISSUE_TEMPLATE/1-new-feature.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 LICENSE delete mode 100644 LICENSE.md create mode 100644 PULL_REQUEST_TEMPLATE.md create mode 100644 README.md delete mode 100644 readme.md diff --git a/.editorconfig b/.editorconfig index 8738948..dfb139b 100644 --- a/.editorconfig +++ b/.editorconfig @@ -7,6 +7,13 @@ charset = utf-8 indent_size = 2 indent_style = space trim_trailing_whitespace = true +max_line_length = 100 [Makefile] indent_style = tab + +[*.bs] +indent_size = 2 + +[*.py] +indent_size = 4 diff --git a/.github/ISSUE_TEMPLATE/0-new-issue.yml b/.github/ISSUE_TEMPLATE/0-new-issue.yml new file mode 100644 index 0000000..9ce01b2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/0-new-issue.yml @@ -0,0 +1,17 @@ +name: New issue +description: File a new issue against the URL Pattern Standard. +body: + - type: markdown + attributes: + value: | + Before filling out this form, please familiarize yourself with the [Code of Conduct](https://whatwg.org/code-of-conduct). You might also find the [FAQ](https://whatwg.org/faq) and [Working Mode](https://whatwg.org/working-mode) useful. + + If at any point you have questions, please reach out to us on [Chat](https://whatwg.org/chat). + - type: textarea + attributes: + label: "What is the issue with the URL Pattern Standard?" + validations: + required: true + - type: markdown + attributes: + value: "Thank you for taking the time to improve the URL Pattern Standard!" diff --git a/.github/ISSUE_TEMPLATE/1-new-feature.yml b/.github/ISSUE_TEMPLATE/1-new-feature.yml new file mode 100644 index 0000000..5380680 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/1-new-feature.yml @@ -0,0 +1,27 @@ +name: New feature +description: Request a new feature in the URL Pattern Standard. +labels: ["addition/proposal", "needs implementer interest"] +body: + - type: markdown + attributes: + value: | + Before filling out this form, please familiarize yourself with the [Code of Conduct](https://whatwg.org/code-of-conduct), [FAQ](https://whatwg.org/faq), and [Working Mode](https://whatwg.org/working-mode). They help with setting expectations and making sure you know what is required. The FAQ ["How should I go about proposing new features to WHATWG standards?"](https://whatwg.org/faq#adding-new-features) is especially relevant. + + If at any point you have questions, please reach out to us on [Chat](https://whatwg.org/chat). + - type: textarea + attributes: + label: "What problem are you trying to solve?" + validations: + required: true + - type: textarea + attributes: + label: "What solutions exist today?" + - type: textarea + attributes: + label: "How would you solve it?" + - type: textarea + attributes: + label: "Anything else?" + - type: markdown + attributes: + value: "Thank you for taking the time to improve the URL Pattern Standard!" diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..70e8d0d --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: Chat + url: https://whatwg.org/chat + about: Please do reach out with questions and feedback! + - name: Stack Overflow + url: https://stackoverflow.com/ + about: If you're having trouble building a web page, this is not the right repository. Consider asking your question on Stack Overflow instead. diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 9a665df..af3476e 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -9,14 +9,17 @@ on: jobs: build: name: Build - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - - uses: actions/checkout@v2 - - name: Build - run: make ci - - name: Deploy - if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }} - uses: peaceiris/actions-gh-pages@v3 + - uses: actions/checkout@v3 with: - github_token: ${{ secrets.GITHUB_TOKEN }} - publish_dir: ./out + fetch-depth: 2 + - uses: actions/setup-python@v4 + with: + python-version: "3.11" + # Note: `make deploy` will do a deploy dry run on PRs. + - run: make deploy + env: + SERVER: ${{ secrets.MARQUEE_SERVER }} + SERVER_PUBLIC_KEY: ${{ secrets.MARQUEE_PUBLIC_KEY }} + SERVER_DEPLOY_KEY: ${{ secrets.MARQUEE_DEPLOY_KEY }} diff --git a/.gitignore b/.gitignore index dd6648e..3e7476c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ -/out/ +/urlpattern.spec.whatwg.org/ +/deploy.sh /spec.html -*.swp diff --git a/.pr-preview.json b/.pr-preview.json index 54feea3..45f78ce 100644 --- a/.pr-preview.json +++ b/.pr-preview.json @@ -1,4 +1,9 @@ { "src_file": "spec.bs", - "type": "bikeshed" + "type": "bikeshed", + "params": { + "force": 1, + "md-status": "LS-PR", + "md-Text-Macro": "PR-NUMBER {{ pull_request.number }}" + } } diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..f2dcda4 --- /dev/null +++ b/LICENSE @@ -0,0 +1,356 @@ +Copyright © WHATWG (Apple, Google, Mozilla, Microsoft). + +This work is licensed under a Creative Commons Attribution 4.0 International +License. To the extent portions of it are incorporated into source code, +such portions in the source code are licensed under the BSD 3-Clause License instead. + +- - - - + +Creative Commons Attribution 4.0 International Public License + +By exercising the Licensed Rights (defined below), You accept and agree +to be bound by the terms and conditions of this Creative Commons +Attribution 4.0 International Public License ("Public License"). To the +extent this Public License may be interpreted as a contract, You are +granted the Licensed Rights in consideration of Your acceptance of +these terms and conditions, and the Licensor grants You such rights in +consideration of benefits the Licensor receives from making the +Licensed Material available under these terms and conditions. + + +Section 1 -- Definitions. + + a. Adapted Material means material subject to Copyright and Similar + Rights that is derived from or based upon the Licensed Material + and in which the Licensed Material is translated, altered, + arranged, transformed, or otherwise modified in a manner requiring + permission under the Copyright and Similar Rights held by the + Licensor. For purposes of this Public License, where the Licensed + Material is a musical work, performance, or sound recording, + Adapted Material is always produced where the Licensed Material is + synched in timed relation with a moving image. + + b. Adapter's License means the license You apply to Your Copyright + and Similar Rights in Your contributions to Adapted Material in + accordance with the terms and conditions of this Public License. + + c. Copyright and Similar Rights means copyright and/or similar rights + closely related to copyright including, without limitation, + performance, broadcast, sound recording, and Sui Generis Database + Rights, without regard to how the rights are labeled or + categorized. For purposes of this Public License, the rights + specified in Section 2(b)(1)-(2) are not Copyright and Similar + Rights. + + d. Effective Technological Measures means those measures that, in the + absence of proper authority, may not be circumvented under laws + fulfilling obligations under Article 11 of the WIPO Copyright + Treaty adopted on December 20, 1996, and/or similar international + agreements. + + e. Exceptions and Limitations means fair use, fair dealing, and/or + any other exception or limitation to Copyright and Similar Rights + that applies to Your use of the Licensed Material. + + f. Licensed Material means the artistic or literary work, database, + or other material to which the Licensor applied this Public + License. + + g. Licensed Rights means the rights granted to You subject to the + terms and conditions of this Public License, which are limited to + all Copyright and Similar Rights that apply to Your use of the + Licensed Material and that the Licensor has authority to license. + + h. Licensor means the individual(s) or entity(ies) granting rights + under this Public License. + + i. Share means to provide material to the public by any means or + process that requires permission under the Licensed Rights, such + as reproduction, public display, public performance, distribution, + dissemination, communication, or importation, and to make material + available to the public including in ways that members of the + public may access the material from a place and at a time + individually chosen by them. + + j. Sui Generis Database Rights means rights other than copyright + resulting from Directive 96/9/EC of the European Parliament and of + the Council of 11 March 1996 on the legal protection of databases, + as amended and/or succeeded, as well as other essentially + equivalent rights anywhere in the world. + + k. You means the individual or entity exercising the Licensed Rights + under this Public License. Your has a corresponding meaning. + + +Section 2 -- Scope. + + a. License grant. + + 1. Subject to the terms and conditions of this Public License, + the Licensor hereby grants You a worldwide, royalty-free, + non-sublicensable, non-exclusive, irrevocable license to + exercise the Licensed Rights in the Licensed Material to: + + a. reproduce and Share the Licensed Material, in whole or + in part; and + + b. produce, reproduce, and Share Adapted Material. + + 2. Exceptions and Limitations. For the avoidance of doubt, where + Exceptions and Limitations apply to Your use, this Public + License does not apply, and You do not need to comply with + its terms and conditions. + + 3. Term. The term of this Public License is specified in Section + 6(a). + + 4. Media and formats; technical modifications allowed. The + Licensor authorizes You to exercise the Licensed Rights in + all media and formats whether now known or hereafter created, + and to make technical modifications necessary to do so. The + Licensor waives and/or agrees not to assert any right or + authority to forbid You from making technical modifications + necessary to exercise the Licensed Rights, including + technical modifications necessary to circumvent Effective + Technological Measures. For purposes of this Public License, + simply making modifications authorized by this Section 2(a) + (4) never produces Adapted Material. + + 5. Downstream recipients. + + a. Offer from the Licensor -- Licensed Material. Every + recipient of the Licensed Material automatically + receives an offer from the Licensor to exercise the + Licensed Rights under the terms and conditions of this + Public License. + + b. No downstream restrictions. You may not offer or impose + any additional or different terms or conditions on, or + apply any Effective Technological Measures to, the + Licensed Material if doing so restricts exercise of the + Licensed Rights by any recipient of the Licensed + Material. + + 6. No endorsement. Nothing in this Public License constitutes or + may be construed as permission to assert or imply that You + are, or that Your use of the Licensed Material is, connected + with, or sponsored, endorsed, or granted official status by, + the Licensor or others designated to receive attribution as + provided in Section 3(a)(1)(A)(i). + + b. Other rights. + + 1. Moral rights, such as the right of integrity, are not + licensed under this Public License, nor are publicity, + privacy, and/or other similar personality rights; however, to + the extent possible, the Licensor waives and/or agrees not to + assert any such rights held by the Licensor to the limited + extent necessary to allow You to exercise the Licensed + Rights, but not otherwise. + + 2. Patent and trademark rights are not licensed under this + Public License. + + 3. To the extent possible, the Licensor waives any right to + collect royalties from You for the exercise of the Licensed + Rights, whether directly or through a collecting society + under any voluntary or waivable statutory or compulsory + licensing scheme. In all other cases the Licensor expressly + reserves any right to collect such royalties. + + +Section 3 -- License Conditions. + +Your exercise of the Licensed Rights is expressly made subject to the +following conditions. + + a. Attribution. + + 1. If You Share the Licensed Material (including in modified + form), You must: + + a. retain the following if it is supplied by the Licensor + with the Licensed Material: + + i. identification of the creator(s) of the Licensed + Material and any others designated to receive + attribution, in any reasonable manner requested by + the Licensor (including by pseudonym if + designated); + + ii. a copyright notice; + + iii. a notice that refers to this Public License; + + iv. a notice that refers to the disclaimer of + warranties; + + v. a URI or hyperlink to the Licensed Material to the + extent reasonably practicable; + + b. indicate if You modified the Licensed Material and + retain an indication of any previous modifications; and + + c. indicate the Licensed Material is licensed under this + Public License, and include the text of, or the URI or + hyperlink to, this Public License. + + 2. You may satisfy the conditions in Section 3(a)(1) in any + reasonable manner based on the medium, means, and context in + which You Share the Licensed Material. For example, it may be + reasonable to satisfy the conditions by providing a URI or + hyperlink to a resource that includes the required + information. + + 3. If requested by the Licensor, You must remove any of the + information required by Section 3(a)(1)(A) to the extent + reasonably practicable. + + 4. If You Share Adapted Material You produce, the Adapter's + License You apply must not prevent recipients of the Adapted + Material from complying with this Public License. + + +Section 4 -- Sui Generis Database Rights. + +Where the Licensed Rights include Sui Generis Database Rights that +apply to Your use of the Licensed Material: + + a. for the avoidance of doubt, Section 2(a)(1) grants You the right + to extract, reuse, reproduce, and Share all or a substantial + portion of the contents of the database; + + b. if You include all or a substantial portion of the database + contents in a database in which You have Sui Generis Database + Rights, then the database in which You have Sui Generis Database + Rights (but not its individual contents) is Adapted Material; and + + c. You must comply with the conditions in Section 3(a) if You Share + all or a substantial portion of the contents of the database. + +For the avoidance of doubt, this Section 4 supplements and does not +replace Your obligations under this Public License where the Licensed +Rights include other Copyright and Similar Rights. + + +Section 5 -- Disclaimer of Warranties and Limitation of Liability. + + a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE + EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS + AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF + ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, + IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, + WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR + PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, + ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT + KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT + ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. + + b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE + TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, + NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, + INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, + COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR + USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN + ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR + DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR + IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. + + c. The disclaimer of warranties and limitation of liability provided + above shall be interpreted in a manner that, to the extent + possible, most closely approximates an absolute disclaimer and + waiver of all liability. + + +Section 6 -- Term and Termination. + + a. This Public License applies for the term of the Copyright and + Similar Rights licensed here. However, if You fail to comply with + this Public License, then Your rights under this Public License + terminate automatically. + + b. Where Your right to use the Licensed Material has terminated under + Section 6(a), it reinstates: + + 1. automatically as of the date the violation is cured, provided + it is cured within 30 days of Your discovery of the + violation; or + + 2. upon express reinstatement by the Licensor. + + For the avoidance of doubt, this Section 6(b) does not affect any + right the Licensor may have to seek remedies for Your violations + of this Public License. + + c. For the avoidance of doubt, the Licensor may also offer the + Licensed Material under separate terms or conditions or stop + distributing the Licensed Material at any time; however, doing so + will not terminate this Public License. + + d. Sections 1, 5, 6, 7, and 8 survive termination of this Public + License. + + +Section 7 -- Other Terms and Conditions. + + a. The Licensor shall not be bound by any additional or different + terms or conditions communicated by You unless expressly agreed. + + b. Any arrangements, understandings, or agreements regarding the + Licensed Material not stated herein are separate from and + independent of the terms and conditions of this Public License. + + +Section 8 -- Interpretation. + + a. For the avoidance of doubt, this Public License does not, and + shall not be interpreted to, reduce, limit, restrict, or impose + conditions on any use of the Licensed Material that could lawfully + be made without permission under this Public License. + + b. To the extent possible, if any provision of this Public License is + deemed unenforceable, it shall be automatically reformed to the + minimum extent necessary to make it enforceable. If the provision + cannot be reformed, it shall be severed from this Public License + without affecting the enforceability of the remaining terms and + conditions. + + c. No term or condition of this Public License will be waived and no + failure to comply consented to unless expressly agreed to by the + Licensor. + + d. Nothing in this Public License constitutes or may be interpreted + as a limitation upon, or waiver of, any privileges and immunities + that apply to the Licensor or You, including from the legal + processes of any jurisdiction or authority. + +- - - - + +BSD 3-Clause License + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +- - - - diff --git a/LICENSE.md b/LICENSE.md deleted file mode 100644 index 0a9804c..0000000 --- a/LICENSE.md +++ /dev/null @@ -1,3 +0,0 @@ -All Reports in this Repository are licensed by Contributors under the [W3C Software and Document License](http://www.w3.org/Consortium/Legal/2015/copyright-software-and-document). -Contributions to Specifications are made under the [W3C CLA](https://www.w3.org/community/about/agreements/cla/). -Contributions to Test Suites are made under the [W3C 3-clause BSD License](https://www.w3.org/Consortium/Legal/2008/03-bsd-license.html). diff --git a/Makefile b/Makefile index a28941a..42de7ce 100644 --- a/Makefile +++ b/Makefile @@ -1,27 +1,23 @@ -SHELL=/bin/bash +SHELL=/bin/bash -o pipefail +.PHONY: local remote deploy -local: spec.bs - bikeshed --die-on=warning spec spec.bs spec.html - -spec.html: spec.bs +remote: spec.bs @ (HTTP_STATUS=$$(curl https://api.csswg.org/bikeshed/ \ - --output spec.html \ - --write-out "%{http_code}" \ - --header "Accept: text/plain, text/html" \ - -F die-on=warning \ - -F file=@spec.bs) && \ - [[ "$$HTTP_STATUS" -eq "200" ]]) || ( \ - echo ""; cat spec.html; echo ""; \ - rm -f spec.html; \ - exit 22 \ - ); + --output spec.html \ + --write-out "%{http_code}" \ + --header "Accept: text/plain, text/html" \ + -F die-on=warning \ + -F md-Text-Macro="COMMIT-SHA LOCAL COPY" \ + -F file=@spec.bs) && \ + [[ "$$HTTP_STATUS" -eq "200" ]]) || ( \ + echo ""; cat spec.html; echo ""; \ + rm -f spec.html; \ + exit 22 \ + ); -remote: spec.html - -ci: spec.bs - mkdir -p out - make remote - mv spec.html out/index.html +local: spec.bs + bikeshed spec spec.bs spec.html --md-Text-Macro="COMMIT-SHA LOCAL COPY" -clean: - rm spec.html +deploy: spec.bs + curl --remote-name --fail https://resources.whatwg.org/build/deploy.sh + bash ./deploy.sh diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..47dad46 --- /dev/null +++ b/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,21 @@ + + +- [ ] At least two implementers are interested (and none opposed): + * … + * … +- [ ] [Tests](https://github.com/web-platform-tests/wpt) are written and can be reviewed and commented upon at: + * … +- [ ] [Implementation bugs](https://github.com/whatwg/meta/blob/main/MAINTAINERS.md#handling-pull-requests) are filed: + * Chromium: … + * Gecko: … + * WebKit: … + * Deno: … + * kenchris/urlpattern-polyfill: … +- [ ] [MDN issue](https://github.com/whatwg/meta/blob/main/MAINTAINERS.md#handling-pull-requests) is filed: … +- [ ] The top of this comment includes a [clear commit message](https://github.com/whatwg/meta/blob/main/COMMITTING.md) to use. + +(See [WHATWG Working Mode: Changes](https://whatwg.org/working-mode#changes) for more details.) diff --git a/README.md b/README.md new file mode 100644 index 0000000..628e6ad --- /dev/null +++ b/README.md @@ -0,0 +1,33 @@ +This repository hosts the [URL Pattern Standard](https://urlpattern.spec.whatwg.org/). + +## Code of conduct + +We are committed to providing a friendly, safe, and welcoming environment for all. Please read and respect the [Code of Conduct](https://whatwg.org/code-of-conduct). + +## Contribution opportunities + +Folks notice minor and larger issues with the URL Pattern Standard all the time and we'd love your help fixing those. Pull requests for typographical and grammar errors are also most welcome. + +Issues labeled ["good first issue"](https://github.com/whatwg/urlpattern/labels/good%20first%20issue) are a good place to get a taste for editing the URL Pattern Standard. Note that we don't assign issues and there's no reason to ask for availability either, just provide a pull request. + +If you are thinking of suggesting a new feature, read through the [FAQ](https://whatwg.org/faq) and [Working Mode](https://whatwg.org/working-mode) documents to get yourself familiarized with the process. + +We'd be happy to help you with all of this [on Chat](https://whatwg.org/chat). + +## Pull requests + +In short, change `spec.bs` and submit your patch, with a [good commit message](https://github.com/whatwg/meta/blob/main/COMMITTING.md). + +Please add your name to the Acknowledgments section in your first pull request, even for trivial fixes. The names are sorted lexicographically. + +To ensure your patch meets all the necessary requirements, please also see the [Contributor Guidelines](https://github.com/whatwg/meta/blob/main/CONTRIBUTING.md). Editors of the URL Pattern Standard are expected to follow the [Maintainer Guidelines](https://github.com/whatwg/meta/blob/main/MAINTAINERS.md). + +## Tests + +Tests are an essential part of the standardization process and will need to be created or adjusted as changes to the standard are made. Tests for the URL Pattern Standard can be found in the `urlpattern/` directory of [`web-platform-tests/wpt`](https://github.com/web-platform-tests/wpt). + +A dashboard showing the tests running against browser engines can be seen at [wpt.fyi/results/urlpattern](https://wpt.fyi/results/urlpattern). + +## Building "locally" + +For quick local iteration, run `make`; this will use a web service to build the standard, so that you don't have to install anything. See more in the [Contributor Guidelines](https://github.com/whatwg/meta/blob/main/CONTRIBUTING.md#building). diff --git a/readme.md b/readme.md deleted file mode 100644 index 4f8b8a4..0000000 --- a/readme.md +++ /dev/null @@ -1,10 +0,0 @@ -This repository proposes creating a native web API to match URLs called URLPattern. URLPattern would support both web developer use in JS and native URL matching in other web APIs. For example, the initial use cases discuss using URLPattern for service worker scope matching. - -For more information: - -* The [URLPattern documentation](mdn-drafts/QUICK-REFERENCE.md) describes the final API shape and provides a number of examples. -* The [December 2020 update](202012-update.md) describes the API shape and implementation status at the time. -* The [explainer](explainer.md) discusses the motivating use cases and early API ideas. -* The [design document](https://docs.google.com/document/d/17L6b3zlTHtyxQvOAvbK55gQOi5rrJLERwjt_sKXpzqc/edit) goes into more detail, including webidl and how the API might be implemented in Chromium. Some of this has changed during implementation. See the [latest update](202012-update.md) for the most recent API shape. - -For questions about usage, please use [Github Discussions](https://github.com/WICG/urlpattern/discussions). For issues with the spec and feature requests, please use [Github Issues](https://github.com/WICG/urlpattern/issues). diff --git a/spec.bs b/spec.bs index 5b2e916..5ca0fe4 100644 --- a/spec.bs +++ b/spec.bs @@ -337,7 +337,7 @@ Each {{URLPattern}} object has an associated hash component< 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. 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. Let |pathCompileOptions| be copy of the [=pathname options=] with the the [=options/ignore case=] property set to |options|["{{URLPatternOptions/ignoreCase}}"]. + 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|. @@ -681,8 +681,8 @@ To parse a constructor string given a string |input|:
"`hostname`"
- 1. If the the result of running [=is an IPv6 open=] given |parser| is true, then increment |parser|'s [=constructor string parser/hostname IPv6 bracket depth=] by 1. - 1. Otherwise if the the result of running [=is an IPv6 close=] given |parser| is true, then decrement |parser|'s [=constructor string parser/hostname IPv6 bracket depth=] by 1. + 1. If the result of running [=is an IPv6 open=] given |parser| is true, then increment |parser|'s [=constructor string parser/hostname IPv6 bracket depth=] by 1. + 1. Otherwise if the result of running [=is an IPv6 close=] given |parser| is true, then decrement |parser|'s [=constructor string parser/hostname IPv6 bracket depth=] by 1. 1. Otherwise if the result of running [=is a port prefix=] given |parser| is true and |parser|'s [=constructor string parser/hostname IPv6 bracket depth=] is zero, then run [=change state=] given |parser|, "`port`", and 1. 1. Otherwise if the result of running [=is a pathname start=] given |parser| is true, then run [=change state=] given |parser|, "`pathname`", and 0. 1. Otherwise if the result of running [=is a search prefix=] given |parser| is true, then run [=change state=] given |parser|, "`search`", and 1. @@ -1423,7 +1423,7 @@ To generate a regular expression and name list from a given [= 1. [=Continue=]. 1. If |part|'s [=part/modifier=] is "`none`" or "`optional`":
-

This section handles non-repeating parts with a [=part/prefix=] and/or [=part/suffix=]. There is an inner capturing group that contains the primary |regexp value|. The inner group is then combined with the [=part/prefix=] and/or [=part/suffix=] in an outer non-capturing group. Finally the modifier is applied. The resulting form is as follows. +

This section handles non-repeating parts with a [=part/prefix=] or [=part/suffix=]. There is an inner capturing group that contains the primary |regexp value|. The inner group is then combined with the [=part/prefix=] or [=part/suffix=] in an outer non-capturing group. Finally the modifier is applied. The resulting form is as follows.

`(?:())`

1. Append "`(?:`" to the end of |result|. @@ -1438,7 +1438,7 @@ To generate a regular expression and name list from a given [= 1. [=Assert=]: |part|'s [=part/modifier=] is "`zero-or-more`" or "`one-or-more`". 1. [=Assert=]: |part|'s [=part/prefix=] is not the empty string or |part|'s [=part/suffix=] is not the empty string.
-

Repeating parts with a [=part/prefix=] and/or [=part/suffix=] are dramatically more complicated. We want to exclude the initial [=part/prefix=] and the final [=part/suffix=], but include them between any repeated elements. To achieve this we provide a separate initial expression that excludes the [=part/prefix=]. Then the expression is duplicated with the [=part/prefix=]/[=part/suffix=] values included in an optional repeating element. If zero values are permitted then a final optional modifier may be appended. The resulting form is as follows. +

Repeating parts with a [=part/prefix=] or [=part/suffix=] are dramatically more complicated. We want to exclude the initial [=part/prefix=] and the final [=part/suffix=], but include them between any repeated elements. To achieve this we provide a separate initial expression that excludes the [=part/prefix=]. Then the expression is duplicated with the [=part/prefix=]/[=part/suffix=] values included in an optional repeating element. If zero values are permitted then a final optional modifier may be appended. The resulting form is as follows.

`(?:((?:)(?:(?:))*))?`

1. Append "`(?:`" to the end of |result|. From 7ef2e902d3a4a82c1db0396588982507d235c423 Mon Sep 17 00:00:00 2001 From: Domenic Denicola Date: Tue, 17 Oct 2023 16:25:37 +0900 Subject: [PATCH 02/11] Editorial: update the standard for the WHATWG move * Use the WHATWG template. * Add an Acknowledgments section and IPR statement. * Sentence-case all headings. * Add missing example IDs and suppress a warning about "optional" being used in an example. * Minor fixes to the introductory example to work well with WHATWG styling. --- spec.bs | 185 ++++++++++++++++++++------------------------------------ 1 file changed, 67 insertions(+), 118 deletions(-) diff --git a/spec.bs b/spec.bs index 5ca0fe4..3839c26 100644 --- a/spec.bs +++ b/spec.bs @@ -1,21 +1,10 @@ @@ -31,113 +20,55 @@ spec: ECMASCRIPT; urlPrefix: https://tc39.es/ecma262/ text: IdentifierStart; url: #prod-IdentifierStart - - - - -

The {{URLPattern}} class

+

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=]. 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. -
- The shorthand "`https://example.com/:category/*`" corresponds to the following components: +
+

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

- : [=URLPattern/protocol component|protocol=] - :: "`https`" - : [=URLPattern/username component|username=] - :: "" - : [=URLPattern/password component|password=] - :: "" - : [=URLPattern/hostname component|hostname=] - :: "`example.com`" - : [=URLPattern/port component|port=] - :: "" - : [=URLPattern/pathname component|pathname=] - :: "`/:category/*`" - : [=URLPattern/search component|search=] - :: "" - : [=URLPattern/hash component|hash=] - :: "" +
[=URLPattern/protocol component|protocol=] +
"`https`" + +
[=URLPattern/username component|username=] +
"" + +
[=URLPattern/password component|password=] +
"" + +
[=URLPattern/hostname component|hostname=] +
"`example.com`" + +
[=URLPattern/port component|port=] +
"" + +
[=URLPattern/pathname component|pathname=] +
"`/:category/*`" + +
[=URLPattern/search component|search=] +
"" + +
[=URLPattern/hash component|hash=] +
""
It matches the following URLs: - * `https://example.com/products/` - * `https://example.com/blog/our-greatest-product-ever` + +
    + * `https://example.com/products/` + * `https://example.com/blog/our-greatest-product-ever` +
It does not match the following URLs: - * `https://example.com/` - * `http://example.com/products/` - * `https://example.com:8443/blog/our-greatest-product-ever` + +
    + * `https://example.com/` + * `http://example.com/products/` + * `https://example.com:8443/blog/our-greatest-product-ever` +
@@ -536,7 +467,7 @@ The <dfn>pathname options</dfn> is an [=options=] [=struct=] with [=options/deli 1. Return false. </div> -<h3 id=constructor-string-parsing>Constructor String Parsing</h3> +<h3 id=constructor-string-parsing>Constructor string parsing</h3> A <dfn export>constructor string parser</dfn> is a [=struct=]. @@ -877,17 +808,17 @@ A <dfn>pattern string</dfn> is a string that is written to match a set of target It can be [=parse a pattern string|parsed=] to produce a [=/part list=] which describes, in order, what must appear in a component string for the pattern string to match. -<div class="example"> +<div class="example" id="example-pattern-strings"> Pattern strings can contain capture groups, which by default match the shortest possible string, up to a component-specific separator (`/` in the pathname, `.` in the hostname). For example, the pathname pattern "`/blog/:title`" will match "`/blog/hello-world`" but not "`/blog/2012/02`". A regular expression can also be used instead, so the pathname pattern "`/blog/:year(\\d+)/:month(\\d+)`" will match "`/blog/2012/02`". - A group can also be made optional, or repeated, by using a modifier. For example, the pathname pattern "`/products/:id?"` will match both "`/products`" and "`/products/2`" (but not "`/products/`"). In the pathname specifically, groups automatically require a leading `/`; to avoid this, the group can be explicitly deliminated, as in the pathname pattern "`/products/{:id}?`". + A group can also be made <span class=allow-2119>optional</span>, or repeated, by using a modifier. For example, the pathname pattern "`/products/:id?"` will match both "`/products`" and "`/products/2`" (but not "`/products/`"). In the pathname specifically, groups automatically require a leading `/`; to avoid this, the group can be explicitly deliminated, as in the pathname pattern "`/products/{:id}?`". 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-patterns>Parsing patterns</h3> <h4 id=tokens>Tokens</h4> @@ -1376,7 +1307,7 @@ To determine if a value <dfn>is a duplicate name</dfn> given a [=pattern parser= 1. Return false. </div> -<h3 id=converting-part-lists-to-regular-expressions>Converting Part Lists to Regular Expressions</h3> +<h3 id=converting-part-lists-to-regular-expressions>Converting part lists to regular expressions</h3> <div algorithm> To <dfn export>generate a regular expression and name list</dfn> from a given [=/part list=] |part list| and [=/options=] |options|: @@ -1490,7 +1421,7 @@ To <dfn>escape a regexp string</dfn> given a string |input|: 1. Return |result|. </div> -<h3 id=converting-part-lists-to-pattern-strings>Converting Part Lists to Pattern Strings</h3> +<h3 id=converting-part-lists-to-pattern-strings>Converting part lists to pattern strings</h3> <div algorithm> To <dfn export>generate a [=/pattern string=]</dfn> from a given [=/part list=] |part list| and [=/options=] |options|: @@ -1619,7 +1550,7 @@ To <dfn>convert a modifier to a string</dfn> given a [=part/modifier=] |modifier <h2 id=canon>Canonicalization</h2> -<h3 id=canon-encoding-callbacks>Encoding Callbacks</h3> +<h3 id=canon-encoding-callbacks>Encoding callbacks</h3> <div algorithm> To <dfn>canonicalize a protocol</dfn> given a string |value|: @@ -1741,7 +1672,7 @@ To <dfn>convert a modifier to a string</dfn> given a [=part/modifier=] |modifier 1. Return |dummyURL|'s [=url/fragment=]. </div> -<h3 id=canon-processing-for-init>{{URLPatternInit}} Processing</h3> +<h3 id=canon-processing-for-init>{{URLPatternInit}} processing</h3> <div algorithm> To <dfn>process a URLPatternInit</dfn> given a {{URLPatternInit}} |init|, a string |type|, a string or null |protocol|, a string or null |username|, a string or null |password|, a string or null |hostname|, a string or null |port|, a string or null |pathname|, a string or null |search|, and a string or null |hash|: @@ -1873,3 +1804,21 @@ To <dfn>convert a modifier to a string</dfn> given a [=part/modifier=] |modifier 1. If |type| is "`pattern`" then return |strippedValue|. 1. Return the result of running [=canonicalize a hash=] given |strippedValue|. </div> + +<h2 id=acknowledgments class=no-num>Acknowledgments</h2> + +The editors would like to thank +Anne van Kesteren, +Luca Casonato, and +Sayan Pal +for their contributors to this specification. + +A special thanks to the [pillarjs/path-to-regexp](https://github.com/pillarjs/path-to-regexp) creators for their work on the open-source library and pattern syntax which inspired this standard. + +This standard is written by +Ben Kelly ([Google](https://www.google.com/), [wanderview@chromium.org](mailto:wanderview@chromium.org)), +Jeremy Roman ([Google](https://www.google.com/), [jbroman@chromium.org](mailto:jbroman@chromium.org)), and +Shunya Shishido ([Google](https://www.google.com/), [sisidovski@chromium.org](mailto:sisidovski@chromium.org)). + + +<p boilerplate=ipr>This Living Standard was originally developed in the W3C WICG, where it was available under the [W3C Software and Document License](https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document). From 8bce2d4f97c0d8bf2c7a599a0541e93b36d09ea9 Mon Sep 17 00:00:00 2001 From: Domenic Denicola <d@domenic.me> Date: Wed, 18 Oct 2023 11:44:18 +0900 Subject: [PATCH 03/11] Update Shunya's name --- spec.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec.bs b/spec.bs index 3839c26..432ee14 100644 --- a/spec.bs +++ b/spec.bs @@ -1818,7 +1818,7 @@ A special thanks to the [pillarjs/path-to-regexp](https://github.com/pillarjs/pa This standard is written by Ben Kelly ([Google](https://www.google.com/), [wanderview@chromium.org](mailto:wanderview@chromium.org)), Jeremy Roman ([Google](https://www.google.com/), [jbroman@chromium.org](mailto:jbroman@chromium.org)), and -Shunya Shishido ([Google](https://www.google.com/), [sisidovski@chromium.org](mailto:sisidovski@chromium.org)). +宍戸俊哉 (Shunya Shishido, [Google](https://www.google.com/), [sisidovski@chromium.org](mailto:sisidovski@chromium.org)). <p boilerplate=ipr>This Living Standard was originally developed in the W3C WICG, where it was available under the [W3C Software and Document License](https://www.w3.org/Consortium/Legal/2015/copyright-software-and-document). From b35b25cd09f74c42a2e3c3f4fbabac8fdcf0b075 Mon Sep 17 00:00:00 2001 From: Domenic Denicola <d@domenic.me> Date: Wed, 18 Oct 2023 11:59:02 +0900 Subject: [PATCH 04/11] Validation error fixes --- spec.bs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/spec.bs b/spec.bs index 432ee14..f281c99 100644 --- a/spec.bs +++ b/spec.bs @@ -1001,7 +1001,7 @@ A [=tokenizer=] has an associated <dfn for=tokenizer>code point</dfn>, a Unicode 1. Set |tokenizer|'s [=token/index=] to |next position|. </div> -<div algorthm> +<div algorithm> To <dfn>add a token with default length</dfn> for a given [=tokenizer=] |tokenizer|, [=token/type=] |type|, number |next position|, and number |value position|: 1. Let |computed length| be |next position| &minus; |value position|. @@ -1114,9 +1114,9 @@ To <dfn>parse a pattern string</dfn> given a [=/pattern string=] |input|, [=/opt 1. Let |parser| be a new [=pattern parser=] whose [=pattern parser/encoding callback=] is |encoding callback| and [=pattern parser/segment wildcard regexp=] is the result of running [=generate a segment wildcard regexp=] given |options|. 1. Set |parser|'s [=pattern parser/token list=] to the result of running [=tokenize=] given |input| and "<a for="tokenize policy">`strict`</a>". 1. While |parser|'s [=pattern parser/index=] is less than |parser|'s [=pattern parser/token list=]'s [=list/size=]: - <div class="note"> - <p>This first section is looking for the sequence: `<prefix char><name><regexp><modifier>`. There could be zero to all of these tokens. - <dl class="example" id="parse-example-1"> + <div class="example"> + <p>This first section is looking for the sequence: `<prefix char><name><regexp><modifier>`. There could be zero to all of these tokens. + <dl id="parse-example-1"> <dt>"`/:foo(bar)?`"</dt> <dd>All four [=tokens=].</dd> <dt>"`/`"</dt> From 414d5fcfb98ec8259b8fb6d5b4293de4742f3bb5 Mon Sep 17 00:00:00 2001 From: Domenic Denicola <d@domenic.me> Date: Wed, 18 Oct 2023 12:02:40 +0900 Subject: [PATCH 05/11] More fixes --- spec.bs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/spec.bs b/spec.bs index f281c99..e65f8b7 100644 --- a/spec.bs +++ b/spec.bs @@ -357,7 +357,7 @@ A [=component=] has an associated <dfn for=component>group name list</dfn>, a [= 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 allow-2119">The specification uses regular expressions to perform all matching, but this is not required. 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 should be immediately evaluated in the [=compile a component=] algorithm so an error can be thrown if they are invalid. + <p class="note">The specification uses regular expressions to perform all matching, but this is not required. 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. Return a new [=component=] whose [=component/pattern string=] is |pattern string|, [=component/regular expression=] is |regular expression|, and [=component/group name list=] is |name list|. </div> @@ -509,7 +509,7 @@ A [=constructor string parser=] has an associated <dfn export for="constructor s <p>The URLPattern constructor string algorithm is very similar to the [=basic URL parser=] algorithm, but some differences prevent us from using that algorithm directly. <p>First, the URLPattern constructor string parser operates on [=tokens=] generated using the "`lenient`" [=tokenize policy=]. In constrast, [=basic URL parser=] operates on code points. Operating on [=tokens=] allows the URLPattern constructor string parser to more easily distinguish between code points that are significant pattern syntax and code points that might be a URL component separator. For example, it makes it trivial to handle named groups like "`:hmm`" in "`https://a.c:hmm.example.com:8080`" without getting confused with the port number. <p>Second, the URLPattern constructor string parser needs to avoid applying URL canonicalization to all code points like [=basic URL parser=] does. Instead we perform canonicalization on only parts of the pattern string we know are safe later when compiling each component pattern string. - <p class=allow-2119>Finally, the URLPattern constructor string parser does not handle some parts of the [=basic URL parser=] state machine. For example, it does not treat backslashes specially as they would all be treated as pattern characters and would require excessive escaping. In addition, this parser may not handle some more esoteric parts of the URL parsing algorithm like file URLs with a hostname. The goal with this parser was to handle the most common URLs while allowing any niche case to be handled instead via the {{URLPatternInit}} constructor. + <p>Finally, the URLPattern constructor string parser does not handle some parts of the [=basic URL parser=] state machine. For example, it does not treat backslashes specially as they would all be treated as pattern characters and would require excessive escaping. In addition, this parser might not handle some more esoteric parts of the URL parsing algorithm like file URLs with a hostname. The goal with this parser was to handle the most common URLs while allowing any niche case to be handled instead via the {{URLPatternInit}} constructor. </div> <div algorithm> @@ -562,11 +562,11 @@ To <dfn>parse a constructor string</dfn> given a string |input|: 1. Increment |parser|'s [=constructor string parser/token index=] by |parser|'s [=constructor string parser/token increment=]. 1. [=Continue=]. 1. Switch on |parser|'s [=constructor string parser/state=] and run the associated steps: - <dl class=switch> + <dl class="switch"> <dt>"<a for="constructor string parser/state">`init`</a>"</dt> <dd> 1. If the result of running [=is a protocol suffix=] given |parser| is true: - <p class="note allow-2119">We found a protocol suffix, so this must be an absolute URLPattern constructor string. Therefore initialize all component to the empty string. + <p class="note">We found a protocol suffix, so this is an absolute URLPattern constructor string. Therefore initialize all component to the empty string. 1. Set |parser|'s [=constructor string parser/result=]["{{URLPatternInit/username}}"] to the empty string. 1. Set |parser|'s [=constructor string parser/result=]["{{URLPatternInit/password}}"] to the empty string. 1. Set |parser|'s [=constructor string parser/result=]["{{URLPatternInit/hostname}}"] to the empty string. @@ -1114,9 +1114,9 @@ To <dfn>parse a pattern string</dfn> given a [=/pattern string=] |input|, [=/opt 1. Let |parser| be a new [=pattern parser=] whose [=pattern parser/encoding callback=] is |encoding callback| and [=pattern parser/segment wildcard regexp=] is the result of running [=generate a segment wildcard regexp=] given |options|. 1. Set |parser|'s [=pattern parser/token list=] to the result of running [=tokenize=] given |input| and "<a for="tokenize policy">`strict`</a>". 1. While |parser|'s [=pattern parser/index=] is less than |parser|'s [=pattern parser/token list=]'s [=list/size=]: - <div class="example"> + <div class="example" id="parse-example-1"> <p>This first section is looking for the sequence: `<prefix char><name><regexp><modifier>`. There could be zero to all of these tokens. - <dl id="parse-example-1"> + <dl> <dt>"`/:foo(bar)?`"</dt> <dd>All four [=tokens=].</dd> <dt>"`/`"</dt> @@ -1139,7 +1139,7 @@ To <dfn>parse a pattern string</dfn> given a [=/pattern string=] |input|, [=/opt 1. Let |name token| be the result of running [=try to consume a token=] given |parser| and "<a for=token/type>`name`</a>". 1. Let |regexp or wildcard token| be the result of running [=try to consume a regexp or wildcard token=] given |parser| and |name token|. 1. If |name token| is not null or |regexp or wildcard token| is not null: - <p class=note>If there is a matching group, we need to add the [=part=] immediately. + <p class="note">If there is a matching group, we need to add the [=part=] immediately. 1. Let |prefix| be the empty string. 1. If |char token| is not null then set |prefix| to |char token|'s [=token/value=]. 1. If |prefix| is not the empty string and not |options|'s [=options/prefix code point=]: @@ -1150,15 +1150,15 @@ To <dfn>parse a pattern string</dfn> given a [=/pattern string=] |input|, [=/opt 1. Run [=add a part=] given |parser|, |prefix|, |name token|, |regexp or wildcard token|, the empty string, and |modifier token|. 1. [=Continue=]. 1. Let |fixed token| be |char token|. - <p class=note>If there was no matching group, then we need to buffer any fixed text. We want to collect as much text as possible before adding it as a "<a for=part/type>`fixed-text`</a>" [=part=]. + <p class="note">If there was no matching group, then we need to buffer any fixed text. We want to collect as much text as possible before adding it as a "<a for=part/type>`fixed-text`</a>" [=part=]. 1. If |fixed token| is null, then set |fixed token| to the result of running [=try to consume a token=] given |parser| and "<a for=token/type>`escaped-char`</a>". 1. If |fixed token| is not null: 1. Append |fixed token|'s [=token/value=] to |parser|'s [=pattern parser/pending fixed value=]. 1. [=Continue=]. 1. Let |open token| be the result of running [=try to consume a token=] given |parser| and "<a for=token/type>`open`</a>". - <div class=note> - <p class=allow-2119>Next we look for the sequence `<open><char prefix><name><regexp><char suffix><close><modifier>`. The open and close are required, but the other tokens are optional. - <dl class=example id=parsing-example-2> + <div class="example" id="parsing-example-2"> + <p>Next we look for the sequence `<open><char prefix><name><regexp><char suffix><close><modifier>`. The open and close are necessary, but the other tokens are optional. + <dl> <dt>"`{a:foo(bar)b}?`"</dt> <dd>All [=tokens=] are present. <dt>"`{:foo}?`"</dt> From dcd5d193b3ccf1cdd64f27c3749f1bcb4a61a896 Mon Sep 17 00:00:00 2001 From: Domenic Denicola <d@domenic.me> Date: Wed, 18 Oct 2023 14:25:56 +0900 Subject: [PATCH 06/11] More 2119 fixes --- spec.bs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/spec.bs b/spec.bs index e65f8b7..5981dfb 100644 --- a/spec.bs +++ b/spec.bs @@ -357,7 +357,7 @@ A [=component=] has an associated <dfn for=component>group name list</dfn>, a [= 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 required. 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. + <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. Return a new [=component=] whose [=component/pattern string=] is |pattern string|, [=component/regular expression=] is |regular expression|, and [=component/group name list=] is |name list|. </div> @@ -523,12 +523,10 @@ To <dfn>parse a constructor string</dfn> given a string |input|: </div> 1. [=While=] |parser|'s [=constructor string parser/token index=] is less than |parser|'s [=constructor string parser/token list=] [=list/size=]: 1. Set |parser|'s [=constructor string parser/token increment=] to 1. - <p class="note allow-2119">On every iteration of the parse loop the |parser|'s [=constructor string parser/token index=] will be incremented by its [=constructor string parser/token increment=] value. Typically this means incrementing by 1, but at certain times it is set to zero. The [=constructor string parser/token increment=] is then always reset back to 1 at the top of the loop. + <p class="note">On every iteration of the parse loop the |parser|'s [=constructor string parser/token index=] will be incremented by its [=constructor string parser/token increment=] value. Typically this means incrementing by 1, but at certain times it is set to zero. The [=constructor string parser/token increment=] is then always reset back to 1 at the top of the loop. 1. If |parser|'s [=constructor string parser/token list=][|parser|'s [=constructor string parser/token index=]]'s [=token/type=] is "<a for=token/type>`end`</a>" then: 1. If |parser|'s [=constructor string parser/state=] is "<a for="constructor string parser/state">`init`</a>": - <div class=note> - <p class=allow-2119>If we reached the end of the string in the "<a for="constructor string parser/state">`init`</a>" [=constructor string parser/state=], then we failed to find a protocol terminator and this must be a relative URLPattern constructor string. - </div> + <p class="note">If we reached the end of the string in the "<a for="constructor string parser/state">`init`</a>" [=constructor string parser/state=], then we failed to find a protocol terminator and this has to be a relative URLPattern constructor string. 1. Run [=rewind=] given |parser|. <p class=note>We next determine at which component the relative pattern begins. Relative pathnames are most common, but URLs and URLPattern constructor strings can begin with the search or hash components as well. 1. If the result of running [=is a hash prefix=] given |parser| is true, then run [=change state=] given |parser|, "<a for="constructor string parser/state">`hash`</a>" and 1. @@ -813,7 +811,7 @@ It can be [=parse a pattern string|parsed=] to produce a [=/part list=] which de A regular expression can also be used instead, so the pathname pattern "`/blog/:year(\\d+)/:month(\\d+)`" will match "`/blog/2012/02`". - A group can also be made <span class=allow-2119>optional</span>, or repeated, by using a modifier. For example, the pathname pattern "`/products/:id?"` will match both "`/products`" and "`/products/2`" (but not "`/products/`"). In the pathname specifically, groups automatically require a leading `/`; to avoid this, the group can be explicitly deliminated, as in the pathname pattern "`/products/{:id}?`". + A group can also be made <span class="allow-2119">optional</span>, or repeated, by using a modifier. For example, the pathname pattern "`/products/:id?"` will match both "`/products`" and "`/products/2`" (but not "`/products/`"). In the pathname specifically, groups automatically require a leading `/`; to avoid this, the group can be explicitly deliminated, as in the pathname pattern "`/products/{:id}?`". A full wildcard `*` can also be used to match as much as possible, as in the pathname pattern "`/products/*`". </div> @@ -1157,7 +1155,7 @@ To <dfn>parse a pattern string</dfn> given a [=/pattern string=] |input|, [=/opt 1. [=Continue=]. 1. Let |open token| be the result of running [=try to consume a token=] given |parser| and "<a for=token/type>`open`</a>". <div class="example" id="parsing-example-2"> - <p>Next we look for the sequence `<open><char prefix><name><regexp><char suffix><close><modifier>`. The open and close are necessary, but the other tokens are optional. + <p>Next we look for the sequence `<open><char prefix><name><regexp><char suffix><close><modifier>`. The open and close are necessary, but the other tokens are not. <dl> <dt>"`{a:foo(bar)b}?`"</dt> <dd>All [=tokens=] are present. @@ -1335,7 +1333,7 @@ To <dfn export>generate a regular expression and name list</dfn> from a given [= 1. Otherwise if |part|'s [=part/type=] is "<a for=part/type>`full-wildcard`</a>", then set |regexp value| to [=full wildcard regexp value=]. 1. If |part|'s [=part/prefix=] is the empty string and |part|'s [=part/suffix=] is the empty string: <div class=note> - <p class=allow-2119>If there is no [=part/prefix=] or [=part/suffix=] then generation depends on the modifier. If there is no modifier or just the optional modifier, it uses the following simple form: + <p>If there is no [=part/prefix=] or [=part/suffix=] then generation depends on the modifier. If there is no modifier or just the <span class="allow-2119">optional</span> modifier, it uses the following simple form: <p>`(<regexp value>)<modifier>` <p>If there is a repeating modifier, however, we will use the more complex form: <p>`((?:<regexp value>)<modifier>)` @@ -1369,7 +1367,7 @@ To <dfn export>generate a regular expression and name list</dfn> from a given [= 1. [=Assert=]: |part|'s [=part/modifier=] is "<a for=part/modifier>`zero-or-more`</a>" or "<a for=part/modifier>`one-or-more`</a>". 1. [=Assert=]: |part|'s [=part/prefix=] is not the empty string or |part|'s [=part/suffix=] is not the empty string. <div class=note> - <p class=allow-2119>Repeating parts with a [=part/prefix=] or [=part/suffix=] are dramatically more complicated. We want to exclude the initial [=part/prefix=] and the final [=part/suffix=], but include them between any repeated elements. To achieve this we provide a separate initial expression that excludes the [=part/prefix=]. Then the expression is duplicated with the [=part/prefix=]/[=part/suffix=] values included in an optional repeating element. If zero values are permitted then a final optional modifier may be appended. The resulting form is as follows. + <p>Repeating parts with a [=part/prefix=] or [=part/suffix=] are dramatically more complicated. We want to exclude the initial [=part/prefix=] and the final [=part/suffix=], but include them between any repeated elements. To achieve this we provide a separate initial expression that excludes the [=part/prefix=]. Then the expression is duplicated with the [=part/prefix=]/[=part/suffix=] values included in an <span class="allow-2119">optional</span> repeating element. If zero values are permitted then a final <span class="allow-2119">optional</span> modifier can be appended. The resulting form is as follows. <p>`(?:<prefix>((?:<regexp value>)(?:<suffix><prefix>(?:<regexp value>))*)<suffix>)?` </div> 1. Append "`(?:`" to the end of |result|. From 0e3a072b71d152c8bb43eb7a19051334a07c29e6 Mon Sep 17 00:00:00 2001 From: Domenic Denicola <d@domenic.me> Date: Wed, 18 Oct 2023 14:31:01 +0900 Subject: [PATCH 07/11] Delete extra CoC --- CODE_OF_CONDUCT.md | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 CODE_OF_CONDUCT.md diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index 04f41dc..0000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,3 +0,0 @@ -# Code of Conduct - -All documentation, code and communication under this repository are covered by the [W3C Code of Ethics and Professional Conduct](https://www.w3.org/Consortium/cepc/). From 91222315c4fd6343d6c8e35434f69aec33963e2b Mon Sep 17 00:00:00 2001 From: Domenic Denicola <d@domenic.me> Date: Wed, 18 Oct 2023 14:31:59 +0900 Subject: [PATCH 08/11] Delete extra CONTRIBUTING.md --- CONTRIBUTING.md | 26 -------------------------- 1 file changed, 26 deletions(-) delete mode 100644 CONTRIBUTING.md diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index fb24f38..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,26 +0,0 @@ -## Editing the specification - -Edits to the specification are done in the `spec.bs` file, which is then compiled with the [Bikeshed](https://tabatkins.github.io/bikeshed/) spec pre-processor. - -To build the specification, you can use one of: - -- `make local`: uses a locally-installed copy of Bikeshed -- `make remote`: uses a Bikeshed web service, so you don't have to install anything locally - -## For maintainers: identifying contributors to a pull request - -If the author is not the sole contributor to a pull request, please identify all contributors in the pull request comment. - -To add a contributor (other than the author, which is automatic), mark them one per line as follows: - -``` -+@github_username -``` - -If you added a contributor by mistake, you can remove them in a comment with: - -``` --@github_username -``` - -If the author is making a pull request on behalf of someone else but they had no part in designing the feature, you can remove them with the above syntax. From b62405015d6ed4c5d54b46436319bf529c51a815 Mon Sep 17 00:00:00 2001 From: Domenic Denicola <d@domenic.me> Date: Wed, 18 Oct 2023 14:32:53 +0900 Subject: [PATCH 09/11] Delete w3c.json --- w3c.json | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 w3c.json diff --git a/w3c.json b/w3c.json deleted file mode 100644 index ddb742b..0000000 --- a/w3c.json +++ /dev/null @@ -1,5 +0,0 @@ - { - "group": [80485] -, "contacts": ["yoavweiss"] -, "repo-type": "cg-report" -} From e4b098eaf2a0dd85cd6d1e12247976c1818154d0 Mon Sep 17 00:00:00 2001 From: Domenic Denicola <d@domenic.me> Date: Wed, 18 Oct 2023 14:44:51 +0900 Subject: [PATCH 10/11] Update acks with info copied from OT update file --- spec.bs | 41 ++++++++++++++++++++++++++++++++++++++--- 1 file changed, 38 insertions(+), 3 deletions(-) diff --git a/spec.bs b/spec.bs index 5981dfb..524b0fd 100644 --- a/spec.bs +++ b/spec.bs @@ -1806,12 +1806,47 @@ To <dfn>convert a modifier to a string</dfn> given a [=part/modifier=] |modifier <h2 id=acknowledgments class=no-num>Acknowledgments</h2> The editors would like to thank +Alex Russell, Anne van Kesteren, -Luca Casonato, and -Sayan Pal +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, and +Youenn Fablet for their contributors to this specification. -A special thanks to the [pillarjs/path-to-regexp](https://github.com/pillarjs/path-to-regexp) creators for their work on the open-source library and pattern syntax which inspired this standard. +Special thanks to Blake Embrey and the other [pillarjs/path-to-regexp](https://github.com/pillarjs/path-to-regexp) [contributors](https://github.com/pillarjs/path-to-regexp/graphs/contributors) for building an excellent open source library that so many have found useful. + +Also, special thanks to Kenneth Rohde Christiansen for his work on the polyfill. He put in extensive work to adapt to the changing {{URLPattern}} API. This standard is written by Ben Kelly ([Google](https://www.google.com/), [wanderview@chromium.org](mailto:wanderview@chromium.org)), From 13b8b1464ec873dab131332035707adba66a8bb0 Mon Sep 17 00:00:00 2001 From: Domenic Denicola <d@domenic.me> Date: Wed, 18 Oct 2023 14:53:42 +0900 Subject: [PATCH 11/11] Turn off max line length in bs file --- .editorconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/.editorconfig b/.editorconfig index dfb139b..9947ad1 100644 --- a/.editorconfig +++ b/.editorconfig @@ -14,6 +14,7 @@ indent_style = tab [*.bs] indent_size = 2 +max_line_length = off [*.py] indent_size = 4