Match selectors inside ShadowRoot trees
This commit is contained in:
1 parent
a4a3ea49ba
commit
6fdcd19898
4 files changed
+33
-9
No files matched your search
@@ -743,6 +743,29 @@ impl DomTree {
|
||||
Ok(results)
|
||||
}
|
||||
|
||||
/// Test one element as the selector subject, including when it is
|
||||
/// detached or is a direct child of a shadow-tree compatibility root.
|
||||
pub fn matches_selector(&self, nid: NodeId, selector: &str) -> Result<bool, String> {
|
||||
if !self.with_node(nid, |node| node.is_element()).unwrap_or(false) {
|
||||
return Ok(false);
|
||||
}
|
||||
let selector_list = parse_selector(selector)?;
|
||||
let mut caches = selectors::context::SelectorCaches::default();
|
||||
let mut context = MatchingContext::new(
|
||||
MatchingMode::Normal,
|
||||
None,
|
||||
&mut caches,
|
||||
QuirksMode::NoQuirks,
|
||||
NeedsSelectorFlags::No,
|
||||
MatchingForInvalidation::No,
|
||||
);
|
||||
Ok(selectors::matching::matches_selector_list(
|
||||
&selector_list,
|
||||
&DomElement::new(self, nid),
|
||||
&mut context,
|
||||
))
|
||||
}
|
||||
|
||||
/// Parse a single selector once for repeated single-element matching, and
|
||||
/// precompute its specificity, ancestor hashes, and "subject key" (the
|
||||
/// rightmost id/class/tag used to bucket the rule for fast candidate
|
||||
|
||||
Vendored
+1
-7
@@ -2059,13 +2059,7 @@ class Element extends Node {
|
||||
if (rest === "") return true;
|
||||
return this.matches(rest);
|
||||
}
|
||||
const parent = this.parentNode;
|
||||
if (!parent || !parent.querySelectorAll) return false;
|
||||
const matches = parent.querySelectorAll(s);
|
||||
for (let i = 0; i < matches.length; i++) {
|
||||
if (matches[i]._nid === this._nid) return true;
|
||||
}
|
||||
return false;
|
||||
return _dom("matches_selector", this._nid, String(s)) === "true";
|
||||
}
|
||||
closest(s) {
|
||||
let el = this;
|
||||
|
||||
@@ -288,6 +288,10 @@ fn op_dom_inner(state: &OpState, cmd: String, arg1: String, arg2: String) -> Str
|
||||
.map(|ids| ids.iter().map(|id| id.index() as i32).collect()).unwrap_or_default();
|
||||
serde_json::to_string(&ids).unwrap_or("[]".into())
|
||||
}
|
||||
"matches_selector" => {
|
||||
let nid = NodeId::new(arg1.parse::<u32>().unwrap_or(0));
|
||||
dom.matches_selector(nid, &arg2).unwrap_or(false).to_string()
|
||||
}
|
||||
"node_type" => {
|
||||
let nid = arg1.parse::<u32>().unwrap_or(0);
|
||||
dom.with_node(NodeId::new(nid), |n| match &n.data {
|
||||
|
||||
@@ -1991,7 +1991,10 @@ mod tests {
|
||||
const parsed = [
|
||||
inside.parentNode === root,
|
||||
inside.getRootNode() === root,
|
||||
root.textContent
|
||||
root.textContent,
|
||||
inside.matches("span#inside"),
|
||||
root.querySelector("span#inside") === inside,
|
||||
root.querySelectorAll("span#inside").length === 1
|
||||
];
|
||||
|
||||
const a = document.createElement("a");
|
||||
@@ -2059,7 +2062,7 @@ mod tests {
|
||||
],
|
||||
[true, true, true],
|
||||
[true, true, true],
|
||||
[true, true, "inside"],
|
||||
[true, true, "inside", true, true, true],
|
||||
["b", "a", "i"],
|
||||
[["b", "a", "x-one", "x-two", "i"], 0, true, true],
|
||||
[["a", "x-one", "x-two", "b"], true, true],
|
||||
|
||||
Reference in new issue
Block a user