Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bump cssparser to 0.28 and selectors to 0.23. #99

Merged
merged 1 commit into from Jan 10, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.toml
Expand Up @@ -15,11 +15,11 @@ repository = "https://github.com/causal-agent/scraper"
readme = "README.md"

[dependencies]
cssparser = "0.27"
cssparser = "0.28"
ego-tree = "0.6.2"
html5ever = "0.26"
matches = "0.1.9"
selectors = "0.22.0"
selectors = "0.23.0"
smallvec = "1.9.0"
tendril = "0.4.3"
indexmap = { version = "1.9.1", optional = true }
Expand Down
49 changes: 24 additions & 25 deletions src/element_ref/element.rs
@@ -1,10 +1,10 @@
use html5ever::{LocalName, Namespace};
use html5ever::Namespace;
use selectors::attr::{AttrSelectorOperation, CaseSensitivity, NamespaceConstraint};
use selectors::matching;
use selectors::{Element, OpaqueElement};

use super::ElementRef;
use crate::selector::{NonTSPseudoClass, PseudoElement, Simple};
use crate::selector::{CssLocalName, CssString, NonTSPseudoClass, PseudoElement, Simple};

/// Note: will never match against non-tree-structure pseudo-classes.
impl<'a> Element for ElementRef<'a> {
Expand All @@ -30,19 +30,15 @@ impl<'a> Element for ElementRef<'a> {
false
}

fn is_part(&self, _name: &LocalName) -> bool {
fn is_part(&self, _name: &CssLocalName) -> bool {
false
}

fn is_same_type(&self, other: &Self) -> bool {
self.value().name == other.value().name
}

fn exported_part(&self, _: &LocalName) -> Option<LocalName> {
None
}

fn imported_part(&self, _: &LocalName) -> Option<LocalName> {
fn imported_part(&self, _: &CssLocalName) -> Option<CssLocalName> {
None
}

Expand All @@ -63,8 +59,8 @@ impl<'a> Element for ElementRef<'a> {
self.value().name.ns == ns!(html)
}

fn has_local_name(&self, name: &LocalName) -> bool {
&self.value().name.local == name
fn has_local_name(&self, name: &CssLocalName) -> bool {
self.value().name.local == name.0
}

fn has_namespace(&self, namespace: &Namespace) -> bool {
Expand All @@ -74,12 +70,12 @@ impl<'a> Element for ElementRef<'a> {
fn attr_matches(
&self,
ns: &NamespaceConstraint<&Namespace>,
local_name: &LocalName,
operation: &AttrSelectorOperation<&String>,
local_name: &CssLocalName,
operation: &AttrSelectorOperation<&CssString>,
) -> bool {
self.value().attrs.iter().any(|(key, value)| {
!matches!(*ns, NamespaceConstraint::Specific(url) if *url != key.ns)
&& *local_name == key.local
&& local_name.0 == key.local
&& operation.eval_str(value)
})
}
Expand Down Expand Up @@ -109,15 +105,15 @@ impl<'a> Element for ElementRef<'a> {
true
}

fn has_id(&self, id: &LocalName, case_sensitivity: CaseSensitivity) -> bool {
fn has_id(&self, id: &CssLocalName, case_sensitivity: CaseSensitivity) -> bool {
match self.value().id {
Some(ref val) => case_sensitivity.eq(id.as_bytes(), val.as_bytes()),
Some(ref val) => case_sensitivity.eq(id.0.as_bytes(), val.as_bytes()),
None => false,
}
}

fn has_class(&self, name: &LocalName, case_sensitivity: CaseSensitivity) -> bool {
self.value().has_class(name, case_sensitivity)
fn has_class(&self, name: &CssLocalName, case_sensitivity: CaseSensitivity) -> bool {
self.value().has_class(&name.0, case_sensitivity)
}

fn is_empty(&self) -> bool {
Expand All @@ -135,14 +131,12 @@ impl<'a> Element for ElementRef<'a> {
#[cfg(test)]
mod tests {
use crate::html::Html;
use crate::selector::Selector;
use crate::selector::{CssLocalName, Selector};
use selectors::attr::CaseSensitivity;
use selectors::Element;

#[test]
fn test_has_id() {
use html5ever::LocalName;

let html = "<p id='link_id_456'>hey there</p>";
let fragment = Html::parse_fragment(html);
let sel = Selector::parse("p").unwrap();
Expand All @@ -151,7 +145,7 @@ mod tests {
assert_eq!(
true,
element.has_id(
&LocalName::from("link_id_456"),
&CssLocalName::from("link_id_456"),
CaseSensitivity::CaseSensitive
)
);
Expand All @@ -162,7 +156,7 @@ mod tests {
assert_eq!(
false,
element.has_id(
&LocalName::from("any_link_id"),
&CssLocalName::from("any_link_id"),
CaseSensitivity::CaseSensitive
)
);
Expand All @@ -185,14 +179,16 @@ mod tests {

#[test]
fn test_has_class() {
use html5ever::LocalName;
let html = "<p class='my_class'>hey there</p>";
let fragment = Html::parse_fragment(html);
let sel = Selector::parse("p").unwrap();
let element = fragment.select(&sel).next().unwrap();
assert_eq!(
true,
element.has_class(&LocalName::from("my_class"), CaseSensitivity::CaseSensitive)
element.has_class(
&CssLocalName::from("my_class"),
CaseSensitivity::CaseSensitive
)
);

let html = "<p>hey there</p>";
Expand All @@ -201,7 +197,10 @@ mod tests {
let element = fragment.select(&sel).next().unwrap();
assert_eq!(
false,
element.has_class(&LocalName::from("my_class"), CaseSensitivity::CaseSensitive)
element.has_class(
&CssLocalName::from("my_class"),
CaseSensitivity::CaseSensitive
)
);
}
}
73 changes: 50 additions & 23 deletions src/selector.rs
Expand Up @@ -7,7 +7,7 @@ use smallvec::SmallVec;

use html5ever::{LocalName, Namespace};
use selectors::parser::SelectorParseErrorKind;
use selectors::{matching, parser, visitor};
use selectors::{matching, parser};

use crate::error::SelectorErrorKind;
use crate::ElementRef;
Expand Down Expand Up @@ -67,15 +67,13 @@ impl<'i> parser::Parser<'i> for Parser {
pub struct Simple;

impl parser::SelectorImpl for Simple {
type AttrValue = String;
type Identifier = LocalName;
type ClassName = LocalName;
type PartName = LocalName;
type LocalName = LocalName;
type NamespacePrefix = LocalName;
type AttrValue = CssString;
type Identifier = CssLocalName;
type LocalName = CssLocalName;
type NamespacePrefix = CssLocalName;
type NamespaceUrl = Namespace;
type BorrowedNamespaceUrl = Namespace;
type BorrowedLocalName = LocalName;
type BorrowedLocalName = CssLocalName;

type NonTSPseudoClass = NonTSPseudoClass;
type PseudoElement = PseudoElement;
Expand All @@ -84,6 +82,50 @@ impl parser::SelectorImpl for Simple {
type ExtraMatchingData = String;
}

/// Wraps [`String`] so that it can be used with [`selectors`]
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CssString(pub String);

impl<'a> From<&'a str> for CssString {
fn from(val: &'a str) -> Self {
Self(val.to_owned())
}
}

impl AsRef<str> for CssString {
fn as_ref(&self) -> &str {
&self.0
}
}

impl cssparser::ToCss for CssString {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
where
W: fmt::Write,
{
cssparser::serialize_string(&self.0, dest)
}
}

/// Wraps [`LocalName`] so that it can be used with [`selectors`]
#[derive(Debug, Default, Clone, PartialEq, Eq)]
pub struct CssLocalName(pub LocalName);

impl<'a> From<&'a str> for CssLocalName {
fn from(val: &'a str) -> Self {
Self(val.into())
}
}

impl cssparser::ToCss for CssLocalName {
fn to_css<W>(&self, dest: &mut W) -> fmt::Result
where
W: fmt::Write,
{
dest.write_str(&self.0)
}
}

/// Non Tree-Structural Pseudo-Class.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum NonTSPseudoClass {}
Expand All @@ -98,21 +140,6 @@ impl parser::NonTSPseudoClass for NonTSPseudoClass {
fn is_user_action_state(&self) -> bool {
false
}

fn has_zero_specificity(&self) -> bool {
false
}
}

impl parser::Visit for NonTSPseudoClass {
type Impl = Simple;

fn visit<V>(&self, _visitor: &mut V) -> bool
where
V: visitor::SelectorVisitor<Impl = Self::Impl>,
{
true
}
}

impl cssparser::ToCss for NonTSPseudoClass {
Expand Down