/* This Source Code Form is subject to the terms of the Mozilla Public *License,v.2.0.IfacopyoftheMPLwasnotdistributedwiththis
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
externcrate nsstring; use nsstring::nsACString; use nsstring::nsCString; use thin_vec::ThinVec;
use std::ptr; use url::Url; use urlpattern::parser::RegexSyntax; use urlpattern::quirks; use urlpattern::regexp::RegExp;
// Implement drop so that when dom::URLPattern goes out of scope // urlpattern_pattern_free() also triggers urlpattern::URLPattern<R> to drop. // When the pattern's inner regexp goes with it, this drop will cleanup the // spidermonkey regexp obj impl Drop for SpiderMonkeyRegexp { fn drop(&mutself) { unsafe {
free_regexp_ffi(self.1);
}
}
}
fn matches<'a>(&self, text: &'a str) -> Option<Vec<Option<&'a str>>> { // bit of a hack because protocol_component_matches_special_scheme // needs to know if the result of spidermonkey_matches is none or some // during pattern construction to check if protocol matches special schemes. // as such this method is not used in firefox for actual matching // actual URL matching uses matcher_matches let matches = spidermonkey_regexp_matches(self, text, false); if matches.is_some() { let dummy_vec = vec![None]; return Some(dummy_vec);
}
None
}
// early exit if the regex matching failed to run or if it wasn't a match if !success || !match_result { return None;
}
// copy strings to rust-interface type letmut rust_results = Vec::new(); for i in0..results.len() { let maybe_str = &results[i]; // Check if this capture group matched (valid == true) if maybe_str.valid {
rust_results.push(Some(maybe_str.string.to_owned().to_string()));
} else {
rust_results.push(None);
}
}
Some(rust_results)
}
// performs the match on the inner matcher of a component with a given input string // this function was adapted from // https://github.com/denoland/rust-urlpattern/blob/main/src/matcher.rs pubfn matcher_matches<'a>(
matcher: *mut UrlPatternMatcherPtr, mut input: &'a str,
match_only: bool,
) -> Option<Vec<Option<String>>> { let matcher: &Matcher = unsafe { &*(matcher as *const _ as *const Matcher) }; let prefix_len = matcher.prefix.len(); let suffix_len = matcher.suffix.len(); let input_len = input.len(); let ignore_case = matcher.ignore_case;
if prefix_len + suffix_len > 0 { // The input must be at least as long as the prefix and suffix combined, // because these must both be present, and not overlap. if input_len < prefix_len + suffix_len { return None;
} if !input.starts_with(&matcher.prefix) { return None;
} if !input.ends_with(&matcher.suffix) { return None;
}
InnerMatcher::SingleCapture {
filter,
allow_empty,
} => { if input.is_empty() && !allow_empty { return None;
} iflet Some(filter) = filter { if ignore_case { if input
.to_lowercase()
.contains(filter.to_lowercase().collect::<Vec<_>>().as_slice())
{ return None;
}
} elseif input.contains(*filter) { return None;
}
}
Some(vec![Some(input.to_string())])
}
InnerMatcher::RegExp { regexp, .. } => { // regexp can be an error result here if an invalid regexp string // was passed to the regexp constructor. This can happen in the crate // during parsing of the URLPattern string input into Init because // the parser requires knowing if the protocol provided is // special, so we compile AND match on the protocol component // pre-emptively. Perhaps, we could detect regexp obj error slightly // earlier, immediately after component compilation, but both ways // the error bubbles up the same to the glue in // init_from_string_and_base_url
// ignore_case not needed here because the regexp was already // compiled with the correct flags. spidermonkey_matches uses the // pre-compiled regexp which has the flags baked in. let matches = spidermonkey_regexp_matches(regexp.as_ref().ok()?, input, match_only)?;
Some(
matches
.into_iter()
.map(|opt| opt.map(|s| s.to_string()))
.collect(),
)
}
}
}
// convert from glue::UrlPatternInit to urlpattern::UrlPatternInit, used by: // * parse_pattern_from_string // * parse_pattern_from_init impl From<UrlPatternInit> for urlpattern::UrlPatternInit { fn from(wrapper: UrlPatternInit) -> urlpattern::UrlPatternInit { let maybe_base = if wrapper.base_url.valid { let s = wrapper.base_url.string.to_string().to_owned(); if s.is_empty() {
None
} else {
Url::parse(s.as_str()).ok()
}
} else {
None
};
urlpattern::UrlPatternInit {
protocol: maybe_to_option_string(&wrapper.protocol),
username: maybe_to_option_string(&wrapper.username),
password: maybe_to_option_string(&wrapper.password),
hostname: maybe_to_option_string(&wrapper.hostname),
port: maybe_to_option_string(&wrapper.port),
pathname: maybe_to_option_string(&wrapper.pathname),
search: maybe_to_option_string(&wrapper.search),
hash: maybe_to_option_string(&wrapper.hash),
base_url: maybe_base,
}
}
}
impl From<&UrlPatternInit> for urlpattern::UrlPatternInit { fn from(wrapper: &UrlPatternInit) -> urlpattern::UrlPatternInit { let maybe_base = if wrapper.base_url.valid { let s = wrapper.base_url.string.to_string().to_owned(); if s.is_empty() {
None
} else {
Url::parse(s.as_str()).ok()
}
} else {
None
};
urlpattern::UrlPatternInit {
protocol: maybe_to_option_string(&wrapper.protocol),
username: maybe_to_option_string(&wrapper.username),
password: maybe_to_option_string(&wrapper.password),
hostname: maybe_to_option_string(&wrapper.hostname),
port: maybe_to_option_string(&wrapper.port),
pathname: maybe_to_option_string(&wrapper.pathname),
search: maybe_to_option_string(&wrapper.search),
hash: maybe_to_option_string(&wrapper.hash),
base_url: maybe_base,
}
}
}
// convert from glue::UrlPatternInit to quirks::UrlPatternInit // used by parse_pattern into the internal function // MatchInput `From` conversion also uses impl From<UrlPatternInit> for quirks::UrlPatternInit { fn from(wrapper: UrlPatternInit) -> quirks::UrlPatternInit { let maybe_base = if wrapper.base_url.valid {
Some(wrapper.base_url.string.to_string())
} else {
None
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.