Auto merge of #14043 - servo:string-cache-up, r=nox

Update to string-cache 0.3

Previously, `string-cache` defined:
*  An string-like `Atom` type,
* An `atom!("foo")` macro that expands to a value of that type, for a set of strings known at compile-time,
* A `struct Namespace(Atom);` type
* A `ns!(html)` macro that maps known prefixed to `Namespace` values with the corresponding namespace URL.

Adding a string to the static set required making a change to the `string-cache` crate.

With 0.3, the `Atom` type is now generic, with a type parameter that provides a set of static strings. We can have multiple such sets, defined in different crates. The `string_cache_codegen` crate, to be used in build scripts, generates code that defines such a set, a new atom type (a type alias for `Atom<_>` with the type parameter set), and an `atom!`-like macro.

The html5ever repository has a new `html5ever_atoms` crate that defines three such types: `Prefix`, `Namespace`, and `LocalName` (with respective `namespace_prefix!`, `namespace_url!`, and `local_name!` macros). It also defines the `ns!` macro like before.

This repository has a new `servo_atoms` crate in `components/atoms` that, for now, defines a single `Atom` type (and `atom!`) macro. (`servo_atoms::Atom` is defined as something like `type Atom = string_cache::Atom<ServoStaticStringSet>;`, so overall there’s now two types named `Atom`.)

In this PR, `servo_atoms::Atom` is used for everything else that was `string_cache::Atom` before. But more atom types can be defined as needed. Two reasons to do this are to auto-generate the set of static strings (I’m planning to do this for CSS property names, which is the motivation for this change), or to have the type system help us avoid mix up unrelated things (this is why we had a `Namespace` type ever before this change).

Introducing new types helped me find a bug: when creating a new attribute `dom::Element::set_style_attr`, would pass `Some(atom!("style"))` instead of `None` (now `Option<html5ever_atoms::Prefix>` instead of `Option<string_cache::Atom>`) to the `prefix` argument of `Attr::new`. I suppose the author of that code confused it with the `local_name` argument.

---

Note that Stylo is not affected by any of this. The `gecko_string_cache` module is unchanged, with a single `Atom` type. The `style` crate conditionally compiles `Prefix` and `LocalName` re-exports for that are both `gecko_string_cache::Atom` on stylo.

---
<!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: -->
- [x] `./mach build -d` does not report any errors
- [x] `./mach test-tidy` does not report any errors
- [ ] These changes fix #__ (github issue number if applicable).

<!-- Either: -->
- [ ] There are tests for these changes OR
- [ ] These changes do not require tests because _____

<!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. -->

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/14043)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2016-11-03 11:19:44 -05:00 committed by GitHub
commit 5b4cc9568d
170 changed files with 1309 additions and 1050 deletions

View file

@ -15,7 +15,7 @@ doctest = false
[features]
gecko = ["nsstring_vendor"]
servo = ["serde/unstable", "serde", "serde_derive", "heapsize_derive",
"style_traits/servo", "app_units/plugins", "string_cache",
"style_traits/servo", "app_units/plugins", "servo_atoms", "html5ever-atoms",
"cssparser/heap_size", "cssparser/serde-serialization",
"url/heap_size", "plugins", "parking_lot/nightly"]
testing = []
@ -31,6 +31,7 @@ euclid = "0.10.1"
fnv = "1.0"
heapsize = "0.3.0"
heapsize_derive = {version = "0.1", optional = true}
html5ever-atoms = {version = "0.1", optional = true}
lazy_static = "0.2"
log = "0.3.5"
libc = "0.2"
@ -48,8 +49,8 @@ rustc-serialize = "0.3"
selectors = "0.14"
serde = {version = "0.8", optional = true}
serde_derive = {version = "0.8", optional = true}
servo_atoms = {path = "../atoms", optional = true}
smallvec = "0.1"
string_cache = {version = "0.2.26", features = ["heap_size"], optional = true}
style_traits = {path = "../style_traits"}
time = "0.1"
unicode-segmentation = "0.1.2"

View file

@ -4,6 +4,7 @@
//! CSS transitions and animations.
use Atom;
use bezier::Bezier;
use context::SharedStyleContext;
use dom::{OpaqueNode, UnsafeNode};
@ -19,7 +20,6 @@ use properties::longhands::transition_timing_function::computed_value::Transitio
use selector_matching::ApplicableDeclarationBlock;
use std::sync::Arc;
use std::sync::mpsc::Sender;
use string_cache::Atom;
use timer::Timer;
use values::computed::Time;

View file

@ -6,6 +6,7 @@
//!
//! [attr]: https://dom.spec.whatwg.org/#interface-attr
use {Atom, Prefix, Namespace, LocalName};
use app_units::Au;
use cssparser::{self, Color, RGBA};
use euclid::num::Zero;
@ -15,7 +16,6 @@ use std::str::FromStr;
use str::{HTML_SPACE_CHARACTERS, read_exponent, read_fraction};
use str::{read_numbers, split_commas, split_html_space_chars};
#[cfg(not(feature = "gecko"))] use str::str_join;
use string_cache::{Atom, Namespace};
use url::Url;
use values::specified::Length;
@ -548,8 +548,8 @@ pub fn parse_length(mut value: &str) -> LengthOrPercentageOrAuto {
#[derive(Clone, Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct AttrIdentifier {
pub local_name: Atom,
pub name: Atom,
pub local_name: LocalName,
pub name: LocalName,
pub namespace: Namespace,
pub prefix: Option<Atom>,
pub prefix: Option<Prefix>,
}

View file

@ -6,6 +6,7 @@
//!
//! [custom]: https://drafts.csswg.org/css-variables/
use Atom;
use cssparser::{Delimiter, Parser, SourcePosition, ToCss, Token, TokenSerializationType};
use properties::DeclaredValue;
use std::ascii::AsciiExt;
@ -13,7 +14,6 @@ use std::borrow::Cow;
use std::collections::{HashMap, HashSet};
use std::fmt;
use std::sync::Arc;
use string_cache::Atom;
// Does not include the `--` prefix
pub type Name = Atom;

View file

@ -6,6 +6,7 @@
#![allow(unsafe_code)]
use {Atom, Namespace, LocalName};
use atomic_refcell::{AtomicRef, AtomicRefCell};
use data::{ElementStyles, ElementData};
use element_state::ElementState;
@ -19,7 +20,6 @@ use sink::Push;
use std::fmt::Debug;
use std::ops::BitOr;
use std::sync::Arc;
use string_cache::{Atom, Namespace};
use traversal::DomTraversalContext;
use util::opts;
@ -182,8 +182,8 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre
fn get_state(&self) -> ElementState;
fn has_attr(&self, namespace: &Namespace, attr: &Atom) -> bool;
fn attr_equals(&self, namespace: &Namespace, attr: &Atom, value: &Atom) -> bool;
fn has_attr(&self, namespace: &Namespace, attr: &LocalName) -> bool;
fn attr_equals(&self, namespace: &Namespace, attr: &LocalName, value: &Atom) -> bool;
/// Set the restyle damage field.
fn set_restyle_damage(self, damage: Self::ConcreteRestyleDamage);

View file

@ -25,7 +25,11 @@ pub mod atom_macro;
#[macro_use]
pub mod namespace;
pub use string_cache::namespace::{Namespace, WeakNamespace};
pub use self::namespace::{Namespace, WeakNamespace};
macro_rules! local_name {
($s: tt) => { atom!($s) }
}
/// A strong reference to a Gecko atom.
#[derive(PartialEq, Eq)]

View file

@ -3,7 +3,7 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use gecko_bindings::structs::nsIAtom;
use std::borrow::Borrow;
use std::borrow::{Borrow, Cow};
use std::fmt;
use std::ops::Deref;
use string_cache::{Atom, WeakAtom};
@ -31,6 +31,12 @@ impl Deref for Namespace {
}
}
impl<'a> From<Cow<'a, str>> for Namespace {
fn from(s: Cow<'a, str>) -> Self {
Namespace(Atom::from(s))
}
}
impl fmt::Display for Namespace {
fn fmt(&self, w: &mut fmt::Formatter) -> fmt::Result {
self.0.fmt(w)

View file

@ -53,8 +53,10 @@ extern crate deque;
extern crate encoding;
extern crate euclid;
extern crate fnv;
#[cfg(feature = "gecko")] #[macro_use] pub mod gecko_string_cache;
extern crate heapsize;
#[cfg(feature = "servo")] #[macro_use] extern crate heapsize_derive;
#[cfg(feature = "servo")] #[macro_use] extern crate html5ever_atoms;
#[allow(unused_extern_crates)]
#[macro_use]
extern crate lazy_static;
@ -78,8 +80,8 @@ extern crate selectors;
#[cfg(feature = "servo")]
extern crate serde;
#[cfg(feature = "servo")] #[macro_use] extern crate serde_derive;
#[cfg(feature = "servo")] #[macro_use] extern crate servo_atoms;
extern crate smallvec;
#[cfg(feature = "servo")] #[macro_use] extern crate string_cache;
#[macro_use]
extern crate style_traits;
extern crate time;
@ -88,10 +90,6 @@ extern crate unicode_segmentation;
extern crate url;
extern crate util;
#[cfg(feature = "gecko")]
#[path = "./gecko_string_cache/mod.rs"]
#[macro_use] pub mod string_cache;
pub mod animation;
pub mod atomic_refcell;
pub mod attr;
@ -137,6 +135,17 @@ use cssparser::ToCss;
use std::fmt;
use std::sync::Arc;
#[cfg(feature = "gecko")] pub use gecko_string_cache as string_cache;
#[cfg(feature = "gecko")] pub use gecko_string_cache::Atom;
#[cfg(feature = "gecko")] pub use gecko_string_cache::Namespace;
#[cfg(feature = "gecko")] pub use gecko_string_cache::Atom as Prefix;
#[cfg(feature = "gecko")] pub use gecko_string_cache::Atom as LocalName;
#[cfg(feature = "servo")] pub use servo_atoms::Atom;
#[cfg(feature = "servo")] pub use html5ever_atoms::Prefix;
#[cfg(feature = "servo")] pub use html5ever_atoms::LocalName;
#[cfg(feature = "servo")] pub use html5ever_atoms::Namespace;
/// The CSS properties supported by the style system.
// Generated from the properties.mako.rs template by build.rs
#[macro_use]

View file

@ -6,6 +6,7 @@
#![allow(unsafe_code)]
use {Atom, LocalName};
use animation;
use arc_ptr_eq;
use atomic_refcell::AtomicRefMut;
@ -29,7 +30,6 @@ use std::mem;
use std::ops::Deref;
use std::slice::IterMut;
use std::sync::Arc;
use string_cache::Atom;
use util::opts;
fn create_common_style_affecting_attributes_from_element<E: TElement>(element: &E)
@ -38,12 +38,12 @@ fn create_common_style_affecting_attributes_from_element<E: TElement>(element: &
for attribute_info in &common_style_affecting_attributes() {
match attribute_info.mode {
CommonStyleAffectingAttributeMode::IsPresent(flag) => {
if element.has_attr(&ns!(), &attribute_info.atom) {
if element.has_attr(&ns!(), &attribute_info.attr_name) {
flags.insert(flag)
}
}
CommonStyleAffectingAttributeMode::IsEqual(ref target_value, flag) => {
if element.attr_equals(&ns!(), &attribute_info.atom, target_value) {
if element.attr_equals(&ns!(), &attribute_info.attr_name, target_value) {
flags.insert(flag)
}
}
@ -333,7 +333,7 @@ bitflags! {
}
pub struct CommonStyleAffectingAttributeInfo {
pub atom: Atom,
pub attr_name: LocalName,
pub mode: CommonStyleAffectingAttributeMode,
}
@ -348,23 +348,23 @@ pub enum CommonStyleAffectingAttributeMode {
pub fn common_style_affecting_attributes() -> [CommonStyleAffectingAttributeInfo; 5] {
[
CommonStyleAffectingAttributeInfo {
atom: atom!("hidden"),
attr_name: local_name!("hidden"),
mode: CommonStyleAffectingAttributeMode::IsPresent(HIDDEN_ATTRIBUTE),
},
CommonStyleAffectingAttributeInfo {
atom: atom!("nowrap"),
attr_name: local_name!("nowrap"),
mode: CommonStyleAffectingAttributeMode::IsPresent(NO_WRAP_ATTRIBUTE),
},
CommonStyleAffectingAttributeInfo {
atom: atom!("align"),
attr_name: local_name!("align"),
mode: CommonStyleAffectingAttributeMode::IsEqual(atom!("left"), ALIGN_LEFT_ATTRIBUTE),
},
CommonStyleAffectingAttributeInfo {
atom: atom!("align"),
attr_name: local_name!("align"),
mode: CommonStyleAffectingAttributeMode::IsEqual(atom!("center"), ALIGN_CENTER_ATTRIBUTE),
},
CommonStyleAffectingAttributeInfo {
atom: atom!("align"),
attr_name: local_name!("align"),
mode: CommonStyleAffectingAttributeMode::IsEqual(atom!("right"), ALIGN_RIGHT_ATTRIBUTE),
}
]
@ -373,8 +373,8 @@ pub fn common_style_affecting_attributes() -> [CommonStyleAffectingAttributeInfo
/// Attributes that, if present, disable style sharing. All legacy HTML attributes must be in
/// either this list or `common_style_affecting_attributes`. See the comment in
/// `synthesize_presentational_hints_for_legacy_attributes`.
pub fn rare_style_affecting_attributes() -> [Atom; 3] {
[ atom!("bgcolor"), atom!("border"), atom!("colspan") ]
pub fn rare_style_affecting_attributes() -> [LocalName; 3] {
[ local_name!("bgcolor"), local_name!("border"), local_name!("colspan") ]
}
fn have_same_class<E: TElement>(element: &E,
@ -703,7 +703,7 @@ pub trait MatchMethods : TElement {
return StyleSharingResult::CannotShare
}
if self.has_attr(&ns!(), &atom!("id")) {
if self.has_attr(&ns!(), &local_name!("id")) {
return StyleSharingResult::CannotShare
}

View file

@ -6,13 +6,13 @@
//!
//! [mq]: https://drafts.csswg.org/mediaqueries/
use Atom;
use app_units::Au;
use cssparser::{Delimiter, Parser, ToCss, Token};
use euclid::size::{Size2D, TypedSize2D};
use properties::longhands;
use serialize_comma_separated_list;
use std::fmt::{self, Write};
use string_cache::Atom;
use style_traits::ViewportPx;
use values::specified;

View file

@ -191,7 +191,7 @@
use std::sync::Arc;
use values::computed::{Context, ToComputedValue};
use values::{computed, specified};
use string_cache::Atom;
use Atom;
${caller.body()}
#[allow(unused_variables)]
pub fn cascade_property(declaration: &PropertyDeclaration,

View file

@ -648,9 +648,9 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
pub mod computed_value {
use cssparser::ToCss;
use std::fmt;
use string_cache::Atom;
use Atom;
pub use string_cache::Atom as SingleComputedValue;
pub use Atom as SingleComputedValue;
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
@ -676,7 +676,7 @@ ${helpers.single_keyword("overflow-x", "visible hidden scroll auto",
pub use self::computed_value::T as SpecifiedValue;
impl NoViewportPercentage for SpecifiedValue {}
pub use string_cache::Atom as SingleSpecifiedValue;
pub use Atom as SingleSpecifiedValue;
#[inline]
pub fn parse_one(input: &mut Parser) -> Result<SingleSpecifiedValue, ()> {

View file

@ -20,7 +20,7 @@
pub mod computed_value {
use cssparser::ToCss;
use std::fmt;
use string_cache::Atom;
use Atom;
#[derive(Debug, PartialEq, Eq, Clone, Hash)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf, Deserialize, Serialize))]
@ -46,19 +46,25 @@
#[cfg(not(feature = "gecko"))] // Gecko can't borrow atoms as UTF-8.
pub fn from_atom(input: Atom) -> FontFamily {
let option = match_ignore_ascii_case! { &input,
&atom!("serif") => Some(atom!("serif")),
&atom!("sans-serif") => Some(atom!("sans-serif")),
&atom!("cursive") => Some(atom!("cursive")),
&atom!("fantasy") => Some(atom!("fantasy")),
&atom!("monospace") => Some(atom!("monospace")),
_ => None
};
match option {
Some(family) => FontFamily::Generic(family),
None => FontFamily::FamilyName(input)
match input {
atom!("serif") |
atom!("sans-serif") |
atom!("cursive") |
atom!("fantasy") |
atom!("monospace") => {
return FontFamily::Generic(input)
}
_ => {}
}
match_ignore_ascii_case! { input,
"serif" => return FontFamily::Generic(atom!("serif")),
"sans-serif" => return FontFamily::Generic(atom!("sans-serif")),
"cursive" => return FontFamily::Generic(atom!("cursive")),
"fantasy" => return FontFamily::Generic(atom!("fantasy")),
"monospace" => return FontFamily::Generic(atom!("monospace")),
_ => {}
}
FontFamily::FamilyName(input)
}
}
impl ToCss for FontFamily {
@ -101,12 +107,12 @@
// FIXME(bholley): The fast thing to do here would be to look up the
// string (as lowercase) in the static atoms table. We don't have an
// API to do that yet though, so we do the simple thing for now.
match &first_ident[..] {
s if atom!("serif").eq_str_ignore_ascii_case(s) => return Ok(FontFamily::Generic(atom!("serif"))),
s if atom!("sans-serif").eq_str_ignore_ascii_case(s) => return Ok(FontFamily::Generic(atom!("sans-serif"))),
s if atom!("cursive").eq_str_ignore_ascii_case(s) => return Ok(FontFamily::Generic(atom!("cursive"))),
s if atom!("fantasy").eq_str_ignore_ascii_case(s) => return Ok(FontFamily::Generic(atom!("fantasy"))),
s if atom!("monospace").eq_str_ignore_ascii_case(s) => return Ok(FontFamily::Generic(atom!("monospace"))),
match_ignore_ascii_case! { first_ident,
"serif" => return Ok(FontFamily::Generic(atom!("serif"))),
"sans-serif" => return Ok(FontFamily::Generic(atom!("sans-serif"))),
"cursive" => return Ok(FontFamily::Generic(atom!("cursive"))),
"fantasy" => return Ok(FontFamily::Generic(atom!("fantasy"))),
"monospace" => return Ok(FontFamily::Generic(atom!("monospace"))),
_ => {}
}

View file

@ -16,6 +16,7 @@ use std::collections::HashSet;
use std::fmt::{self, Write};
use std::sync::Arc;
use Atom;
use app_units::Au;
#[cfg(feature = "servo")] use cssparser::{Color as CSSParserColor, RGBA};
use cssparser::{Parser, ToCss, TokenSerializationType};
@ -23,7 +24,6 @@ use error_reporting::ParseErrorReporter;
use url::Url;
#[cfg(feature = "servo")] use euclid::side_offsets::SideOffsets2D;
use euclid::size::Size2D;
use string_cache::Atom;
use computed_values;
#[cfg(feature = "servo")] use logical_geometry::{LogicalMargin, PhysicalSide};
use logical_geometry::WritingMode;

View file

@ -4,6 +4,7 @@
//! Restyle hints: an optimization to avoid unnecessarily matching selectors.
use Atom;
use element_state::*;
#[cfg(feature = "servo")]
use heapsize::HeapSizeOf;
@ -14,7 +15,6 @@ use selectors::matching::matches_complex_selector;
use selectors::parser::{AttrSelector, Combinator, ComplexSelector, SelectorImpl, SimpleSelector};
use std::clone::Clone;
use std::sync::Arc;
use string_cache::Atom;
/// When the ElementState of an element (like IN_HOVER_STATE) changes, certain
/// pseudo-classes (like :hover) may require us to restyle that element, its

View file

@ -104,7 +104,7 @@ pub fn attr_exists_selector_is_shareable(attr_selector: &AttrSelector<TheSelecto
// NB(pcwalton): If you update this, remember to update the corresponding list in
// `can_share_style_with()` as well.
common_style_affecting_attributes().iter().any(|common_attr_info| {
common_attr_info.atom == attr_selector.name && match common_attr_info.mode {
common_attr_info.attr_name == attr_selector.name && match common_attr_info.mode {
CommonStyleAffectingAttributeMode::IsPresent(_) => true,
CommonStyleAffectingAttributeMode::IsEqual(..) => false,
}
@ -115,9 +115,10 @@ pub fn attr_equals_selector_is_shareable(attr_selector: &AttrSelector<TheSelecto
value: &AttrValue) -> bool {
// FIXME(pcwalton): Remove once we start actually supporting RTL text. This is in
// here because the UA style otherwise disables all style sharing completely.
// FIXME(SimonSapin): should this be the attribute *name* rather than value?
atom!("dir") == *value ||
common_style_affecting_attributes().iter().any(|common_attr_info| {
common_attr_info.atom == attr_selector.name && match common_attr_info.mode {
common_attr_info.attr_name == attr_selector.name && match common_attr_info.mode {
CommonStyleAffectingAttributeMode::IsEqual(ref target_value, _) => {
*target_value == *value
}

View file

@ -4,6 +4,7 @@
//! Selector matching.
use {Atom, LocalName};
use dom::PresentationalHintsSynthetizer;
use element_state::*;
use error_reporting::StdoutErrorReporter;
@ -19,7 +20,7 @@ use selectors::Element;
use selectors::bloom::BloomFilter;
use selectors::matching::{AFFECTED_BY_STYLE_ATTRIBUTE, AFFECTED_BY_PRESENTATIONAL_HINTS};
use selectors::matching::{MatchingReason, StyleRelations, matches_complex_selector};
use selectors::parser::{Selector, SimpleSelector, LocalName, ComplexSelector};
use selectors::parser::{Selector, SimpleSelector, LocalName as LocalNameSelector, ComplexSelector};
use sink::Push;
use smallvec::VecLike;
use std::borrow::Borrow;
@ -29,7 +30,6 @@ use std::hash::BuildHasherDefault;
use std::hash::Hash;
use std::slice;
use std::sync::Arc;
use string_cache::Atom;
use style_traits::viewport::ViewportConstraints;
use stylesheets::{CSSRule, Origin, Stylesheet, UserAgentStylesheets};
use viewport::{self, MaybeNew, ViewportRule};
@ -661,10 +661,10 @@ pub struct SelectorMap {
// TODO: Tune the initial capacity of the HashMap
pub id_hash: FnvHashMap<Atom, Vec<Rule>>,
pub class_hash: FnvHashMap<Atom, Vec<Rule>>,
pub local_name_hash: FnvHashMap<Atom, Vec<Rule>>,
pub local_name_hash: FnvHashMap<LocalName, Vec<Rule>>,
/// Same as local_name_hash, but keys are lower-cased.
/// For HTML elements in HTML documents.
pub lower_local_name_hash: FnvHashMap<Atom, Vec<Rule>>,
pub lower_local_name_hash: FnvHashMap<LocalName, Vec<Rule>>,
/// Rules that don't have ID, class, or element selectors.
pub other_rules: Vec<Rule>,
/// Whether this hash is empty.
@ -856,7 +856,7 @@ impl SelectorMap {
return;
}
if let Some(LocalName { name, lower_name }) = SelectorMap::get_local_name(&rule) {
if let Some(LocalNameSelector { name, lower_name }) = SelectorMap::get_local_name(&rule) {
find_push(&mut self.local_name_hash, name, rule.clone());
find_push(&mut self.lower_local_name_hash, lower_name, rule);
return;
@ -892,10 +892,10 @@ impl SelectorMap {
}
/// Retrieve the name if it is a type selector, or None otherwise.
pub fn get_local_name(rule: &Rule) -> Option<LocalName<TheSelectorImpl>> {
pub fn get_local_name(rule: &Rule) -> Option<LocalNameSelector<TheSelectorImpl>> {
for ss in &rule.selector.compound_selector {
if let SimpleSelector::LocalName(ref n) = *ss {
return Some(LocalName {
return Some(LocalNameSelector {
name: n.name.clone(),
lower_name: n.lower_name.clone(),
})

View file

@ -2,6 +2,7 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
use {Atom, Prefix, Namespace, LocalName};
use attr::{AttrIdentifier, AttrValue};
use cssparser::ToCss;
use element_state::ElementState;
@ -11,7 +12,6 @@ use selector_impl::{attr_equals_selector_is_shareable, attr_exists_selector_is_s
use selectors::{Element, MatchAttrGeneric};
use selectors::parser::{AttrSelector, ParserContext, SelectorImpl};
use std::fmt;
use string_cache::{Atom, Namespace};
/// NB: If you add to this list, be sure to update `each_pseudo_element` too.
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
@ -159,10 +159,10 @@ impl SelectorImpl for ServoSelectorImpl {
type AttrValue = String;
type Identifier = Atom;
type ClassName = Atom;
type LocalName = Atom;
type NamespacePrefix = Atom;
type LocalName = LocalName;
type NamespacePrefix = Prefix;
type NamespaceUrl = Namespace;
type BorrowedLocalName = Atom;
type BorrowedLocalName = LocalName;
type BorrowedNamespaceUrl = Namespace;
fn attr_exists_selector_is_shareable(attr_selector: &AttrSelector<Self>) -> bool {
@ -324,14 +324,14 @@ impl ServoElementSnapshot {
}
}
fn get_attr(&self, namespace: &Namespace, name: &Atom) -> Option<&AttrValue> {
fn get_attr(&self, namespace: &Namespace, name: &LocalName) -> Option<&AttrValue> {
self.attrs.as_ref().unwrap().iter()
.find(|&&(ref ident, _)| ident.local_name == *name &&
ident.namespace == *namespace)
.map(|&(_, ref v)| v)
}
fn get_attr_ignore_ns(&self, name: &Atom) -> Option<&AttrValue> {
fn get_attr_ignore_ns(&self, name: &LocalName) -> Option<&AttrValue> {
self.attrs.as_ref().unwrap().iter()
.find(|&&(ref ident, _)| ident.local_name == *name)
.map(|&(_, ref v)| v)
@ -348,18 +348,18 @@ impl ElementSnapshot for ServoElementSnapshot {
}
fn id_attr(&self) -> Option<Atom> {
self.get_attr(&ns!(), &atom!("id")).map(|v| v.as_atom().clone())
self.get_attr(&ns!(), &local_name!("id")).map(|v| v.as_atom().clone())
}
fn has_class(&self, name: &Atom) -> bool {
self.get_attr(&ns!(), &atom!("class"))
self.get_attr(&ns!(), &local_name!("class"))
.map_or(false, |v| v.as_tokens().iter().any(|atom| atom == name))
}
fn each_class<F>(&self, mut callback: F)
where F: FnMut(&Atom)
{
if let Some(v) = self.get_attr(&ns!(), &atom!("class")) {
if let Some(v) = self.get_attr(&ns!(), &local_name!("class")) {
for class in v.as_tokens() {
callback(class);
}

View file

@ -4,6 +4,7 @@
//! Style sheets and their CSS rules.
use {Atom, Prefix, Namespace};
use cssparser::{AtRuleParser, Parser, QualifiedRuleParser, decode_stylesheet_bytes};
use cssparser::{AtRuleType, RuleListParser, Token};
use encoding::EncodingRef;
@ -18,7 +19,6 @@ use selector_impl::TheSelectorImpl;
use selectors::parser::{Selector, parse_selector_list};
use std::cell::Cell;
use std::sync::Arc;
use string_cache::{Atom, Namespace};
use url::Url;
use viewport::ViewportRule;
@ -99,7 +99,7 @@ impl CSSRule {
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct NamespaceRule {
/// `None` for the default Namespace
pub prefix: Option<Atom>,
pub prefix: Option<Prefix>,
pub url: Namespace,
}
@ -316,10 +316,10 @@ impl<'a> AtRuleParser for TopLevelRuleParser<'a> {
self.state.set(State::Namespaces);
let prefix_result = input.try(|input| input.expect_ident());
let url = Namespace(Atom::from(try!(input.expect_url_or_string())));
let url = Namespace::from(try!(input.expect_url_or_string()));
let opt_prefix = if let Ok(prefix) = prefix_result {
let prefix: Atom = prefix.into();
let prefix = Prefix::from(prefix);
self.context.selector_context.namespace_prefixes.insert(
prefix.clone(), url.clone());
Some(prefix)