pub struct Translator { /* private fields */ }Expand description
A reusable translator for one Mode, optionally carrying a
default namespace prefix.
Every flavour difference — which pseudo-class overrides apply,
whether names are ASCII-lowercased, where :lang() reads from — is
derived from the mode by the private accessors below. Casing is
applied here in the translator, never via Servo’s parser settings.
Default is Mode::Generic with no default namespace: the plain
translator, the same as Translator::new(Mode::Generic).
Implementations§
Source§impl Translator
impl Translator
Sourcepub const fn new(mode: Mode) -> Self
pub const fn new(mode: Mode) -> Self
Build a translator for one of the three Mode flavours, with
no default namespace — see
Translator::with_default_namespace_prefix.
The result is immutable and holds no per-selector state, so a single translator can be reused for any number of translations.
Sourcepub fn with_default_namespace_prefix(
self,
prefix: impl Into<Cow<'static, str>>,
) -> Self
pub fn with_default_namespace_prefix( self, prefix: impl Into<Cow<'static, str>>, ) -> Self
Put unprefixed type selectors in a default namespace, the way a
stylesheet’s @namespace url(…) does.
This crate never sees namespace URLs, so the default namespace is
named by the prefix the emitted XPath should use — one the
caller’s namespace map binds, exactly as a written h|p prefix
would be:
use css_to_xpath::{Mode, Translator};
let t = Translator::new(Mode::Xhtml).with_default_namespace_prefix("h");
assert_eq!(t.css_to_xpath("body > p", "").unwrap(), "h:body/h:p");
assert_eq!(t.css_to_xpath("p:is(a, b)", "").unwrap(), "h:p[self::h:a or self::h:b]");The semantics are the CSS Namespaces 3 ones. A default namespace
applies to type selectors and to the implicit universal selector
of a compound that has none (.c becomes h:*[…], * becomes
h:*), but never to attribute selectors — an unprefixed
attribute name has no namespace by definition. |e still means
“no namespace” and *|e still means “any namespace”; and, per
Selectors Level 4, the implicit universal selector of an
:is() / :where() / :not() argument is not qualified, so
:is(p) picks up the default namespace but :is(.c) does not.
The prefix is checked exactly as a written one is, when the
translation reaches it: one that is not a usable XPath name is an
Error rather than a guess. An empty prefix means no default
namespace.
Sourcepub fn default_namespace_prefix(&self) -> Option<&str>
pub fn default_namespace_prefix(&self) -> Option<&str>
The default namespace prefix set by
Translator::with_default_namespace_prefix, if any.
Sourcepub fn css_to_xpath(&self, css: &str, prefix: &str) -> Result<String, Error>
pub fn css_to_xpath(&self, css: &str, prefix: &str) -> Result<String, Error>
Translate comma-separated selector groups, each prefixed, joined with “ | “.
prefix is prepended verbatim to every selector-group branch, so
it must end in something a node test can follow: an axis
("descendant-or-self::", crate::DESCENDANT_OR_SELF) or a
step separator ("//", crate::WHOLE_DOCUMENT). Pass "" for
a bare relative expression. Nothing validates it — a prefix like
"/html/body " yields /html/body div, which XPath reads as a
division, not a path.
A selector group anchored on :scope ignores prefix and
anchors on the self:: axis instead, since :scope names the
context node the XPath is evaluated from.
§Errors
Returns an Error when the selector is syntactically invalid
or uses an unsupported construct.