Skip to content

Commit

Permalink
feat(urlpattern): add ignoreCase option & hasRegExpGroups property, a…
Browse files Browse the repository at this point in the history
…nd fix spec discrepancies (#24741)

Fixes #20906
Fixes #24266
Closes #21073

---------

Signed-off-by: Leo Kettmeir <crowlkats@toaxl.com>
Co-authored-by: Luca Casonato <lucacasonato@yahoo.com>
  • Loading branch information
crowlKats and lucacasonato authored Aug 5, 2024
1 parent 3f79db1 commit 27ea23e
Show file tree
Hide file tree
Showing 5 changed files with 65 additions and 358 deletions.
9 changes: 4 additions & 5 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

65 changes: 56 additions & 9 deletions ext/url/01_urlpattern.js
Original file line number Diff line number Diff line change
Expand Up @@ -137,33 +137,65 @@ class SampledLRUCache {

const matchInputCache = new SampledLRUCache(4096);

const _hasRegExpGroups = Symbol("[[hasRegExpGroups]]");

class URLPattern {
/** @type {Components} */
[_components];
[_hasRegExpGroups];

#reusedResult;

/**
* @param {URLPatternInput} input
* @param {string} [baseURL]
* @param {string} [baseURLOrOptions]
* @param {string} [maybeOptions]
*/
constructor(input, baseURL = undefined) {
constructor(
input,
baseURLOrOptions = undefined,
maybeOptions = undefined,
) {
this[webidl.brand] = webidl.brand;
const prefix = "Failed to construct 'URLPattern'";
webidl.requiredArguments(arguments.length, 1, prefix);
input = webidl.converters.URLPatternInput(input, prefix, "Argument 1");
if (baseURL !== undefined) {
baseURL = webidl.converters.USVString(baseURL, prefix, "Argument 2");

let baseURL;
let options;
if (webidl.type(baseURLOrOptions) === "String") {
webidl.requiredArguments(arguments.length, 1, prefix);
input = webidl.converters.URLPatternInput(input, prefix, "Argument 1");
baseURL = webidl.converters.USVString(
baseURLOrOptions,
prefix,
"Argument 2",
);
options = webidl.converters.URLPatternOptions(
maybeOptions !== undefined ? maybeOptions : { __proto: null },
prefix,
"Argument 3",
);
} else {
if (input !== undefined) {
input = webidl.converters.URLPatternInput(input, prefix, "Argument 1");
} else {
input = { __proto__: null };
}
options = webidl.converters.URLPatternOptions(
maybeOptions,
prefix,
"Argument 2",
);
}

const components = op_urlpattern_parse(input, baseURL);
const components = op_urlpattern_parse(input, baseURL, options);
this[_hasRegExpGroups] = components.hasRegexpGroups;

for (let i = 0; i < COMPONENTS_KEYS.length; ++i) {
const key = COMPONENTS_KEYS[i];
try {
components[key].regexp = new SafeRegExp(
components[key].regexpString,
"u",
options.ignoreCase ? "ui" : "u",
);
} catch (e) {
throw new TypeError(`${prefix}: ${key} is invalid; ${e.message}`);
Expand Down Expand Up @@ -212,6 +244,11 @@ class URLPattern {
return this[_components].hash.patternString;
}

get hasRegExpGroups() {
webidl.assertBranded(this, URLPatternPrototype);
return this[_hasRegExpGroups];
}

/**
* @param {URLPatternInput} input
* @param {string} [baseURL]
Expand Down Expand Up @@ -312,7 +349,7 @@ class URLPattern {
const groups = res.groups;
for (let i = 0; i < groupList.length; ++i) {
// TODO(lucacasonato): this is vulnerable to override mistake
groups[groupList[i]] = match[i + 1] ?? "";
groups[groupList[i]] = match[i + 1];
}
break;
}
Expand Down Expand Up @@ -344,6 +381,7 @@ class URLPattern {
"pathname",
"search",
"hash",
"hasRegExpGroups",
],
}),
inspectOptions,
Expand Down Expand Up @@ -375,4 +413,13 @@ webidl.converters["URLPatternInput"] = (V, prefix, context, opts) => {
return webidl.converters.USVString(V, prefix, context, opts);
};

webidl.converters.URLPatternOptions = webidl
.createDictionaryConverter("URLPatternOptions", [
{
key: "ignoreCase",
converter: webidl.converters.boolean,
defaultValue: false,
},
]);

export { URLPattern };
2 changes: 1 addition & 1 deletion ext/url/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ path = "lib.rs"

[dependencies]
deno_core.workspace = true
urlpattern = "0.2.0"
urlpattern = "0.3.0"

[dev-dependencies]
deno_bench_util.workspace = true
Expand Down
3 changes: 2 additions & 1 deletion ext/url/urlpattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,15 @@ use urlpattern::quirks::UrlPattern;
pub fn op_urlpattern_parse(
#[serde] input: StringOrInit,
#[string] base_url: Option<String>,
#[serde] options: urlpattern::UrlPatternOptions,
) -> Result<UrlPattern, AnyError> {
let init = urlpattern::quirks::process_construct_pattern_input(
input,
base_url.as_deref(),
)
.map_err(|e| type_error(e.to_string()))?;

let pattern = urlpattern::quirks::parse_pattern(init)
let pattern = urlpattern::quirks::parse_pattern(init, options)
.map_err(|e| type_error(e.to_string()))?;

Ok(pattern)
Expand Down
Loading

0 comments on commit 27ea23e

Please sign in to comment.