From 22c632e87d6a2113f28ecff375e2d5b6f69c9710 Mon Sep 17 00:00:00 2001 From: Ben Kelly Date: Wed, 28 Jul 2021 02:52:10 +0000 Subject: [PATCH] URLPattern: Implement compareComponent() method. This CL adds a prototype URLPattern.compareComponent() to provide a natural ordering to URLPattern pattern strings. This was based on feedback from routing framework authors and there is some discussion in: https://github.com/WICG/urlpattern/issues/61 The general algorithm is to compare the component patterns Part by Part. The PartType, Modifier, and text contents are compared for each Part, but group names are not considered. The end result is a mostly lexicographical ordering based on fixed text. Matching groups and modifiers are ordered such that more restrictive patterns are greater. Bug: 1232795 Change-Id: I8474cd7d7689e657c9c74c552ad630cdcdd86c95 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3052630 Commit-Queue: Ben Kelly Reviewed-by: Jeremy Roman Cr-Commit-Position: refs/heads/master@{#906025} --- .../mojom/web_feature/web_feature.mojom | 1 + .../bindings/generated_in_modules.gni | 2 + .../modules/url_pattern/url_pattern.cc | 30 +++++ .../modules/url_pattern/url_pattern.h | 6 +- .../modules/url_pattern/url_pattern.idl | 7 ++ .../url_pattern/url_pattern_component.cc | 115 ++++++++++++++++- .../url_pattern/url_pattern_component.h | 7 ++ .../urlpattern-compare-test-data.json | 116 ++++++++++++++++++ .../resources/urlpattern-compare-tests.js | 26 ++++ .../wpt/urlpattern/urlpattern-compare.any.js | 2 + .../urlpattern-compare.https.any.js | 2 + ...erface-listing-service-worker-expected.txt | 1 + ...face-listing-dedicated-worker-expected.txt | 1 + .../global-interface-listing-expected.txt | 1 + ...terface-listing-shared-worker-expected.txt | 1 + third_party/liburlpattern/pattern.cc | 14 +-- third_party/liburlpattern/pattern.h | 36 +++--- tools/metrics/histograms/enums.xml | 1 + 18 files changed, 342 insertions(+), 27 deletions(-) create mode 100644 third_party/blink/web_tests/external/wpt/urlpattern/resources/urlpattern-compare-test-data.json create mode 100644 third_party/blink/web_tests/external/wpt/urlpattern/resources/urlpattern-compare-tests.js create mode 100644 third_party/blink/web_tests/external/wpt/urlpattern/urlpattern-compare.any.js create mode 100644 third_party/blink/web_tests/external/wpt/urlpattern/urlpattern-compare.https.any.js diff --git a/third_party/blink/public/mojom/web_feature/web_feature.mojom b/third_party/blink/public/mojom/web_feature/web_feature.mojom index d00cb41c5b1921..90e7d02e98dafd 100644 --- a/third_party/blink/public/mojom/web_feature/web_feature.mojom +++ b/third_party/blink/public/mojom/web_feature/web_feature.mojom @@ -3278,6 +3278,7 @@ enum WebFeature { kBlobStoreAccessAcrossAgentClustersInResolveAsURLLoaderFactory = 3963, kBlobStoreAccessAcrossAgentClustersInResolveForNavigation = 3964, kTapDelayEnabled = 3965, + kV8URLPattern_CompareComponent_Method = 3966, // Add new features immediately above this line. Don't change assigned // numbers of any item, and don't reuse removed slots. diff --git a/third_party/blink/renderer/bindings/generated_in_modules.gni b/third_party/blink/renderer/bindings/generated_in_modules.gni index be695e387ee0ba..998b6e7a0012e6 100644 --- a/third_party/blink/renderer/bindings/generated_in_modules.gni +++ b/third_party/blink/renderer/bindings/generated_in_modules.gni @@ -873,6 +873,8 @@ generated_dictionary_sources_in_modules = [ "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_decoder_options.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_encoder_encode_into_result.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_text_encoder_encode_into_result.h", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_url_pattern_component.cc", + "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_url_pattern_component.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_url_pattern_component_result.cc", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_url_pattern_component_result.h", "$root_gen_dir/third_party/blink/renderer/bindings/modules/v8/v8_url_pattern_init.cc", diff --git a/third_party/blink/renderer/modules/url_pattern/url_pattern.cc b/third_party/blink/renderer/modules/url_pattern/url_pattern.cc index 60e69a5118580b..3abf9254028f1d 100644 --- a/third_party/blink/renderer/modules/url_pattern/url_pattern.cc +++ b/third_party/blink/renderer/modules/url_pattern/url_pattern.cc @@ -390,6 +390,36 @@ String URLPattern::hash() const { return hash_->GeneratePatternString(); } +// static +int URLPattern::compareComponent(const V8URLPatternComponent& component, + const URLPattern* left, + const URLPattern* right) { + switch (component.AsEnum()) { + case V8URLPatternComponent::Enum::kProtocol: + return url_pattern::Component::Compare(*left->protocol_, + *right->protocol_); + case V8URLPatternComponent::Enum::kUsername: + return url_pattern::Component::Compare(*left->username_, + *right->username_); + case V8URLPatternComponent::Enum::kPassword: + return url_pattern::Component::Compare(*left->password_, + *right->password_); + case V8URLPatternComponent::Enum::kHostname: + return url_pattern::Component::Compare(*left->hostname_, + *right->hostname_); + case V8URLPatternComponent::Enum::kPort: + return url_pattern::Component::Compare(*left->port_, *right->port_); + case V8URLPatternComponent::Enum::kPathname: + return url_pattern::Component::Compare(*left->pathname_, + *right->pathname_); + case V8URLPatternComponent::Enum::kSearch: + return url_pattern::Component::Compare(*left->search_, *right->search_); + case V8URLPatternComponent::Enum::kHash: + return url_pattern::Component::Compare(*left->hash_, *right->hash_); + } + NOTREACHED(); +} + void URLPattern::Trace(Visitor* visitor) const { visitor->Trace(protocol_); visitor->Trace(username_); diff --git a/third_party/blink/renderer/modules/url_pattern/url_pattern.h b/third_party/blink/renderer/modules/url_pattern/url_pattern.h index 387235391c3b2b..4dd1affda57ac8 100644 --- a/third_party/blink/renderer/modules/url_pattern/url_pattern.h +++ b/third_party/blink/renderer/modules/url_pattern/url_pattern.h @@ -1,4 +1,3 @@ -// Copyright 2020 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. @@ -7,6 +6,7 @@ #include "base/types/pass_key.h" #include "third_party/blink/renderer/bindings/modules/v8/v8_typedefs.h" +#include "third_party/blink/renderer/bindings/modules/v8/v8_url_pattern_component.h" #include "third_party/blink/renderer/modules/modules_export.h" #include "third_party/blink/renderer/platform/bindings/script_wrappable.h" #include "third_party/liburlpattern/parse.h" @@ -69,6 +69,10 @@ class MODULES_EXPORT URLPattern : public ScriptWrappable { String search() const; String hash() const; + static int compareComponent(const V8URLPatternComponent& component, + const URLPattern* left, + const URLPattern* right); + void Trace(Visitor* visitor) const override; private: diff --git a/third_party/blink/renderer/modules/url_pattern/url_pattern.idl b/third_party/blink/renderer/modules/url_pattern/url_pattern.idl index bc677cd67119ef..4140668a70e15c 100644 --- a/third_party/blink/renderer/modules/url_pattern/url_pattern.idl +++ b/third_party/blink/renderer/modules/url_pattern/url_pattern.idl @@ -4,6 +4,9 @@ typedef (USVString or URLPatternInit) URLPatternInput; +enum URLPatternComponent { "protocol", "username", "password", "hostname", + "port", "pathname", "search", "hash" }; + // https://wicg.github.io/urlpattern/ [ Exposed=(Window,Worker), @@ -26,4 +29,8 @@ typedef (USVString or URLPatternInit) URLPatternInput; readonly attribute USVString pathname; readonly attribute USVString search; readonly attribute USVString hash; + + [Measure] + static short compareComponent(URLPatternComponent component, + URLPattern left, URLPattern right); }; diff --git a/third_party/blink/renderer/modules/url_pattern/url_pattern_component.cc b/third_party/blink/renderer/modules/url_pattern/url_pattern_component.cc index 2f7516961d5ae0..8e029755c12b39 100644 --- a/third_party/blink/renderer/modules/url_pattern/url_pattern_component.cc +++ b/third_party/blink/renderer/modules/url_pattern/url_pattern_component.cc @@ -92,10 +92,12 @@ liburlpattern::EncodeCallback GetEncodeCallback(Component::Type type, // Utility method to get the correct liburlpattern parse options for a given // type. const liburlpattern::Options& GetOptions(Component::Type type) { + using liburlpattern::Options; + // The liburlpattern::Options to use for most component patterns. We // default to strict mode and case sensitivity. In addition, most // components have no concept of a delimiter or prefix character. - DEFINE_THREAD_SAFE_STATIC_LOCAL(liburlpattern::Options, default_options, + DEFINE_THREAD_SAFE_STATIC_LOCAL(Options, default_options, ({.delimiter_list = "", .prefix_list = "", .sensitive = true, @@ -106,7 +108,7 @@ const liburlpattern::Options& GetOptions(Component::Type type) { // by default. Note, hostnames are case insensitive but we require case // sensitivity here. This assumes that the hostname values have already // been normalized to lower case as in URL(). - DEFINE_THREAD_SAFE_STATIC_LOCAL(liburlpattern::Options, hostname_options, + DEFINE_THREAD_SAFE_STATIC_LOCAL(Options, hostname_options, ({.delimiter_list = ".", .prefix_list = "", .sensitive = true, @@ -116,7 +118,7 @@ const liburlpattern::Options& GetOptions(Component::Type type) { // "/" delimiter controlling how far a named group like ":bar" will match // by default. It also configures "/" to be treated as an automatic // prefix before groups. - DEFINE_THREAD_SAFE_STATIC_LOCAL(liburlpattern::Options, pathname_options, + DEFINE_THREAD_SAFE_STATIC_LOCAL(Options, pathname_options, ({.delimiter_list = "/", .prefix_list = "/", .sensitive = true, @@ -138,6 +140,88 @@ const liburlpattern::Options& GetOptions(Component::Type type) { NOTREACHED(); } +// Utility function to return a statically allocated Part list. +const std::vector& GetWildcardOnlyPartList() { + using liburlpattern::Modifier; + using liburlpattern::Part; + using liburlpattern::PartType; + DEFINE_THREAD_SAFE_STATIC_LOCAL( + std::vector, instance, + ({Part(PartType::kFullWildcard, + /*name=*/"", + /*prefix=*/"", /*value=*/"", /*suffix=*/"", Modifier::kNone)})); + return instance; +} + +int ComparePart(const liburlpattern::Part& lh, const liburlpattern::Part& rh) { + // We prioritize PartType in the ordering so we can favor fixed text. The + // type ordering is: + // + // kFixed > kRegex > kSegmentWildcard > kFullWildcard. + // + // We considered kRegex greater than the wildcards because it is likely to be + // used for imposing some constraint and not just duplicating wildcard + // behavior. + // + // This comparison depends on the PartType enum in liburlpattern having the + // correct corresponding numeric values. + // + // Next the Modifier is considered: + // + // kNone > kOneOrMore > kOptional > kZeroOrMore. + // + // The rationale here is that requring the match group to exist is more + // restrictive then making it optional and requiring an exact count is more + // restrictive than repeating. + // + // This comparison depends on the Modifier enum in liburlpattern having the + // correct corresponding numeric values. + // + // Finally we lexicographically compare the text components from left to + // right; `prefix`, `value`, and `suffix`. Its ok to depend on simple + // byte-wise string comparison here because the values have all been URL + // encoded. This guarantees the strings contain only ASCII. + auto left = std::tie(lh.type, lh.modifier, lh.prefix, lh.value, lh.suffix); + auto right = std::tie(rh.type, rh.modifier, rh.prefix, rh.value, rh.suffix); + if (left < right) + return -1; + else if (left == right) + return 0; + else + return 1; +} + +// Utility method to compare two part lists. +int ComparePartList(const std::vector& lh, + const std::vector& rh) { + using liburlpattern::Modifier; + using liburlpattern::Part; + using liburlpattern::PartType; + + // Begin by comparing each Part in the lists with each other. If any + // are not equal, then we are done. + size_t i = 0; + for (; i < lh.size() && i < rh.size(); ++i) { + int r = ComparePart(lh[i], rh[i]); + if (r) + return r; + } + + // We reached the end of at least one of the lists without finding a + // difference. However, we must handle the case where one list is longer + // than the other. In this case we compare the next Part from the + // longer list to a synthetically created empty kFixed Part. This is + // necessary in order for "/foo/" to be considered more restrictive, and + // therefore greater, than "/foo/*". + if (i == lh.size() && i != rh.size()) + return ComparePart(Part(PartType::kFixed, "", Modifier::kNone), rh[i]); + else if (i != lh.size() && i == rh.size()) + return ComparePart(lh[i], Part(PartType::kFixed, "", Modifier::kNone)); + + // No differences were found, so declare them equal. + return 0; +} + } // anonymous namespace // static @@ -218,6 +302,31 @@ Component* Component::Compile(const String& pattern, std::move(wtf_name_list), base::PassKey()); } +// static +int Component::Compare(const Component& lh, const Component& rh) { + using liburlpattern::Modifier; + using liburlpattern::Part; + using liburlpattern::PartType; + + // If both the left and right components are empty wildcards, then they are + // effectively equal. + if (!lh.pattern_.has_value() && !rh.pattern_.has_value()) + return 0; + + // If one side has a real pattern and the other side is an empty component, + // then we have to compare to a part list with a single full wildcard. + if (lh.pattern_.has_value() && !rh.pattern_.has_value()) { + return ComparePartList(lh.pattern_->PartList(), GetWildcardOnlyPartList()); + } + + if (!lh.pattern_.has_value() && rh.pattern_.has_value()) { + return ComparePartList(GetWildcardOnlyPartList(), rh.pattern_->PartList()); + } + + // Otherwise compare the part lists of the patterns on each side. + return ComparePartList(lh.pattern_->PartList(), rh.pattern_->PartList()); +} + Component::Component(Type type, liburlpattern::Pattern pattern, ScriptRegexp* regexp, diff --git a/third_party/blink/renderer/modules/url_pattern/url_pattern_component.h b/third_party/blink/renderer/modules/url_pattern/url_pattern_component.h index f5793e04c2d79b..31ca11e1f6211c 100644 --- a/third_party/blink/renderer/modules/url_pattern/url_pattern_component.h +++ b/third_party/blink/renderer/modules/url_pattern/url_pattern_component.h @@ -52,6 +52,13 @@ class Component final : public GarbageCollected { Component* protocol_component, ExceptionState& exception_state); + // Compare the pattern strings in the two given components. This provides a + // mostly lexicographical ordering based on fixed text in the patterns. + // Matching groups and modifiers are treated such that more restrictive + // patterns are greater in value. Group names are not considered in the + // comparison. + static int Compare(const Component& lh, const Component& rh); + // Constructs a Component with a real `pattern` that compiled to the given // `regexp`. Component(Type type, diff --git a/third_party/blink/web_tests/external/wpt/urlpattern/resources/urlpattern-compare-test-data.json b/third_party/blink/web_tests/external/wpt/urlpattern/resources/urlpattern-compare-test-data.json new file mode 100644 index 00000000000000..54dd80a91a2348 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/urlpattern/resources/urlpattern-compare-test-data.json @@ -0,0 +1,116 @@ +[ + { + "component": "pathname", + "left": { "pathname": "/foo/a" }, + "right": { "pathname": "/foo/b" }, + "expected": -1 + }, + { + "component": "pathname", + "left": { "pathname": "/foo/b" }, + "right": { "pathname": "/foo/bar" }, + "expected": -1 + }, + { + "component": "pathname", + "left": { "pathname": "/foo/bar" }, + "right": { "pathname": "/foo/:bar" }, + "expected": 1 + }, + { + "component": "pathname", + "left": { "pathname": "/foo/" }, + "right": { "pathname": "/foo/:bar" }, + "expected": 1 + }, + { + "component": "pathname", + "left": { "pathname": "/foo/:bar" }, + "right": { "pathname": "/foo/*" }, + "expected": 1 + }, + { + "component": "pathname", + "left": { "pathname": "/foo/{bar}" }, + "right": { "pathname": "/foo/(bar)" }, + "expected": 1 + }, + { + "component": "pathname", + "left": { "pathname": "/foo/{bar}" }, + "right": { "pathname": "/foo/{bar}+" }, + "expected": 1 + }, + { + "component": "pathname", + "left": { "pathname": "/foo/{bar}+" }, + "right": { "pathname": "/foo/{bar}?" }, + "expected": 1 + }, + { + "component": "pathname", + "left": { "pathname": "/foo/{bar}?" }, + "right": { "pathname": "/foo/{bar}*" }, + "expected": 1 + }, + { + "component": "pathname", + "left": { "pathname": "/foo/(123)" }, + "right": { "pathname": "/foo/(12)" }, + "expected": 1 + }, + { + "component": "pathname", + "left": { "pathname": "/foo/:b" }, + "right": { "pathname": "/foo/:a" }, + "expected": 0 + }, + { + "component": "pathname", + "left": { "pathname": "*/foo" }, + "right": { "pathname": "*" }, + "expected": 1 + }, + { + "component": "port", + "left": { "port": "9" }, + "right": { "port": "100" }, + "expected": 1 + }, + { + "component": "pathname", + "left": { "pathname": "foo/:bar?/baz" }, + "right": { "pathname": "foo/{:bar}?/baz" }, + "expected": -1 + }, + { + "component": "pathname", + "left": { "pathname": "foo/:bar?/baz" }, + "right": { "pathname": "foo{/:bar}?/baz" }, + "expected": 0 + }, + { + "component": "pathname", + "left": { "pathname": "foo/:bar?/baz" }, + "right": { "pathname": "fo{o/:bar}?/baz" }, + "expected": 1 + }, + { + "component": "pathname", + "left": { "pathname": "foo/:bar?/baz" }, + "right": { "pathname": "foo{/:bar/}?baz" }, + "expected": -1 + }, + { + "component": "pathname", + "left": "https://a.example.com/b?a", + "right": "https://b.example.com/a?b", + "expected": 1 + }, + { + "component": "pathname", + "left": { "pathname": "/foo/{bar}/baz" }, + "right": { "pathname": "/foo/bar/baz" }, + "expected": 0 + } +] diff --git a/third_party/blink/web_tests/external/wpt/urlpattern/resources/urlpattern-compare-tests.js b/third_party/blink/web_tests/external/wpt/urlpattern/resources/urlpattern-compare-tests.js new file mode 100644 index 00000000000000..b92b53ee45cd98 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/urlpattern/resources/urlpattern-compare-tests.js @@ -0,0 +1,26 @@ +function runTests(data) { + for (let entry of data) { + test(function() { + const left = new URLPattern(entry.left); + const right = new URLPattern(entry.right); + + assert_equals(URLPattern.compareComponent(entry.component, left, right), entry.expected); + + // We have to coerce to an integer here in order to avoid asserting + // that `+0` is `-0`. + const reverse_expected = ~~(entry.expected * -1); + assert_equals(URLPattern.compareComponent(entry.component, right, left), reverse_expected, "reverse order"); + + assert_equals(URLPattern.compareComponent(entry.component, left, left), 0, "left equality"); + assert_equals(URLPattern.compareComponent(entry.component, right, right), 0, "right equality"); + }, `Component: ${entry.component} ` + + `Left: ${JSON.stringify(entry.left)} ` + + `Right: ${JSON.stringify(entry.right)}`); + } +} + +promise_test(async function() { + const response = await fetch('resources/urlpattern-compare-test-data.json'); + const data = await response.json(); + runTests(data); +}, 'Loading data...'); diff --git a/third_party/blink/web_tests/external/wpt/urlpattern/urlpattern-compare.any.js b/third_party/blink/web_tests/external/wpt/urlpattern/urlpattern-compare.any.js new file mode 100644 index 00000000000000..8db38adfd41d47 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/urlpattern/urlpattern-compare.any.js @@ -0,0 +1,2 @@ +// META: global=window,worker +// META: script=resources/urlpattern-compare-tests.js diff --git a/third_party/blink/web_tests/external/wpt/urlpattern/urlpattern-compare.https.any.js b/third_party/blink/web_tests/external/wpt/urlpattern/urlpattern-compare.https.any.js new file mode 100644 index 00000000000000..8db38adfd41d47 --- /dev/null +++ b/third_party/blink/web_tests/external/wpt/urlpattern/urlpattern-compare.https.any.js @@ -0,0 +1,2 @@ +// META: global=window,worker +// META: script=resources/urlpattern-compare-tests.js diff --git a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt index 9b56893def9570..b5a4908bcf22c1 100644 --- a/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt +++ b/third_party/blink/web_tests/http/tests/serviceworker/webexposed/global-interface-listing-service-worker-expected.txt @@ -1611,6 +1611,7 @@ interface URL setter search setter username interface URLPattern + static method compareComponent attribute @@toStringTag getter hash getter hostname diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt index 2a79ce4d021393..4012bf329884b3 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-dedicated-worker-expected.txt @@ -1673,6 +1673,7 @@ Starting worker: resources/global-interface-listing-worker.js [Worker] setter search [Worker] setter username [Worker] interface URLPattern +[Worker] static method compareComponent [Worker] attribute @@toStringTag [Worker] getter hash [Worker] getter hostname diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt index c83c9e3d1eb070..b19ef5cfb653f8 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-expected.txt @@ -8873,6 +8873,7 @@ interface URL setter search setter username interface URLPattern + static method compareComponent attribute @@toStringTag getter hash getter hostname diff --git a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt index cf4e0f86d6388e..09829a21f85492 100644 --- a/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt +++ b/third_party/blink/web_tests/webexposed/global-interface-listing-shared-worker-expected.txt @@ -1488,6 +1488,7 @@ Starting worker: resources/global-interface-listing-worker.js [Worker] setter search [Worker] setter username [Worker] interface URLPattern +[Worker] static method compareComponent [Worker] attribute @@toStringTag [Worker] getter hash [Worker] getter hostname diff --git a/third_party/liburlpattern/pattern.cc b/third_party/liburlpattern/pattern.cc index 52d78bc538354a..6b996f2072f762 100644 --- a/third_party/liburlpattern/pattern.cc +++ b/third_party/liburlpattern/pattern.cc @@ -15,28 +15,28 @@ namespace { void AppendModifier(Modifier modifier, std::string& append_target) { switch (modifier) { - case Modifier::kNone: + case Modifier::kZeroOrMore: + append_target += '*'; break; case Modifier::kOptional: append_target += '?'; break; - case Modifier::kZeroOrMore: - append_target += '*'; - break; case Modifier::kOneOrMore: append_target += '+'; break; + case Modifier::kNone: + break; } } size_t ModifierLength(Modifier modifier) { switch (modifier) { - case Modifier::kNone: - return 0; - case Modifier::kOptional: case Modifier::kZeroOrMore: + case Modifier::kOptional: case Modifier::kOneOrMore: return 1; + case Modifier::kNone: + return 0; } } diff --git a/third_party/liburlpattern/pattern.h b/third_party/liburlpattern/pattern.h index 523bb8f12e7523..b5ec74e091c83f 100644 --- a/third_party/liburlpattern/pattern.h +++ b/third_party/liburlpattern/pattern.h @@ -13,33 +13,37 @@ namespace liburlpattern { +// Numeric values are set such that more restrictive values come last. This +// is important for comparison routines in calling code, like URLPattern. enum class PartType { - // A fixed, non-variable part of the pattern. Consists of kChar and - // kEscapedChar Tokens. - kFixed, - - // A part with a custom regular expression. - kRegex, + // A part that matches any character to the end of the input string. + kFullWildcard = 0, // A part that matches any character to the next segment separator. - kSegmentWildcard, + kSegmentWildcard = 1, - // A part that matches any character to the end of the input string. - kFullWildcard, + // A part with a custom regular expression. + kRegex = 2, + + // A fixed, non-variable part of the pattern. Consists of kChar and + // kEscapedChar Tokens. + kFixed = 3, }; +// Numeric values are set such that more restrictive values come last. This +// is important for comparison routines in calling code, like URLPattern. enum class Modifier { - // No modifier. - kNone, + // The `*` modifier. + kZeroOrMore = 0, // The `?` modifier. - kOptional, - - // The `*` modifier. - kZeroOrMore, + kOptional = 1, // The `+` modifier. - kOneOrMore, + kOneOrMore = 2, + + // No modifier. + kNone = 3, }; // A structure representing one part of a parsed Pattern. A full Pattern diff --git a/tools/metrics/histograms/enums.xml b/tools/metrics/histograms/enums.xml index 932a265ad14642..4b623051370e32 100644 --- a/tools/metrics/histograms/enums.xml +++ b/tools/metrics/histograms/enums.xml @@ -33995,6 +33995,7 @@ Called by update_use_counter_feature_enum.py.--> +